├── .eslintignore
├── .eslintrc.yml
├── .gitignore
├── .hintrc
├── README.md
├── demo
├── .eslintrc.yml
├── demo-animation-chain.html
├── demo-animation-chain.js
├── demo-animation.html
├── demo-animation.js
├── demo-chain.html
├── demo-chain.js
├── demo-fx.html
├── demo-fx.js
├── demo-group.html
├── demo-group.js
├── demo-input.html
├── demo-input.js
├── demo-keyboard.html
├── demo-keyboard.js
├── demo-light.html
├── demo-light.js
├── demo-load.html
├── demo-load.js
├── demo-particles.html
├── demo-particles.js
├── demo-plane.html
├── demo-plane.js
├── demo-play.html
├── demo-play.js
├── demo-postfx.html
├── demo-postfx.js
├── demo-sound-markers.html
├── demo-sound-markers.js
├── demo-sound.html
├── demo-sound.js
├── demo-tilemap.html
├── demo-tilemap.js
├── demo-timeline.html
├── demo-timeline.js
├── demo-timer-event.html
├── demo-timer-event.js
├── demo-tween.html
├── demo-tween.js
├── demo-video.html
├── demo-video.js
├── demo.html
└── demo.js
├── package-lock.json
├── package.json
├── rollup.config.js
├── src
├── DefaultPluginsConfig.js
├── EaseMap.js
├── FXMap.js
├── InspectorGlobalPlugin.js
├── InspectorScenePlugin.js
├── Install.js
├── const.js
├── main.js
└── util.js
└── test
├── .eslintrc.yml
├── test-load.html
├── test-load.js
├── test.html
└── test.js
/.eslintignore:
--------------------------------------------------------------------------------
1 | dist/
2 | vendor/
--------------------------------------------------------------------------------
/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | env:
2 | browser: yes
3 | es6: yes
4 | extends: semistandard
5 | globals:
6 | Atomics: readonly
7 | SharedArrayBuffer: readonly
8 | parserOptions:
9 | ecmaVersion: 2018
10 | sourceType: module
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | dist
4 | vendor
5 | assets
6 |
--------------------------------------------------------------------------------
/.hintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "development"
4 | ],
5 | "hints": {
6 | "meta-viewport": "off"
7 | }
8 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Phaser 3 Inspector Plugin 🧐
2 | =========================
3 |
4 | View and change game properties, with [Tweakpane](https://github.com/cocopon/tweakpane).
5 |
6 | Demos
7 | -----
8 |
9 | - [First Phaser 3 game](https://codepen.io/samme/pen/YzxbMBV?editors=0010) — simple game, helper functions
10 | - [All the demos](https://codepen.io/collection/LPeVMY)
11 |
12 | You can also paste the [Quick load](#quick-load) snippet into any of the [labs examples](https://labs.phaser.io).
13 |
14 | Install
15 | -------
16 |
17 | The plugins add controls for the game and scene systems. If you don't need these, you can skip this step and use the [helper functions](#helper-functions) only.
18 |
19 | ### Browser / UMD
20 |
21 | [First Phaser 3 game](https://codepen.io/samme/pen/YzxbMBV?editors=0010) shows this setup.
22 |
23 | Include Phaser, [Tweakpane](https://cdn.jsdelivr.net/npm/tweakpane/), and [the plugin UMD script](https://cdn.jsdelivr.net/npm/phaser-plugin-inspector/) in this order. You can download the scripts or use the CDN links.
24 |
25 | ```html
26 |
27 |
28 |
29 | ```
30 |
31 | If this is the only plugin you're using then you can use the "default" configuration:
32 |
33 | ```js
34 | /* global PhaserPluginInspector */
35 |
36 | new Phaser.Game({
37 | plugins: PhaserPluginInspector.DefaultPluginsConfig
38 | });
39 | ```
40 |
41 | Or you can configure the plugins individually:
42 |
43 | ```js
44 | /* global PhaserPluginInspector */
45 |
46 | const { InspectorGlobalPlugin, InspectorScenePlugin } = PhaserPluginInspector;
47 |
48 | new Phaser.Game({
49 | plugins: {
50 | global: [{ key: 'InspectorGlobalPlugin', plugin: InspectorGlobalPlugin, mapping: 'inspectorGame' }],
51 | scene: [{ key: 'InspectorScenePlugin', plugin: InspectorScenePlugin, mapping: 'inspectorScene' }]
52 | }
53 | });
54 | ```
55 |
56 | You can use any mapping, or `{ start: true }` for no mapping. If you don't want to add any controls, you don't need any mapping.
57 |
58 | The helper functions are on the same namespace:
59 |
60 | ```js
61 | /* global PhaserPluginInspector */
62 |
63 | const { AddGameObject } = PhaserPluginInspector
64 | ```
65 |
66 | ### Module
67 |
68 | ```sh
69 | npm install phaser-plugin-inspector tweakpane
70 | ```
71 |
72 | This package has an ES module (`phaser-plugin-inspector.esm.js`, marked as `module`) and a CommonJS-compatible UMD module(`phaser-plugin-inspector.umd.js`, marked as `browser`). You should use the ES module, but some bundlers may pick the UMD module by default. Configure your bundler to use the `module` field, or add an alias to the ES module file, or import the ES module file directly.
73 |
74 | If this is the only plugin you're using then you can use the "default" configuration:
75 |
76 | ```js
77 | import { DefaultPluginsConfig } from 'phaser-plugin-inspector';
78 |
79 | new Phaser.Game({
80 | plugins: DefaultPluginsConfig
81 | });
82 | ```
83 |
84 | Or you can configure the plugins individually:
85 |
86 | ```js
87 | import { InspectorGlobalPlugin, InspectorScenePlugin } from 'phaser-plugin-inspector';
88 |
89 | new Phaser.Game({
90 | plugins: {
91 | global: [{ key: 'InspectorGlobalPlugin', plugin: InspectorGlobalPlugin, mapping: 'inspectorGame' }],
92 | scene: [{ key: 'InspectorScenePlugin', plugin: InspectorScenePlugin, mapping: 'inspectorScene' }]
93 | }
94 | });
95 | ```
96 |
97 | You can import the helper functions as well:
98 |
99 | ```js
100 | import { AddGameObject } from 'phaser-plugin-inspector';
101 | ```
102 |
103 | ### Quick load
104 |
105 | ```js
106 | function preload() {
107 | this.load.scripts('inspector', [
108 | 'https://cdn.jsdelivr.net/npm/tweakpane@3.1.10/dist/tweakpane.js',
109 | 'https://cdn.jsdelivr.net/npm/phaser-plugin-inspector@2.6.0/dist/phaser-plugin-inspector.umd.js',
110 | ]);
111 | this.load.once('complete', () => {
112 | PhaserPluginInspector.Install(this.plugins);
113 | });
114 | }
115 | ```
116 |
117 | ### Load from console
118 |
119 | Given a `game` variable:
120 |
121 | ```js
122 | const scene = game.scene.getScenes(true)[0];
123 |
124 | scene.load.scripts('inspector', [
125 | 'https://cdn.jsdelivr.net/npm/tweakpane@3.1.10/dist/tweakpane.js',
126 | 'https://cdn.jsdelivr.net/npm/phaser-plugin-inspector@2.6.0/dist/phaser-plugin-inspector.umd.js',
127 | ]);
128 | scene.load.once('complete', () => {
129 | PhaserPluginInspector.Install(game.plugins);
130 | }).start();
131 | ```
132 |
133 | Use
134 | ---
135 |
136 | All of the “Print” buttons call `console.info()` or `console.table()`.
137 |
138 | Beware that Tweakpane inputs (checkboxes, sliders, etc.) do not update their values automatically; use the pane's **Refresh** button.
139 |
140 | Tweakpane monitors are updated automatically 5 times per second. For more precise work you may want to pause a scene or its systems.
141 |
142 | You can inspect game objects using the **Display List: Inspect** and **Update List: Inspect** buttons in each scene. The new folder is added to the end of the inspector pane. Look in the console to confirm.
143 |
144 | To step one frame at a time, use **Game → Loop → Sleep**, **Game → Step** (repeat), **Game → Loop → Wake**.
145 |
146 | Helper functions
147 | ----------------
148 |
149 | These create a set of controls for common Phaser objects.
150 |
151 | You can use these functions with or without the plugins.
152 |
153 | The `pane` argument is the Tweakpane pane or a folder in it. The `options` argument is options for the folder.
154 |
155 | Each function creates a [folder](https://cocopon.github.io/tweakpane/ui-components.html#folder) and returns it.
156 |
157 | If you've installed the plugins, then within a scene context (`this`)
158 |
159 | - `this.inspectorGame.pane` or `this.inspectorScene.pane` is the main pane
160 | - `this.inspectorGame.folder` is the “Game” folder
161 | - `this.inspectorScene.folder` is the current scene's folder
162 |
163 | See the [First Phaser 3 game](https://codepen.io/samme/pen/YzxbMBV?editors=0010) demo for this setup.
164 |
165 | If you're not using the plugins, then you should create a pane yourself:
166 |
167 | ```js
168 | const pane = new Tweakpane.Pane();
169 | ```
170 |
171 | Some of these folders need to be disposed manually if you destroy the target object or stop the scene it belongs to. Use
172 |
173 | ```js
174 | folder.dispose();
175 | ```
176 |
177 | ### AddActive(items, pane, options?) → folder
178 |
179 | Adds a set of "active" toggles for any objects with an `active` property, identified by `name`.
180 |
181 | ### AddAlpha(items, pane, options?) → folder
182 |
183 | Adds a set of "alpha" sliders for any objects with an `alpha` property, identified by `name`.
184 |
185 | ### AddAnimationState(animationState, pane, options?) → folder
186 |
187 | Adds a folder for a sprite's animation state, e.g.,
188 |
189 | AddAnimationState(sprite.anims, pane);
190 |
191 | ### AddArcadeBody(body, pane, options?) → folder
192 |
193 | Adds a folder for a game object's Arcade Physics body, e.g.,
194 |
195 | AddArcadeBody(sprite.body, pane);
196 |
197 | ### AddCamera(camera, pane) → folder
198 |
199 | Adds a folder for a camera, e.g.,
200 |
201 | AddCamera(this.cameras.main, pane);
202 |
203 | ### AddChain(chain, pane, options?) → folder
204 |
205 | Adds a folder for a [tween chain](https://docs.phaser.io/api-documentation/class/tweens-tweenchain).
206 |
207 | Dispose this folder if you remove the tween chain.
208 |
209 | ### AddFXComponent(component, pane, options?) → folder
210 |
211 | Adds a folder for a game object's [FX component](https://docs.phaser.io/api-documentation/class/gameobjects-components-fx), e.g.,
212 |
213 | AddFXComponent(sprite.preFX, pane);
214 |
215 | Note that Post FX controllers are always [enabled](https://docs.phaser.io/api-documentation/class/gameobjects-components-fx#enabled).
216 |
217 | ### AddFXController(controller, pane, options?) → folder
218 |
219 | Adds a folder for a game object's [FX controller](https://docs.phaser.io/api-documentation/class/fx-controller), e.g.,
220 |
221 | const barrelEffect = sprite.preFX.addBarrel();
222 |
223 | AddFXController(barrelEffect, pane);
224 |
225 | Note that Post FX controllers are always [active](https://docs.phaser.io/api-documentation/class/fx-controller#active).
226 |
227 | ### AddGameObject(obj, pane, options?) → folder
228 |
229 | Adds a folder for a game object (except group).
230 |
231 | ### AddGroup(group, pane, options?) → folder
232 |
233 | Adds a folder for a group.
234 |
235 | ### AddInput(interactiveObject, pane, options?) → folder
236 |
237 | Adds a folder for a game object's [interactive object](https://docs.phaser.io/api-documentation/typedef/types-input#interactiveobject), e.g.,
238 |
239 | AddInput(sprite.input, pane);
240 |
241 | ### AddKey(key, pane, options?) → folder
242 |
243 | Adds a folder for a [keyboard key object](https://docs.phaser.io/api-documentation/class/input-keyboard-key).
244 |
245 | Dispose this folder if you remove the key.
246 |
247 | ### AddKeys(keys, pane, options?) → folder
248 |
249 | Adds a folder for an object map of [keyboard key objects](https://docs.phaser.io/api-documentation/class/input-keyboard-key), such as that returned by [addKeys()](https://docs.phaser.io/api-documentation/class/input-keyboard-keyboardplugin#addkeys).
250 |
251 | Dispose this folder if you remove those keys.
252 |
253 | ### AddLight(light, pane, options?) → folder
254 |
255 | Adds a folder for a [light](https://docs.phaser.io/api-documentation/class/gameobjects-light) (not point light).
256 |
257 | ### AddParticleEmitter(emitter, pane, options?) → folder
258 |
259 | Adds a folder for a [particle emitter](https://docs.phaser.io/api-documentation/class/gameobjects-particles-particleemitter).
260 |
261 | ### AddScenes(scene, pane, options?) → folder
262 |
263 | Adds a set of "visible" toggles for the scenes, e.g.,
264 |
265 | AddScenes(this.scene.manager.getScenes(false), pane);
266 |
267 | ### AddSound(sound, pane, options?) → folder
268 |
269 | Adds a folder for a [sound](https://docs.phaser.io/api-documentation/class/sound-basesound).
270 |
271 | ### AddTimeline(timeline, pane, options?) → folder
272 |
273 | Adds a folder for a [timeline](https://docs.phaser.io/api-documentation/class/time-timeline).
274 |
275 | ### AddTimerEvent(timerEvent, pane, options?) → folder
276 |
277 | Adds a folder for a [timer event](https://docs.phaser.io/api-documentation/class/time-timerevent).
278 |
279 | Dispose this folder if you remove the timer event.
280 |
281 | ### AddTween(tween, pane, options?) → folder
282 |
283 | Adds a folder for a [tween](https://docs.phaser.io/api-documentation/class/tweens-tween).
284 |
285 | ### AddVideo(video, pane, options?) → folder
286 |
287 | Adds a folder for a [Video game object](https://docs.phaser.io/api-documentation/class/gameobjects-video).
288 |
289 | ### AddVisible(items, pane, options?) → folder
290 |
291 | Adds a set of "visible" toggles for any objects with an `visible` property, identified by `name`.
292 |
293 |
--------------------------------------------------------------------------------
/demo/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | env:
2 | browser: yes
3 | es6: no
4 | extends: semistandard
5 | globals:
6 | Atomics: readonly
7 | SharedArrayBuffer: readonly
8 | Phaser: readonly
9 | __Global__: readonly
10 |
--------------------------------------------------------------------------------
/demo/demo-animation-chain.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
Demo of Phaser 3 Inspector Plugin
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/demo-animation-chain.js:
--------------------------------------------------------------------------------
1 | /* global Phaser, PhaserPluginInspector */
2 |
3 | const { AddAnimationState } = PhaserPluginInspector;
4 |
5 | class Example extends Phaser.Scene {
6 | preload () {
7 | this.load.atlas('knight', 'assets/animations/knight.png', 'assets/animations/knight.json');
8 | this.load.image('bg', 'assets/skies/clouds.png');
9 | this.load.spritesheet('tiles', 'assets/tilemaps/tiles/fantasy-tiles.png', { frameWidth: 64, frameHeight: 64 });
10 | }
11 |
12 | create () {
13 | // The background and floor
14 | this.add.image(400, 16, 'bg').setOrigin(0.5, 0);
15 |
16 | for (var i = 0; i < 13; i++) {
17 | this.add.image(64 * i, 536, 'tiles', 1).setOrigin(0);
18 | }
19 |
20 | var text = this.add.text(400, 8, 'Click to play animation chain', { color: '#ffffff' }).setOrigin(0.5, 0);
21 |
22 | // Our animations
23 | this.anims.create({
24 | key: 'guardStart',
25 | frames: this.anims.generateFrameNames('knight', { prefix: 'guard_start/frame', start: 0, end: 3, zeroPad: 4 }),
26 | frameRate: 8
27 | });
28 |
29 | this.anims.create({
30 | key: 'guard',
31 | frames: this.anims.generateFrameNames('knight', { prefix: 'guard/frame', start: 0, end: 5, zeroPad: 4 }),
32 | frameRate: 8,
33 | repeat: 2
34 | });
35 |
36 | this.anims.create({
37 | key: 'guardEnd',
38 | frames: this.anims.generateFrameNames('knight', { prefix: 'guard_end/frame', start: 0, end: 3, zeroPad: 4 }),
39 | frameRate: 8
40 | });
41 |
42 | this.anims.create({
43 | key: 'idle',
44 | frames: this.anims.generateFrameNames('knight', { prefix: 'idle/frame', start: 0, end: 5, zeroPad: 4 }),
45 | frameRate: 8,
46 | repeat: -1
47 | });
48 |
49 | var lancelot = this.add.sprite(500, 536).setName('lancelot');
50 |
51 | AddAnimationState(lancelot.anims, this.inspectorScene.pane);
52 |
53 | lancelot.setOrigin(0.5, 1);
54 | lancelot.setScale(8);
55 | lancelot.play('idle');
56 |
57 | lancelot.on(Phaser.Animations.Events.SPRITE_ANIMATION_START, function (anim) {
58 | text.setText('Playing ' + anim.key);
59 | });
60 |
61 | this.input.on('pointerdown', function () {
62 | if (lancelot.anims.getName() === 'idle') {
63 | lancelot.playAfterRepeat('guardStart');
64 | lancelot.chain(['guard', 'guardEnd', 'idle']);
65 | }
66 | }, this);
67 | }
68 | }
69 |
70 | // eslint-disable-next-line no-new
71 | new Phaser.Game({
72 | width: 800,
73 | height: 600,
74 | pixelArt: true,
75 | scene: Example,
76 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
77 | audio: {
78 | disableAudio: true
79 | }
80 | });
81 |
--------------------------------------------------------------------------------
/demo/demo-animation.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | Demo of Phaser 3 Inspector Plugin
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/demo-animation.js:
--------------------------------------------------------------------------------
1 | /* global Phaser, PhaserPluginInspector */
2 |
3 | const { AddAnimationState } = PhaserPluginInspector;
4 |
5 | function preload () {
6 | this.load.path = 'assets/animations/aseprite/';
7 |
8 | this.load.aseprite('paladin', 'paladin.png', 'paladin.json');
9 | }
10 |
11 | function create () {
12 | var tags = this.anims.createFromAseprite('paladin');
13 |
14 | var sprite = this.add.sprite(500, 300).play({ key: 'Magnum Break', repeat: -1 }).setScale(6).setName('paladin');
15 |
16 | AddAnimationState(sprite.anims, this.inspectorScene.pane);
17 |
18 | for (var i = 0; i < tags.length; i++) {
19 | var label = this.add.text(32, 32 + (i * 16), tags[i].key, { color: '#00ff00' });
20 |
21 | label.setInteractive();
22 | }
23 |
24 | this.input.on('gameobjectdown', function (pointer, obj) {
25 | sprite.play({
26 | key: obj.text,
27 | repeat: -1
28 | });
29 | });
30 |
31 | this.input.on('gameobjectover', function (pointer, obj) {
32 | obj.setColor('#ff00ff');
33 | });
34 |
35 | this.input.on('gameobjectout', function (pointer, obj) {
36 | obj.setColor('#00ff00');
37 | });
38 | }
39 |
40 | // eslint-disable-next-line no-new
41 | new Phaser.Game({
42 | width: 800,
43 | height: 600,
44 | pixelArt: true,
45 | scene: { preload, create },
46 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
47 | audio: {
48 | disableAudio: true
49 | }
50 | });
51 |
--------------------------------------------------------------------------------
/demo/demo-chain.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 | Demo of Phaser 3 Inspector Plugin
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/demo/demo-chain.js:
--------------------------------------------------------------------------------
1 | /* global PhaserPluginInspector, Tweakpane */
2 |
3 | const { AddChain, AddTween } = PhaserPluginInspector;
4 |
5 | class Example extends Phaser.Scene {
6 | preload () {
7 | this.load.atlas('assets', 'assets/atlas/tweenparts.png', 'assets/atlas/tweenparts.json');
8 | }
9 |
10 | create () {
11 | const chest = this.add.image(400, 600, 'assets', 'blue-closed').setOrigin(0.5, 1);
12 | const key = this.add.image(-200, 300, 'assets', 'simple-key-gold');
13 |
14 | const chain1 = this.tweens.chain({
15 | targets: chest,
16 | tweens: [
17 | {
18 | y: 470,
19 | scaleX: 0.7,
20 | duration: 300,
21 | ease: 'quad.out'
22 | },
23 | {
24 | y: 600,
25 | scaleX: 1,
26 | duration: 1000,
27 | ease: 'bounce.out'
28 | }
29 | ],
30 | loop: -1,
31 | loopDelay: 300
32 | });
33 |
34 | const chain2 = this.tweens.chain({
35 | paused: true,
36 | targets: key,
37 | tweens: [
38 | {
39 | x: 200,
40 | duration: 300,
41 | ease: 'quad.out',
42 | delay: 500
43 | },
44 | {
45 | angle: 360,
46 | duration: 200,
47 | ease: 'linear',
48 | repeat: 4
49 | },
50 | {
51 | angle: 270,
52 | duration: 200,
53 | ease: 'linear'
54 | },
55 | {
56 | scale: 0.65,
57 | y: 380,
58 | duration: 200,
59 | ease: 'power2'
60 | },
61 | {
62 | x: 410,
63 | duration: 300,
64 | ease: 'bounce.out'
65 | },
66 | {
67 | targets: chest,
68 | texture: ['assets', 'blue-open'],
69 | duration: 100
70 | },
71 | {
72 | alpha: 0,
73 | duration: 400,
74 | ease: 'linear'
75 | }
76 | ]
77 | });
78 |
79 | AddChain(chain1, pane);
80 | AddChain(chain2, pane);
81 |
82 | this.input.once('pointerdown', () => {
83 | chain1.completeAfterLoop(0);
84 | chain2.play();
85 | this.openChest(chest, key);
86 | });
87 | }
88 |
89 | openChest (chest, key) {
90 | const tween = this.tweens.add({
91 | targets: chest,
92 | x: 550,
93 | ease: 'power3',
94 | duration: 500
95 | });
96 |
97 | AddTween(tween, pane);
98 | }
99 | }
100 |
101 | const config = {
102 | width: 800,
103 | height: 600,
104 | backgroundColor: '#2d2d2d',
105 | scene: Example
106 | };
107 |
108 | const pane = new Tweakpane.Pane({ title: 'Chains' });
109 |
110 | // eslint-disable-next-line no-unused-vars
111 | const game = new Phaser.Game(config);
112 |
--------------------------------------------------------------------------------
/demo/demo-fx.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | Demo of Phaser 3 Inspector Plugin
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/demo-fx.js:
--------------------------------------------------------------------------------
1 | /* global Phaser, PhaserPluginInspector */
2 |
3 | // eslint-disable-next-line no-unused-vars
4 | const { AddGameObject, AddFXComponent, AddFXController } = PhaserPluginInspector;
5 |
6 | class Example extends Phaser.Scene {
7 | init () {
8 | console.log('renderer', this.renderer);
9 | }
10 |
11 | preload () {
12 | this.load.image('bg', 'assets/skies/space4.png');
13 | this.load.image('lollipop', 'assets/sprites/lollipop.png');
14 | this.load.image('gingerbread', 'assets/sprites/gingerbread.png');
15 | this.load.image('cake', 'assets/sprites/strawberry-cake.png');
16 | }
17 |
18 | create () {
19 | const preMethods = [
20 | 'addBarrel',
21 | // 'addBloom',
22 | 'addBlur',
23 | 'addBokeh',
24 | 'addCircle',
25 | // 'addColorMatrix',
26 | 'addDisplacement',
27 | // 'addGlow',
28 | 'addGradient',
29 | 'addPixelate',
30 | 'addReveal',
31 | 'addShadow',
32 | 'addShine',
33 | 'addTiltShift',
34 | 'addVignette',
35 | 'addWipe'
36 | ];
37 |
38 | this.add.image(400, 300, 'bg');
39 |
40 | const preFXFolder = this.inspectorGame.pane.addFolder({ title: 'Pre Effects' });
41 | const goFolder = this.inspectorGame.pane.addFolder({ title: 'Game Objects' });
42 | const cakes = [];
43 |
44 | for (const m of preMethods) {
45 | const cake = this.add.image(0, 0, 'cake').setName(`cake ${m}`);
46 | cake.preFX.setPadding(8);
47 | const fx = cake.preFX[m]();
48 | AddFXController(fx, preFXFolder, { title: m });
49 | cakes.push(cake);
50 | }
51 |
52 | Phaser.Actions.GridAlign(cakes, { width: 6, cellWidth: 120, cellHeight: 150 });
53 |
54 | const lollipop = this.add.image(400, 400, 'lollipop').setName('lollipop');
55 | lollipop.preFX.setPadding(8);
56 | lollipop.preFX.addColorMatrix().grayscale();
57 | lollipop.preFX.addShadow();
58 |
59 | AddGameObject(lollipop, goFolder);
60 | }
61 | }
62 |
63 | // eslint-disable-next-line no-new
64 | new Phaser.Game({
65 | // type: Phaser.CANVAS,
66 | width: 800,
67 | height: 600,
68 | pixelArt: true,
69 | scene: Example,
70 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
71 | audio: {
72 | disableAudio: true
73 | }
74 | });
75 |
--------------------------------------------------------------------------------
/demo/demo-group.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | Demo of Phaser 3 Inspector Plugin
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/demo-group.js:
--------------------------------------------------------------------------------
1 | /* global Phaser, PhaserPluginInspector, Tweakpane */
2 |
3 | const { AddGroup } = PhaserPluginInspector;
4 |
5 | const pane = new Tweakpane.Pane();
6 |
7 | let group;
8 |
9 | function preload () {
10 | this.load.image('space', 'assets/skies/space.jpg');
11 | this.load.spritesheet('alien', 'assets/tests/invaders/invader1.png', {
12 | frameWidth: 32,
13 | frameHeight: 32
14 | });
15 | }
16 |
17 | function create () {
18 | this.anims.create({
19 | key: 'creep',
20 | frames: this.anims.generateFrameNumbers('alien', { start: 0, end: 1 }),
21 | frameRate: 2,
22 | repeat: -1
23 | });
24 |
25 | this.add.image(512, 384, 'space');
26 |
27 | group = this.add
28 | .group({
29 | defaultKey: 'alien',
30 | maxSize: 50,
31 | createCallback: function (alien) {
32 | alien.setName('alien' + this.getLength());
33 | },
34 | removeCallback: function (alien) {}
35 | })
36 | .setName('aliens');
37 |
38 | AddGroup(group, pane);
39 |
40 | this.time.addEvent({
41 | delay: 200,
42 | repeat: 199,
43 | callback: addAlien
44 | });
45 | }
46 |
47 | function update () {
48 | group.children.iterate(function (alien) {
49 | alien.y += 1;
50 |
51 | if (alien.y > 768) {
52 | group.killAndHide(alien);
53 | }
54 | });
55 | }
56 |
57 | function activateAlien (alien) {
58 | alien
59 | .setActive(true)
60 | .setVisible(true)
61 | .setTint(Phaser.Display.Color.RandomRGB().color)
62 | .play('creep');
63 | }
64 |
65 | function addAlien () {
66 | // Random position above screen
67 | const x = Phaser.Math.Between(0, 1024);
68 | const y = Phaser.Math.Between(-64, 0);
69 |
70 | // Find first inactive sprite in group or add new sprite, and set position
71 | const alien = group.get(x, y);
72 |
73 | // None free or already at maximum amount of sprites in group
74 | if (!alien) return;
75 |
76 | activateAlien(alien);
77 | }
78 |
79 | // eslint-disable-next-line no-new
80 | new Phaser.Game({
81 | width: 800,
82 | height: 600,
83 | pixelArt: true,
84 | scene: { preload, create, update },
85 | audio: {
86 | disableAudio: true
87 | }
88 | });
89 |
--------------------------------------------------------------------------------
/demo/demo-input.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | Demo of Phaser 3 Inspector Plugin
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/demo-input.js:
--------------------------------------------------------------------------------
1 |
2 | /* global Phaser, PhaserPluginInspector */
3 |
4 | const { AddInput } = PhaserPluginInspector;
5 |
6 | function preload () {
7 | this.load.image('ayu', 'assets/pics/ayu2.png');
8 | this.load.image('eye', 'assets/pics/lance-overdose-loader-eye.png');
9 | }
10 |
11 | function create () {
12 | const { pane } = this.inspectorGame;
13 | const zone = this.add.image(500, 300, 'ayu').setInteractive({ dropZone: true }).setName('ayu');
14 | const image = this.add.sprite(200, 300, 'eye').setInteractive({ draggable: true, cursor: 'grab' }).setName('eye');
15 |
16 | AddInput(zone.input, pane);
17 | AddInput(image.input, pane);
18 |
19 | this.input.on('dragstart', function (pointer, gameObject) {
20 | gameObject.setTint(0xff00ff);
21 | });
22 |
23 | this.input.on('drag', function (pointer, gameObject, dragX, dragY) {
24 | gameObject.x = dragX;
25 | gameObject.y = dragY;
26 | });
27 |
28 | this.input.on('dragend', function (pointer, gameObject) {
29 | gameObject.clearTint();
30 | });
31 |
32 | this.input.on('dragenter', function (pointer, gameObject, dropZone) {
33 | dropZone.setTint(0x00ff00);
34 | });
35 |
36 | this.input.on('dragleave', function (pointer, gameObject, dropZone) {
37 | dropZone.clearTint();
38 | });
39 |
40 | this.input.on('drop', function (pointer, gameObject, dropZone) {
41 | gameObject.x = dropZone.x;
42 | gameObject.y = dropZone.y;
43 |
44 | dropZone.clearTint();
45 | });
46 | }
47 |
48 | // eslint-disable-next-line no-new
49 | new Phaser.Game({
50 | scene: { preload, create },
51 | plugins: PhaserPluginInspector.DefaultPluginsConfig
52 | });
53 |
--------------------------------------------------------------------------------
/demo/demo-keyboard.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | Demo of Phaser 3 Inspector Plugin
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/demo-keyboard.js:
--------------------------------------------------------------------------------
1 | /* global Phaser, PhaserPluginInspector */
2 |
3 | const { AddKey, AddKeys } = PhaserPluginInspector;
4 |
5 | function create () {
6 | const { pane } = this.inspectorScene;
7 | const { keyboard } = this.input;
8 |
9 | AddKey(keyboard.addKey('SPACE'), pane);
10 |
11 | AddKeys(keyboard.addKeys('W,A,S,D'), pane);
12 |
13 | AddKeys(keyboard.createCursorKeys(), pane);
14 | }
15 |
16 | // eslint-disable-next-line no-new
17 | new Phaser.Game({
18 | scene: { create },
19 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
20 | audio: {
21 | disableWebAudio: true
22 | }
23 | });
24 |
--------------------------------------------------------------------------------
/demo/demo-light.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | Demo of Phaser 3 Inspector Plugin
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/demo-light.js:
--------------------------------------------------------------------------------
1 | /* global Phaser, PhaserPluginInspector */
2 |
3 | const { AddLight } = PhaserPluginInspector;
4 |
5 | // eslint-disable-next-line no-new
6 | new Phaser.Game({
7 | type: Phaser.WEBGL,
8 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
9 | scene: { preload, create }
10 | });
11 |
12 | function preload () {
13 | this.load.image('robot', ['assets/pics/equality-by-ragnarok.png', 'assets/normal-maps/equality-by-ragnarok_n.png']);
14 | this.load.image('atari', 'assets/sprites/atari400.png');
15 | }
16 |
17 | function create () {
18 | this.lights.enable().setAmbientColor(0x333333);
19 |
20 | const robot = this.add.image(-100, 0, 'robot').setOrigin(0).setScale(0.7);
21 |
22 | robot.setPipeline('Light2D');
23 |
24 | const light = this.lights.addLight(180, 80, 200).setColor(0xffffff).setIntensity(2);
25 |
26 | AddLight(light, this.inspectorScene.pane);
27 | }
28 |
--------------------------------------------------------------------------------
/demo/demo-load.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | Demo of Phaser 3 Inspector Plugin
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/demo-load.js:
--------------------------------------------------------------------------------
1 | /* global Phaser, PhaserPluginInspector */
2 |
3 | // eslint-disable-next-line no-new
4 | new Phaser.Game({
5 | scene: [
6 | {
7 | map: {},
8 |
9 | physics: { arcade: {}, matter: {} },
10 |
11 | preload: function () {
12 | this.sys.load.scripts('inspector', ['../vendor/tweakpane.js', '../dist/phaser-plugin-inspector.umd.js']);
13 | this.sys.load.once('complete', function () {
14 | // eslint-disable-next-line no-undef
15 | PhaserPluginInspector.Install(this.sys.plugins);
16 | }, this);
17 | }
18 | }
19 | ]
20 | });
21 |
--------------------------------------------------------------------------------
/demo/demo-particles.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | Demo of Phaser 3 Inspector Plugin
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/demo-particles.js:
--------------------------------------------------------------------------------
1 |
2 | /* global Phaser, PhaserPluginInspector */
3 |
4 | const { AddGameObject, AddParticleEmitter } = PhaserPluginInspector;
5 |
6 | function preload () {
7 | this.load.atlas('flares', 'assets/particles/flares.png', 'assets/particles/flares.json');
8 | this.load.image('bg', 'assets/skies/darkstone.png');
9 | this.load.image('flare', 'assets/particles/white-flare.png');
10 | this.load.image('fox', 'assets/pics/card3.png');
11 | }
12 |
13 | function create () {
14 | createGlowEmitter.call(this);
15 | createZoneEmitter.call(this);
16 | }
17 |
18 | function createGlowEmitter () {
19 | this.add.image(400, 300, 'bg');
20 |
21 | const card = this.add.image(400, 300, 'fox').setInteractive();
22 |
23 | const emitZone1 = { type: 'edge', source: card.getBounds(), quantity: 42 };
24 |
25 | const emitter = this.add.particles(0, 0, 'flare', {
26 | speed: 24,
27 | frequency: -1,
28 | lifespan: 2000,
29 | quantity: 100,
30 | maxParticles: 1000,
31 | scale: { start: 0.4, end: 0 },
32 | color: [0xffffff, 0x00ffff, 0x0000ff],
33 | emitZone: emitZone1,
34 | duration: 1000,
35 | emitting: false
36 | });
37 |
38 | card.on('pointerdown', () => {
39 | emitter.explode();
40 | });
41 |
42 | const { pane } = this.inspectorScene;
43 |
44 | AddParticleEmitter(emitter, pane);
45 | AddGameObject(emitter, pane);
46 | }
47 |
48 | function createZoneEmitter () {
49 | const shape1 = new Phaser.Geom.Circle(0, 0, 160);
50 | const shape2 = new Phaser.Geom.Ellipse(0, 0, 500, 150);
51 | const shape3 = new Phaser.Geom.Rectangle(-150, -150, 300, 300);
52 | const shape4 = new Phaser.Geom.Line(-150, -150, 150, 150);
53 | const shape5 = new Phaser.Geom.Triangle.BuildEquilateral(0, -140, 300);
54 |
55 | const emitter = this.add.particles(400, 300, 'flares', {
56 | blendMode: 'ADD',
57 | delay: 100,
58 | duration: 60000,
59 | frame: { frames: ['red', 'green', 'blue'], cycle: true },
60 | frequency: 25,
61 | hold: 200,
62 | lifespan: 600,
63 | maxAliveParticles: 100,
64 | name: 'cycling flares',
65 | scale: { start: 0.6, end: 0.1 }
66 | });
67 |
68 | emitter.addEmitZone({ type: 'edge', source: shape1, quantity: 32, total: 64 });
69 | emitter.addEmitZone({ type: 'edge', source: shape2, quantity: 32, total: 64 });
70 | emitter.addEmitZone({ type: 'edge', source: shape3, quantity: 32, total: 64 });
71 | emitter.addEmitZone({ type: 'edge', source: shape4, quantity: 32, total: 64 });
72 | emitter.addEmitZone({ type: 'edge', source: shape5, quantity: 32, total: 64 });
73 |
74 | emitter.createGravityWell({
75 | x: 0,
76 | y: 0,
77 | power: 2,
78 | epsilon: 200,
79 | gravity: 100
80 | });
81 |
82 | console.log('emitter', emitter);
83 |
84 | const { pane } = this.inspectorScene;
85 |
86 | AddParticleEmitter(emitter, pane);
87 | AddGameObject(emitter, pane);
88 | }
89 |
90 | function update () {
91 | }
92 |
93 | // eslint-disable-next-line no-new
94 | new Phaser.Game({
95 | scene: { preload, create, update },
96 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
97 | audio: {
98 | disableAudio: true
99 | }
100 | });
101 |
--------------------------------------------------------------------------------
/demo/demo-plane.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | Demo of Phaser 3 Inspector Plugin
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/demo-plane.js:
--------------------------------------------------------------------------------
1 | /* global Phaser, PhaserPluginInspector */
2 |
3 | const { AddGameObject } = PhaserPluginInspector;
4 |
5 | class Example extends Phaser.Scene {
6 | preload () {
7 | this.load.image('bg', 'assets/skies/space4.png');
8 | this.load.image('pudding', 'assets/tests/pipeline/pudding.png');
9 | }
10 |
11 | create () {
12 | this.add.image(400, 300, 'bg');
13 |
14 | // For NPOT textures (like our pudding texture) you cannot uvScale
15 | // them, because WebGL1 doesn't support this. So instead we can
16 | // create a Plane that is 8x8 cells in size and tile the texture
17 | // across each cell (the last 3 parameters)
18 | const plane = this.add.plane(400, 300, 'pudding', null, 8, 8, true).setName('pudding');
19 |
20 | plane.setViewHeight(512);
21 |
22 | plane.modelRotation.x = -0.59;
23 | plane.modelRotation.y = 0.707;
24 | plane.viewPosition.z = 2.209;
25 |
26 | const rotateRate = 1;
27 | const panRate = 1;
28 | const zoomRate = 4;
29 |
30 | this.input.on('pointermove', pointer => {
31 | if (!pointer.isDown) {
32 | return;
33 | }
34 |
35 | if (!pointer.event.shiftKey) {
36 | plane.modelRotation.y += pointer.velocity.x * (rotateRate / 800);
37 | plane.modelRotation.x += pointer.velocity.y * (rotateRate / 600);
38 | } else {
39 | plane.panX(pointer.velocity.x * (panRate / 800));
40 | plane.panY(pointer.velocity.y * (panRate / 600));
41 | }
42 | });
43 |
44 | this.input.on('wheel', (pointer, over, deltaX, deltaY, deltaZ) => {
45 | plane.panZ(deltaY * (zoomRate / 600));
46 | });
47 |
48 | AddGameObject(plane, this.inspectorScene.pane);
49 | }
50 | }
51 |
52 | // eslint-disable-next-line no-new
53 | new Phaser.Game({
54 | width: 800,
55 | height: 600,
56 | pixelArt: true,
57 | scene: Example,
58 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
59 | audio: {
60 | disableAudio: true
61 | }
62 | });
63 |
--------------------------------------------------------------------------------
/demo/demo-play.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | Demo of Phaser 3 Inspector Plugin
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/demo-play.js:
--------------------------------------------------------------------------------
1 |
2 | /* global Phaser, PhaserPluginInspector */
3 |
4 | console.info(PhaserPluginInspector);
5 | // console.info('{ %s }', Object.keys(PhaserPluginInspector).sort().join(', '));
6 |
7 | const { AddArcadeBody, AddGameObject, AddParticleEmitter } = PhaserPluginInspector;
8 |
9 | let sky;
10 |
11 | function preload () {
12 | this.load.image('sky', 'assets/skies/starfield.png');
13 | this.load.image('logo', 'assets/sprites/phaser3-logo.png');
14 | this.load.image('red', 'assets/particles/red.png');
15 | }
16 |
17 | function create () {
18 | sky = this.add.tileSprite(0, 0, 1024, 768, 'sky')
19 | .setOrigin(0, 0)
20 | .setName('sky');
21 |
22 | const emitter = this.add.particles(0, 0, 'red', {
23 | name: 'red flares',
24 | frequency: 25,
25 | speed: 100,
26 | scale: { start: 1, end: 0 },
27 | blendMode: 'ADD'
28 | });
29 |
30 | const ghost = this.physics.add.image(400, 150, 'logo')
31 | .setAlpha(0.2);
32 |
33 | ghost.body.setAllowGravity(false);
34 |
35 | const logo = this.physics.add.image(400, 100, 'logo')
36 | .setName('logo')
37 | .setVelocity(100, 200)
38 | .setBounce(1, 1)
39 | .setCollideWorldBounds(true);
40 |
41 | this.physics.add.overlap(ghost, logo);
42 |
43 | emitter.startFollow(logo);
44 |
45 | const { pane } = this.inspectorScene;
46 |
47 | AddGameObject(sky, pane);
48 | AddGameObject(logo, pane);
49 | AddArcadeBody(logo.body, pane);
50 | AddGameObject(emitter, pane);
51 | AddParticleEmitter(emitter, pane);
52 | }
53 |
54 | function update () {
55 | sky.tilePositionX += 1;
56 | }
57 |
58 | // eslint-disable-next-line no-new
59 | new Phaser.Game({
60 | scene: { preload, create, update },
61 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
62 | audio: {
63 | disableWebAudio: true
64 | },
65 | physics: {
66 | default: 'arcade',
67 | arcade: {
68 | debug: true,
69 | gravity: { y: 200 }
70 | }
71 | }
72 | });
73 |
--------------------------------------------------------------------------------
/demo/demo-postfx.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 | Demo of Phaser 3 Inspector Plugin
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/demo/demo-postfx.js:
--------------------------------------------------------------------------------
1 | /* global Phaser, PhaserPluginInspector */
2 |
3 | const { AddGameObject, AddFXComponent, AddFXController } = PhaserPluginInspector;
4 |
5 | class Example extends Phaser.Scene {
6 | create () {
7 | const graphics = this.add.graphics().setName('with glow and wipe postFX');
8 |
9 | graphics.fillStyle(0xffff00, 1);
10 | graphics.fillRect(100, 100, 256, 256);
11 |
12 | graphics.fillStyle(0xff00ff, 1);
13 | graphics.fillRect(300, 200, 256, 256);
14 |
15 | graphics.fillStyle(0x00ff00, 1);
16 | graphics.fillTriangle(200, 200, 400, 50, 500, 300);
17 |
18 | const glow = graphics.postFX.addGlow();
19 | const wipe = graphics.postFX.addWipe();
20 |
21 | wipe.progress = 0.25;
22 |
23 | const { pane } = this.inspectorGame;
24 |
25 | AddFXController(glow, pane);
26 | AddFXController(wipe, pane);
27 |
28 | // Only `clear()` is useful:
29 | AddFXComponent(graphics.postFX, pane, { title: 'Post FX (always active, always enabled)' });
30 |
31 | AddGameObject(graphics, pane);
32 | }
33 | }
34 |
35 | // eslint-disable-next-line no-new
36 | new Phaser.Game({
37 | // type: Phaser.CANVAS,
38 | width: 800,
39 | height: 600,
40 | scene: Example,
41 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
42 | audio: {
43 | disableAudio: true
44 | }
45 | });
46 |
--------------------------------------------------------------------------------
/demo/demo-sound-markers.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | Demo of Phaser 3 Inspector Plugin
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/demo-sound-markers.js:
--------------------------------------------------------------------------------
1 |
2 | /* global Phaser, PhaserPluginInspector */
3 |
4 | const { AddSound } = PhaserPluginInspector;
5 |
6 | function preload () {
7 | this.load.image('bg', 'assets/pics/cougar-dragonsun.png');
8 | this.load.audio('sfx', [
9 | 'assets/audio/SoundEffects/magical_horror_audiosprite.ogg',
10 | 'assets/audio/SoundEffects/magical_horror_audiosprite.mp3'
11 | ]);
12 | }
13 |
14 | function create () {
15 | this.add.image(400, 300, 'bg');
16 |
17 | const fx = this.sound.add('sfx');
18 |
19 | const markers = [
20 | { name: 'charm', start: 0, duration: 2.7, config: {} },
21 | { name: 'curse', start: 4, duration: 2.9, config: {} },
22 | { name: 'fireball', start: 8, duration: 5.2, config: {} },
23 | { name: 'spell', start: 14, duration: 4.7, config: {} },
24 | { name: 'soundscape', start: 20, duration: 18.8, config: {} }
25 | ];
26 |
27 | for (const marker of markers) {
28 | fx.addMarker(marker);
29 | }
30 |
31 | AddSound(fx, this.inspectorGame.pane);
32 | }
33 |
34 | // eslint-disable-next-line no-new
35 | new Phaser.Game({
36 | scene: { preload, create },
37 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
38 | audio: {
39 | disableWebAudio: true
40 | }
41 | });
42 |
--------------------------------------------------------------------------------
/demo/demo-sound.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | Demo of Phaser 3 Inspector Plugin
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/demo-sound.js:
--------------------------------------------------------------------------------
1 |
2 | /* global Phaser, PhaserPluginInspector */
3 |
4 | const { AddSound } = PhaserPluginInspector;
5 |
6 | function preload () {
7 | this.load.audio('music', 'assets/audio/Ludwig van Beethoven - The Creatures of Prometheus, Op. 43/Overture.mp3');
8 | }
9 |
10 | function create () {
11 | const music = this.sound.add('music');
12 | music.play();
13 |
14 | const { pane } = this.inspectorScene;
15 |
16 | AddSound(music, pane);
17 |
18 | this.scene.remove();
19 | }
20 |
21 | // eslint-disable-next-line no-new
22 | new Phaser.Game({
23 | scene: { preload, create },
24 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
25 | audio: {
26 | disableWebAudio: true
27 | }
28 | });
29 |
--------------------------------------------------------------------------------
/demo/demo-tilemap.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 | Demo of Phaser 3 Inspector Plugin
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/demo/demo-tilemap.js:
--------------------------------------------------------------------------------
1 | /* global PhaserPluginInspector, Tweakpane */
2 |
3 | const { AddAlpha, AddVisible, AddGameObject } = PhaserPluginInspector;
4 |
5 | const pane = new Tweakpane.Pane({ title: 'Tilemap Demo' });
6 |
7 | class Example extends Phaser.Scene {
8 | preload () {
9 | this.load.image('kenny_platformer_64x64', 'assets/tilemaps/tiles/kenny_platformer_64x64.png');
10 | this.load.tilemapTiledJSON('multiple-layers-map', 'assets/tilemaps/maps/multiple-layers.json');
11 | }
12 |
13 | create () {
14 | this.map = this.make.tilemap({ key: 'multiple-layers-map' });
15 |
16 | const tiles = this.map.addTilesetImage('kenny_platformer_64x64');
17 |
18 | const grid = this.add.grid(
19 | 0, 0,
20 | this.map.widthInPixels, this.map.heightInPixels,
21 | this.map.tileWidth, this.map.tileHeight,
22 | 0, 1,
23 | 0xffff00, 1
24 | ).setAlpha(0.2).setOrigin(0, 0);
25 |
26 | for (const layer of this.map.layers) {
27 | this.map.createLayer(layer.name, tiles).setName(layer.name);
28 | }
29 |
30 | this.map.getLayer('Water Layer').tilemapLayer.setAlpha(0.8);
31 |
32 | const tilemapLayers = this.map.layers.map(l => l.tilemapLayer);
33 |
34 | AddAlpha([grid, ...tilemapLayers], pane);
35 | AddVisible([grid, ...tilemapLayers], pane);
36 |
37 | for (const tilemapLayer of tilemapLayers) {
38 | AddGameObject(tilemapLayer, pane, { title: tilemapLayer.name, expanded: false });
39 | }
40 |
41 | const cursors = this.input.keyboard.createCursorKeys();
42 | const controlConfig = {
43 | camera: this.cameras.main,
44 | left: cursors.left,
45 | right: cursors.right,
46 | up: cursors.up,
47 | down: cursors.down,
48 | speed: 1
49 | };
50 |
51 | this.controls = new Phaser.Cameras.Controls.FixedKeyControl(controlConfig);
52 | }
53 |
54 | update (time, delta) {
55 | this.controls.update(delta);
56 | }
57 | }
58 |
59 | const config = {
60 | width: 1024,
61 | height: 1024,
62 | pixelArt: true,
63 | scene: Example
64 | };
65 |
66 | // eslint-disable-next-line no-new
67 | new Phaser.Game(config);
68 |
--------------------------------------------------------------------------------
/demo/demo-timeline.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 | Demo of Phaser 3 Inspector Plugin
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/demo/demo-timeline.js:
--------------------------------------------------------------------------------
1 | /* global PhaserPluginInspector, Tweakpane */
2 |
3 | const { AddTimeline } = PhaserPluginInspector;
4 |
5 | class Example extends Phaser.Scene {
6 | preload () {
7 | this.load.atlas('timeline', 'assets/atlas/timeline.png', 'assets/atlas/timeline.json');
8 | this.load.image('bg', 'assets/skies/spookysky.jpg');
9 | this.load.atlas('flares', 'assets/particles/flares.png', 'assets/particles/flares.json');
10 | }
11 |
12 | create () {
13 | this.add.image(400, 300, 'bg');
14 |
15 | const crystalball = this.add.sprite(400, 800, 'timeline', 'crystalball');
16 |
17 | const glowFX = crystalball.preFX.addGlow();
18 |
19 | const emitter = this.add.particles(400, 300, 'flares', {
20 | frame: 'white',
21 | blendMode: 'ADD',
22 | lifespan: 1200,
23 | gravityY: -100,
24 | scale: { start: 0.3, end: 0 },
25 | emitting: false
26 | });
27 |
28 | emitter.addEmitZone({ source: new Phaser.Geom.Circle(0, -20, 90) });
29 |
30 | const timeline = this.add.timeline([
31 | {
32 | at: 0,
33 | run: () => {
34 | glowFX.setActive(false);
35 | glowFX.outerStrength = 0;
36 | glowFX.innerStrength = 0;
37 | },
38 | tween: {
39 | targets: crystalball,
40 | y: 300,
41 | ease: 'sine.in',
42 | duration: 750
43 | }
44 | },
45 | {
46 | at: 1000,
47 | run: () => {
48 | glowFX.setActive(true);
49 | emitter.start();
50 | },
51 | tween: {
52 | targets: glowFX,
53 | outerStrength: 16,
54 | innerStrength: 8,
55 | ease: 'sine.in',
56 | yoyo: true,
57 | duration: 500,
58 | repeat: 3
59 | }
60 | },
61 | {
62 | at: 4000,
63 | run: () => {
64 | emitter.stop();
65 | },
66 | tween: {
67 | targets: crystalball,
68 | y: 800,
69 | ease: 'sine.in',
70 | duration: 500
71 | }
72 | },
73 | {
74 | at: 5000,
75 | stop: true
76 | }
77 | ]);
78 |
79 | AddTimeline(timeline, pane);
80 |
81 | timeline.play();
82 | }
83 | }
84 |
85 | const config = {
86 | width: 800,
87 | height: 600,
88 | scene: Example
89 | };
90 |
91 | const pane = new Tweakpane.Pane({ title: 'Timeline Demo' });
92 |
93 | // eslint-disable-next-line no-unused-vars
94 | const game = new Phaser.Game(config);
95 |
--------------------------------------------------------------------------------
/demo/demo-timer-event.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 | Demo of Phaser 3 Inspector Plugin
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/demo/demo-timer-event.js:
--------------------------------------------------------------------------------
1 | /* global PhaserPluginInspector */
2 |
3 | const { AddTimerEvent } = PhaserPluginInspector;
4 |
5 | class Example extends Phaser.Scene {
6 | preload () {
7 | this.load.atlas('timeline', 'assets/atlas/timeline.png', 'assets/atlas/timeline.json');
8 | this.load.image('bg', 'assets/skies/spookysky.jpg');
9 | }
10 |
11 | create () {
12 | // this.time.paused = true;
13 |
14 | this.add.image(400, 300, 'bg');
15 |
16 | const bat = this.add.sprite(200, 150, 'timeline', 'bat');
17 |
18 | const timer = this.time.addEvent({
19 | delay: 200,
20 | startAt: 0,
21 | repeat: 9,
22 | callback: () => {
23 | bat.angle += 36;
24 | }
25 | });
26 |
27 | AddTimerEvent(timer, this.inspectorGame.pane);
28 | }
29 | }
30 |
31 | const gameConfig = {
32 | width: 800,
33 | height: 600,
34 | scene: Example,
35 | plugins: PhaserPluginInspector.DefaultPluginsConfig
36 | };
37 |
38 | // eslint-disable-next-line no-unused-vars
39 | const game = new Phaser.Game(gameConfig);
40 |
--------------------------------------------------------------------------------
/demo/demo-tween.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | Demo of Phaser 3 Inspector Plugin
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/demo-tween.js:
--------------------------------------------------------------------------------
1 |
2 | /* global Phaser, PhaserPluginInspector */
3 |
4 | const { AddTween } = PhaserPluginInspector;
5 |
6 | function preload () {
7 | this.load.image('block', 'assets/sprites/block.png');
8 | }
9 |
10 | function create () {
11 | const image1 = this.add.image(130, 50, 'block');
12 | const image2 = this.add.image(190, 80, 'block');
13 | const image3 = this.add.image(50, 150, 'block');
14 |
15 | const tween = this.tweens.add({
16 | targets: [image1, image2, image3],
17 | props: {
18 | x: { value: '+=600', duration: 3000, ease: 'Power2' },
19 | y: { value: '500', duration: 1500, ease: 'Bounce.easeOut' }
20 | },
21 | delay: 1000
22 | });
23 |
24 | const folder = AddTween(tween, this.inspectorScene.pane);
25 |
26 | this.events.once('shutdown', () => { folder.dispose(); });
27 | }
28 |
29 | function update () {
30 | }
31 |
32 | // eslint-disable-next-line no-new
33 | new Phaser.Game({
34 | scene: { preload, create, update },
35 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
36 | audio: {
37 | disableWebAudio: true
38 | }
39 | });
40 |
--------------------------------------------------------------------------------
/demo/demo-video.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | Demo of Phaser 3 Inspector Plugin
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/demo-video.js:
--------------------------------------------------------------------------------
1 | /* global Phaser, PhaserPluginInspector */
2 |
3 | const { AddGameObject, AddVideo } = PhaserPluginInspector;
4 |
5 | class Example extends Phaser.Scene {
6 | preload () {
7 | this.load.video('spaceace', 'assets/video/spaceace.mp4');
8 | this.load.video('underwater', 'assets/video/underwater.mp4');
9 | }
10 |
11 | create () {
12 | const intro = this.add.video(360, 240, 'underwater').setName('intro');
13 |
14 | intro.on('locked', () => {
15 | const message = this.add.text(360, 120, '👆 Click to play video', { font: '32px Courier', fill: '#00ff00' }).setShadow(1, 1).setOrigin(0.5);
16 |
17 | intro.on('unlocked', () => {
18 | message.destroy();
19 | });
20 | });
21 |
22 | intro.play();
23 |
24 | AddVideo(intro, this.inspectorScene.pane);
25 | AddGameObject(intro, this.inspectorScene.pane);
26 | }
27 | }
28 |
29 | // eslint-disable-next-line no-new
30 | new Phaser.Game({
31 | width: 720,
32 | height: 480,
33 | scene: Example,
34 | plugins: PhaserPluginInspector.DefaultPluginsConfig
35 | });
36 |
--------------------------------------------------------------------------------
/demo/demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | Demo of Phaser 3 Inspector Plugin
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/demo.js:
--------------------------------------------------------------------------------
1 |
2 | /* global Phaser, PhaserPluginInspector */
3 |
4 | // eslint-disable-next-line no-new
5 | new Phaser.Game({
6 | type: Phaser.CANVAS,
7 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
8 | scene: [
9 | { key: 'active' },
10 | { key: 'arcade', physics: { arcade: {} } },
11 | { key: 'matter', physics: { matter: {} } },
12 | { key: 'plugins', plugins: ['InspectorScenePlugin'], active: true },
13 | { key: 'shutdown', active: true, update: function () { this.scene.stop(); } },
14 | { key: 'remove', active: true, update: function () { this.scene.remove(); } }
15 | ]
16 | });
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "phaser-plugin-inspector",
3 | "version": "2.6.0",
4 | "description": "View and change Phaser 3 game properties",
5 | "type": "module",
6 | "module": "dist/phaser-plugin-inspector.esm.js",
7 | "browser": "dist/phaser-plugin-inspector.umd.js",
8 | "files": [
9 | "dist",
10 | "src"
11 | ],
12 | "directories": {
13 | "test": "test"
14 | },
15 | "devDependencies": {
16 | "@rollup/plugin-buble": "^0.21.3",
17 | "@rollup/plugin-commonjs": "^11.1.0",
18 | "@rollup/plugin-node-resolve": "^7.1.3",
19 | "acorn": "^6.4.1",
20 | "chai": "^4.2.0",
21 | "eslint": "^8.57.1",
22 | "eslint-config-semistandard": "^15.0.1",
23 | "eslint-config-standard": "^14.1.1",
24 | "eslint-plugin-import": "^2.22.0",
25 | "eslint-plugin-node": "^10.0.0",
26 | "eslint-plugin-promise": "^4.2.1",
27 | "eslint-plugin-standard": "^4.0.1",
28 | "mocha": "^10.8.2",
29 | "phaser": "3.87.0",
30 | "rollup": "^2.23.0",
31 | "tweakpane": "3.1.10"
32 | },
33 | "peerDependencies": {
34 | "phaser": "^3.60.0",
35 | "tweakpane": "^3.1.0"
36 | },
37 | "scripts": {
38 | "build": "rollup -c",
39 | "clean": "rm dist/*.js",
40 | "dev": "rollup -c -w",
41 | "postbuild": "node -c dist/phaser-plugin-inspector.umd.js",
42 | "vendor": "cp -v node_modules/tweakpane/dist/tweakpane.js node_modules/mocha/mocha.{css,js} node_modules/chai/chai.js node_modules/phaser/dist/phaser.js vendor/",
43 | "preversion": "npm run build",
44 | "test": "eslint src"
45 | },
46 | "repository": {
47 | "type": "git",
48 | "url": "git+https://github.com/samme/phaser-plugin-inspector.git"
49 | },
50 | "keywords": [
51 | "phaser",
52 | "phaser-plugin",
53 | "phaser3",
54 | "phaser3-plugin",
55 | "tweakpane"
56 | ],
57 | "author": "samme",
58 | "license": "ISC",
59 | "bugs": {
60 | "url": "https://github.com/samme/phaser-plugin-inspector/issues"
61 | },
62 | "homepage": "https://github.com/samme/phaser-plugin-inspector#readme"
63 | }
64 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import resolve from '@rollup/plugin-node-resolve';
2 | import commonjs from '@rollup/plugin-commonjs';
3 | import pkg from './package.json';
4 |
5 | export default [
6 | {
7 | external: ['phaser', 'tweakpane'],
8 | input: 'src/main.js',
9 | output: [
10 | {
11 | name: 'PhaserPluginInspector',
12 | file: pkg.browser,
13 | format: 'umd',
14 | globals: { phaser: 'Phaser', tweakpane: 'Tweakpane' }
15 | },
16 | {
17 | file: pkg.module,
18 | format: 'es'
19 | }
20 | ],
21 | plugins: [
22 | resolve(),
23 | commonjs()
24 | ]
25 | }
26 | ];
27 |
--------------------------------------------------------------------------------
/src/DefaultPluginsConfig.js:
--------------------------------------------------------------------------------
1 | import { InspectorGlobalPlugin } from './InspectorGlobalPlugin';
2 | import { InspectorScenePlugin } from './InspectorScenePlugin';
3 | import {
4 | GLOBAL_PLUGIN_KEY,
5 | GLOBAL_PLUGIN_MAPPING,
6 | SCENE_PLUGIN_KEY,
7 | SCENE_PLUGIN_SCENE_MAPPING
8 | } from './const';
9 |
10 | export const DefaultPluginsConfig = {
11 | global: [{ key: GLOBAL_PLUGIN_KEY, plugin: InspectorGlobalPlugin, mapping: GLOBAL_PLUGIN_MAPPING }],
12 | scene: [{ key: SCENE_PLUGIN_KEY, plugin: InspectorScenePlugin, mapping: SCENE_PLUGIN_SCENE_MAPPING }]
13 | };
14 |
--------------------------------------------------------------------------------
/src/EaseMap.js:
--------------------------------------------------------------------------------
1 | import Phaser from 'phaser';
2 |
3 | const {
4 | Back,
5 | Bounce,
6 | Circular,
7 | Cubic,
8 | Elastic,
9 | Expo,
10 | Linear,
11 | Quadratic,
12 | Quartic,
13 | Quintic,
14 | Sine,
15 | Stepped
16 | } = Phaser.Math.Easing;
17 |
18 | /**
19 | * EaseMap
20 | *
21 | * @author Richard Davey
22 | * @copyright 2013-2024 Phaser Studio Inc.
23 | * @license {@link https://opensource.org/licenses/MIT|MIT License}
24 | */
25 |
26 | export const EaseMap = {
27 | Power0: Linear,
28 | Power1: Quadratic.Out,
29 | Power2: Cubic.Out,
30 | Power3: Quartic.Out,
31 | Power4: Quintic.Out,
32 |
33 | Linear: Linear,
34 | Quad: Quadratic.Out,
35 | Cubic: Cubic.Out,
36 | Quart: Quartic.Out,
37 | Quint: Quintic.Out,
38 | Sine: Sine.Out,
39 | Expo: Expo.Out,
40 | Circ: Circular.Out,
41 | Elastic: Elastic.Out,
42 | Back: Back.Out,
43 | Bounce: Bounce.Out,
44 | Stepped: Stepped,
45 |
46 | 'Quad.easeIn': Quadratic.In,
47 | 'Cubic.easeIn': Cubic.In,
48 | 'Quart.easeIn': Quartic.In,
49 | 'Quint.easeIn': Quintic.In,
50 | 'Sine.easeIn': Sine.In,
51 | 'Expo.easeIn': Expo.In,
52 | 'Circ.easeIn': Circular.In,
53 | 'Elastic.easeIn': Elastic.In,
54 | 'Back.easeIn': Back.In,
55 | 'Bounce.easeIn': Bounce.In,
56 |
57 | 'Quad.easeOut': Quadratic.Out,
58 | 'Cubic.easeOut': Cubic.Out,
59 | 'Quart.easeOut': Quartic.Out,
60 | 'Quint.easeOut': Quintic.Out,
61 | 'Sine.easeOut': Sine.Out,
62 | 'Expo.easeOut': Expo.Out,
63 | 'Circ.easeOut': Circular.Out,
64 | 'Elastic.easeOut': Elastic.Out,
65 | 'Back.easeOut': Back.Out,
66 | 'Bounce.easeOut': Bounce.Out,
67 |
68 | 'Quad.easeInOut': Quadratic.InOut,
69 | 'Cubic.easeInOut': Cubic.InOut,
70 | 'Quart.easeInOut': Quartic.InOut,
71 | 'Quint.easeInOut': Quintic.InOut,
72 | 'Sine.easeInOut': Sine.InOut,
73 | 'Expo.easeInOut': Expo.InOut,
74 | 'Circ.easeInOut': Circular.InOut,
75 | 'Elastic.easeInOut': Elastic.InOut,
76 | 'Back.easeInOut': Back.InOut,
77 | 'Bounce.easeInOut': Bounce.InOut
78 | };
79 |
--------------------------------------------------------------------------------
/src/FXMap.js:
--------------------------------------------------------------------------------
1 | export const FXMap = {
2 | 4: 'GLOW',
3 | 5: 'SHADOW',
4 | 6: 'PIXELATE',
5 | 7: 'VIGNETTE',
6 | 8: 'SHINE',
7 | 9: 'BLUR',
8 | 12: 'GRADIENT',
9 | 13: 'BLOOM',
10 | 14: 'COLOR_MATRIX',
11 | 15: 'CIRCLE',
12 | 16: 'BARREL',
13 | 17: 'DISPLACEMENT',
14 | 18: 'WIPE',
15 | 19: 'BOKEH'
16 | };
17 |
--------------------------------------------------------------------------------
/src/InspectorGlobalPlugin.js:
--------------------------------------------------------------------------------
1 | import Phaser from 'phaser';
2 | import { Pane } from 'tweakpane';
3 | import {
4 | AddPointer,
5 | AddScenes,
6 | copyToSafeObj,
7 | animToPrint,
8 | FormatLength,
9 | sceneToPrint,
10 | soundToPrint,
11 | textureToPrint,
12 | printCaches,
13 | printDevice,
14 | snapshot
15 | } from './util';
16 |
17 | export class InspectorGlobalPlugin extends Phaser.Plugins.BasePlugin {
18 | constructor (pluginManager) {
19 | if (Phaser.VERSION.split('.')[1] < 60) {
20 | throw new Error('Phaser v3.60 or later is required');
21 | }
22 |
23 | super(pluginManager);
24 |
25 | this.pane = null;
26 | this.style = null;
27 | }
28 |
29 | init (data) {
30 | }
31 |
32 | start () {
33 | this.pane = new Pane({ title: 'Inspector' });
34 |
35 | this.add();
36 |
37 | this.style = document.createElement('style');
38 | this.style.innerText = '.tp-dfwv { top: 0; width: 320px; max-height: 100%; overflow: auto }';
39 | document.head.appendChild(this.style);
40 | }
41 |
42 | stop () {
43 | document.head.removeChild(this.style);
44 | this.style = null;
45 | this.pane.dispose();
46 | this.pane = null;
47 | }
48 |
49 | destroy () {
50 | this.stop();
51 | super.destroy();
52 | }
53 |
54 | add () {
55 | const { game, pane } = this;
56 | const { anims, cache, device, input, loop, registry, renderer, scale, scene, sound, textures } = game;
57 | const { keyboard, touch } = input;
58 |
59 | pane.addButton({ title: 'Refresh' }).on('click', () => { console.time('refresh'); pane.refresh(); console.timeEnd('refresh'); });
60 |
61 | const folder = pane.addFolder({ title: 'Game', expanded: false });
62 |
63 | folder.addMonitor(game, 'hasFocus');
64 | folder.addMonitor(game, 'isPaused');
65 | folder.addButton({ title: 'Pause' }).on('click', () => { console.info('Pause game'); game.pause(); });
66 | folder.addButton({ title: 'Resume' }).on('click', () => { console.info('Resume game'); game.resume(); });
67 | folder.addButton({ title: 'Step' }).on('click', () => { const t = performance.now(); const dt = loop._target; console.info('step', t, dt); game.step(t, dt); });
68 | folder.addButton({ title: 'Destroy' }).on('click', () => { console.info('Destroy game'); game.destroy(true); });
69 |
70 | const animsFolder = folder.addFolder({ title: 'Animations', expanded: false });
71 | animsFolder.addButton({ title: 'Pause all' }).on('click', () => { console.info('Pause all animations'); anims.pauseAll(); });
72 | animsFolder.addButton({ title: 'Resume all' }).on('click', () => { console.info('Resume all animations'); anims.resumeAll(); });
73 | animsFolder.addButton({ title: 'Print animations' }).on('click', () => { console.info('Animations:'); console.table(anims.anims.getArray().map(animToPrint)); });
74 | animsFolder.addButton({ title: 'Print JSON' }).on('click', () => { console.info(JSON.stringify(anims.toJSON())); });
75 |
76 | const cacheFolder = folder.addFolder({ title: 'Cache', expanded: false });
77 | cacheFolder.addButton({ title: 'Print cache contents' }).on('click', () => { printCaches(cache); });
78 |
79 | const configFolder = folder.addFolder({ title: 'Config', expanded: false });
80 | configFolder.addButton({ title: 'Print game config' }).on('click', () => { console.info('Game config (partial):'); console.table(copyToSafeObj(game.config)); });
81 |
82 | const deviceFolder = folder.addFolder({ title: 'Device', expanded: false });
83 | deviceFolder.addButton({ title: 'Print device info' }).on('click', () => { console.info('Device:'); printDevice(device); });
84 |
85 | const inputFolder = folder.addFolder({ title: 'Input', expanded: false });
86 | inputFolder.addMonitor(input, 'isOver');
87 | inputFolder.addInput(input, 'enabled');
88 | inputFolder.addInput(input, 'globalTopOnly');
89 |
90 | for (const pointer of input.pointers) {
91 | AddPointer(pointer, inputFolder);
92 | }
93 |
94 | if (keyboard) {
95 | const keyboardFolder = folder.addFolder({ title: 'Keyboard', expanded: false });
96 | keyboardFolder.addInput(keyboard, 'enabled');
97 | keyboardFolder.addMonitor(keyboard, 'preventDefault');
98 | }
99 |
100 | if (touch) {
101 | const touchFolder = folder.addFolder({ title: 'Touch', expanded: false });
102 | touchFolder.addInput(touch, 'capture');
103 | touchFolder.addInput(touch, 'enabled');
104 | }
105 |
106 | const loopProxy = {
107 | get 'getDuration()' () { return loop.getDuration(); }
108 | };
109 | const loopFolder = folder.addFolder({ title: 'Loop', expanded: false });
110 | loopFolder.addMonitor(loop, 'actualFps', { view: 'graph', min: 0, max: 120 });
111 | loopFolder.addMonitor(loop, 'delta', { view: 'graph', min: 0, max: 50 });
112 | loopFolder.addMonitor(loop, 'frame', { format: Math.floor });
113 | loopFolder.addMonitor(loopProxy, 'getDuration()');
114 | loopFolder.addMonitor(loop, 'now');
115 | loopFolder.addMonitor(loop, 'rawDelta', { view: 'graph', min: 0, max: 50 });
116 | loopFolder.addMonitor(loop, 'running');
117 | loopFolder.addMonitor(loop, 'startTime');
118 | loopFolder.addMonitor(loop, 'time');
119 | loopFolder.addButton({ title: 'Sleep' }).on('click', () => { console.info('Sleep game loop'); loop.sleep(); });
120 | loopFolder.addButton({ title: 'Wake' }).on('click', () => { console.info('Wake game loop'); loop.wake(); });
121 | loopFolder.addButton({ title: 'Step' }).on('click', () => { const t = performance.now(); console.info('step', t); loop.step(t); });
122 |
123 | const registryFolder = folder.addFolder({ title: 'Registry', expanded: false });
124 | registryFolder.addButton({ title: 'Print registry values' }).on('click', () => { console.info('Registry:'); console.table(registry.getAll()); });
125 |
126 | const rendererFolder = folder.addFolder({ title: 'Renderer', expanded: false });
127 | if (renderer.type === Phaser.CANVAS) {
128 | rendererFolder.addInput(renderer, 'antialias');
129 | rendererFolder.addMonitor(renderer, 'drawCount', { view: 'graph', min: 0, max: 100 });
130 | }
131 | rendererFolder.addButton({ title: 'Snapshot' }).on('click', () => {
132 | console.info('Snapshot');
133 | renderer.snapshot(snapshot);
134 | });
135 | rendererFolder.addButton({ title: 'Print config' }).on('click', () => { console.info('Renderer config:'); console.table(copyToSafeObj(renderer.config)); });
136 |
137 | const scaleFolder = folder.addFolder({ title: 'Scale', expanded: false });
138 | scaleFolder.addMonitor(scale, 'width');
139 | scaleFolder.addMonitor(scale, 'height');
140 | scaleFolder.addButton({ title: 'Start full screen' }).on('click', () => { console.info('Start fullscreen'); scale.startFullscreen(); });
141 | scaleFolder.addButton({ title: 'Stop full screen' }).on('click', () => { console.info('Stop fullscreen'); scale.stopFullscreen(); });
142 |
143 | const sceneFolder = folder.addFolder({ title: 'Scenes', expanded: false });
144 | sceneFolder.addButton({ title: 'Print scenes' }).on('click', () => { console.info('Scenes:'); console.table(scene.scenes.map(sceneToPrint)); });
145 | sceneFolder.addButton({ title: 'Add visible controls' }).on('click', () => { AddScenes(scene.getScenes(false), sceneFolder); });
146 |
147 | const soundFolder = folder.addFolder({ title: 'Sound', expanded: false });
148 | soundFolder.addInput(sound, 'mute');
149 | soundFolder.addInput(sound, 'pauseOnBlur');
150 | soundFolder.addMonitor(sound.sounds, 'length', { label: 'sounds.length', format: FormatLength });
151 | soundFolder.addInput(sound, 'volume', { min: 0, max: 1, step: 0.1 });
152 | soundFolder.addButton({ title: 'Pause all' }).on('click', () => { console.info('Pause all sounds'); sound.pauseAll(); });
153 | soundFolder.addButton({ title: 'Remove all' }).on('click', () => { console.info('Remove all sounds'); sound.removeAll(); });
154 | soundFolder.addButton({ title: 'Resume all' }).on('click', () => { console.info('Resume all sounds'); sound.resumeAll(); });
155 | soundFolder.addButton({ title: 'Stop all' }).on('click', () => { console.info('Stop all sounds'); sound.stopAll(); });
156 | soundFolder.addButton({ title: 'Print sounds' }).on('click', () => { console.info('Sounds:'); console.table(sound.sounds.map(soundToPrint)); });
157 |
158 | const texturesFolder = folder.addFolder({ title: 'Textures', expanded: false });
159 | texturesFolder.addButton({ title: 'Print textures' }).on('click', () => { console.info('Textures:'); console.table(Object.values(textures.list).map(textureToPrint)); });
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/src/InspectorScenePlugin.js:
--------------------------------------------------------------------------------
1 | import Phaser from 'phaser';
2 | import { GLOBAL_PLUGIN_KEY } from './const';
3 | import { AddActive, AddArcadePhysicsWorld, AddCamera, AddMatterPhysicsWorld, AddVisible, cameraToPrint, displayListItemToPrint, FormatLength, InspectByIndex, InspectByName, InspectByType, keyToPrint, lightToPrint, timerEventToPrint, tweenToPrint, updateListItemToPrint } from './util';
4 |
5 | const {
6 | CREATE,
7 | DESTROY,
8 | START
9 | } = Phaser.Scenes.Events;
10 |
11 | const {
12 | START: STATUS_START,
13 | SHUTDOWN: STATUS_SHUTDOWN
14 | } = Phaser.Scenes;
15 |
16 | export class InspectorScenePlugin extends Phaser.Plugins.ScenePlugin {
17 | constructor (scene, pluginManager) {
18 | super(scene, pluginManager);
19 |
20 | this.folder = null;
21 | this.pane = null;
22 | }
23 |
24 | boot () {
25 | this.pane = this.pluginManager.get(GLOBAL_PLUGIN_KEY).pane;
26 | this.folder = this.pane.addFolder({ title: `Scene “${this.systems.settings.key}”`, expanded: false });
27 |
28 | this.systems.events
29 | .on(DESTROY, this.sceneDestroy, this);
30 |
31 | this.add();
32 | }
33 |
34 | destroy () {
35 | this.folder.dispose();
36 | this.folder = null;
37 |
38 | this.systems.events
39 | .off(DESTROY, this.sceneDestroy, this);
40 |
41 | super.destroy();
42 | }
43 |
44 | sceneDestroy () {
45 | this.destroy();
46 | }
47 |
48 | add () {
49 | const { arcadePhysics, cameras, data, displayList, events, input, load, lights, matterPhysics, scenePlugin, time, tweens, updateList } = this.systems;
50 | const sceneKey = scenePlugin.settings.key;
51 | const sceneStatus = scenePlugin.settings.status;
52 |
53 | const camerasFolder = this.folder.addFolder({ title: 'Cameras', expanded: false });
54 | camerasFolder.addButton({ title: 'Print cameras' }).on('click', () => { console.info('Cameras:'); console.table(cameras.cameras.map(cameraToPrint)); });
55 |
56 | if (data) {
57 | const dataFolder = this.folder.addFolder({ title: 'Data', expanded: false });
58 | dataFolder.addButton({ title: 'Print data' }).on('click', () => { console.info('Data:'); console.table(data.getAll()); });
59 | }
60 |
61 | const displayListFolder = this.folder.addFolder({ title: 'Display List', expanded: false });
62 | displayListFolder.addMonitor(displayList, 'length', { format: FormatLength });
63 | displayListFolder.addButton({ title: 'Print' }).on('click', () => { console.info('Display list:'); console.table(displayList.getChildren().map(displayListItemToPrint)); });
64 | displayListFolder.addButton({ title: 'Save JSON' }).on('click', () => { load.saveJSON(displayList.getChildren(), `${sceneKey} displayList.json`); });
65 | displayListFolder.addButton({ title: 'Inspect by name …' }).on('click', () => { InspectByName(prompt('Inspect first game object on display list with name:'), displayList.getChildren(), this.pane); });
66 | displayListFolder.addButton({ title: 'Inspect by type …' }).on('click', () => { InspectByType(prompt('Inspect first game object on display list with type:'), displayList.getChildren(), this.pane); });
67 | displayListFolder.addButton({ title: 'Inspect by index …' }).on('click', () => { InspectByIndex(prompt(`Inspect game object on display list at index (0 to ${displayList.length - 1}):`), displayList.getChildren(), this.pane); });
68 | displayListFolder.addButton({ title: 'Add visible controls' }).on('click', () => { AddVisible(displayList.getChildren(), displayListFolder); });
69 |
70 | if (input) {
71 | const { gamepad, keyboard } = input;
72 | const inputFolder = this.folder.addFolder({ title: 'Input', expanded: false });
73 | inputFolder.addInput(input, 'dragDistanceThreshold', { min: 0, max: 32, step: 1 });
74 | inputFolder.addInput(input, 'dragTimeThreshold', { min: 0, max: 100, step: 10 });
75 | inputFolder.addInput(input, 'enabled');
76 | inputFolder.addMonitor(input, 'pollRate');
77 | inputFolder.addInput(input, 'topOnly');
78 | inputFolder.addMonitor(input, 'x');
79 | inputFolder.addMonitor(input, 'y');
80 | inputFolder.addButton({ title: 'Set poll always' }).on('click', () => { console.info('Poll always'); input.setPollAlways(); });
81 | inputFolder.addButton({ title: 'Set poll on move' }).on('click', () => { console.info('Poll on move'); input.setPollOnMove(); });
82 | inputFolder.addButton({ title: 'Print game objects' }).on('click', () => { console.info('Interactive game objects: '); console.table(input._list.map(displayListItemToPrint)); });
83 |
84 | if (gamepad) {
85 | const gamepadFolder = this.folder.addFolder({ title: 'Gamepads', expanded: false });
86 | gamepadFolder.addInput(gamepad, 'enabled');
87 | gamepadFolder.addMonitor(gamepad, 'total');
88 | }
89 |
90 | if (keyboard) {
91 | const keyboardFolder = this.folder.addFolder({ title: 'Keyboard', expanded: false });
92 | keyboardFolder.addInput(keyboard, 'enabled');
93 | keyboardFolder.addButton({ title: 'Clear captures' }).on('click', () => { console.info('Clear key captures'); keyboard.clearCaptures(); });
94 | keyboardFolder.addButton({ title: 'Remove all keys' }).on('click', () => { console.info('Remove all keys'); keyboard.removeAllKeys(); });
95 | keyboardFolder.addButton({ title: 'Reset keys' }).on('click', () => { console.info('Reset keys'); keyboard.resetKeys(); });
96 | keyboardFolder.addButton({ title: 'Print captures' }).on('click', () => { console.info('Key captures:'); console.table(keyboard.getCaptures()); });
97 | keyboardFolder.addButton({ title: 'Print keys' }).on('click', () => { console.info('Keys:'); console.table(keyboard.keys.map(keyToPrint)); });
98 | }
99 | }
100 |
101 | if (lights) {
102 | const lightsFolder = this.folder.addFolder({ title: 'Lights', expanded: false });
103 | lightsFolder.addInput(lights, 'active');
104 | lightsFolder.addInput(lights, 'ambientColor', { color: { type: 'float' } });
105 | lightsFolder.addMonitor(lights, 'visibleLights', { format: FormatLength });
106 | lightsFolder.addButton({ title: 'Print lights' }).on('click', () => { console.info('Lights:'); console.table(lights.lights.map(lightToPrint)); });
107 | }
108 |
109 | if (load) {
110 | const loadFolder = this.folder.addFolder({ title: 'Load', expanded: false });
111 | loadFolder.addMonitor(load, 'progress', { view: 'graph', min: 0, max: 1 });
112 | loadFolder.addMonitor(load, 'totalComplete');
113 | loadFolder.addMonitor(load, 'totalFailed');
114 | loadFolder.addMonitor(load, 'totalToLoad');
115 | }
116 |
117 | const scenePluginFolder = this.folder.addFolder({ title: 'Scene', expanded: false });
118 | scenePluginFolder.addMonitor(scenePlugin.settings, 'active');
119 | scenePluginFolder.addMonitor(scenePlugin.settings, 'visible');
120 | scenePluginFolder.addMonitor(scenePlugin.settings, 'status');
121 | scenePluginFolder.addButton({ title: 'Pause' }).on('click', () => { console.info('Pause scene', sceneKey); scenePlugin.pause(); });
122 | scenePluginFolder.addButton({ title: 'Resume' }).on('click', () => { console.info('Resume scene', sceneKey); scenePlugin.resume(); });
123 | scenePluginFolder.addButton({ title: 'Sleep' }).on('click', () => { console.info('Sleep scene', sceneKey); scenePlugin.sleep(); });
124 | scenePluginFolder.addButton({ title: 'Wake' }).on('click', () => { console.info('Wake scene', sceneKey); scenePlugin.wake(); });
125 | scenePluginFolder.addButton({ title: 'Stop' }).on('click', () => { console.info('Stop scene', sceneKey); scenePlugin.stop(); });
126 | scenePluginFolder.addButton({ title: 'Restart' }).on('click', () => { console.info('Restart scene', sceneKey); scenePlugin.restart(); });
127 | scenePluginFolder.addButton({ title: 'Remove' }).on('click', () => { console.info('Remove scene', sceneKey); scenePlugin.remove(); });
128 | scenePluginFolder.addButton({ title: 'Print scene data' }).on('click', () => { console.info(`Scene data for ${sceneKey}:`); console.table(scenePlugin.settings.data); });
129 |
130 | if (time) {
131 | const timeFolder = this.folder.addFolder({ title: 'Time', expanded: false });
132 | timeFolder.addMonitor(time._active, 'length', { label: 'events (length)', format: FormatLength });
133 | timeFolder.addMonitor(time, 'now');
134 | timeFolder.addInput(time, 'paused');
135 | timeFolder.addButton({ title: 'Print timer events' }).on('click', () => { console.info('Timer events:'); console.table(time._active.map(timerEventToPrint)); });
136 | }
137 |
138 | if (tweens) {
139 | const tweensFolder = this.folder.addFolder({ title: 'Tweens', expanded: false });
140 | tweensFolder.addInput(tweens, 'timeScale', { min: 0.1, max: 10, step: 0.1 });
141 | tweensFolder.addButton({ title: 'Pause all' }).on('click', () => { console.info('Pause all tweens'); tweens.pauseAll(); });
142 | tweensFolder.addButton({ title: 'Resume all' }).on('click', () => { console.info('Resume all tweens'); tweens.resumeAll(); });
143 | tweensFolder.addButton({ title: 'Stop all' }).on('click', () => { console.info('Stop all tweens'); tweens.killAll(); });
144 | tweensFolder.addButton({ title: 'Print tweens' }).on('click', () => { console.info('Tweens:'); console.table(tweens.getTweens().map(tweenToPrint)); });
145 | }
146 |
147 | const updateListFolder = this.folder.addFolder({ title: 'Update List', expanded: false });
148 | updateListFolder.addMonitor(updateList, 'length', { format: FormatLength });
149 | updateListFolder.addButton({ title: 'Print' }).on('click', () => { console.info('Update list:'); console.table(updateList.getActive().map(updateListItemToPrint)); });
150 | updateListFolder.addButton({ title: 'Save JSON' }).on('click', () => { load.saveJSON(updateList.getActive(), `${sceneKey} updateList.json`); });
151 | updateListFolder.addButton({ title: 'Inspect by name …' }).on('click', () => { InspectByName(prompt('Inspect first game object on update list with name:'), updateList.getActive(), this.pane); });
152 | updateListFolder.addButton({ title: 'Inspect by type …' }).on('click', () => { InspectByType(prompt('Inspect first game object on update list with type:'), updateList.getActive(), this.pane); });
153 | updateListFolder.addButton({ title: 'Inspect by index …' }).on('click', () => { InspectByIndex(prompt(`Inspect game object on update list at index (0 to ${updateList.length - 1}):`), updateList.getActive(), this.pane); });
154 | updateListFolder.addButton({ title: 'Add active controls' }).on('click', () => { AddActive(updateList.getActive(), updateListFolder); });
155 |
156 | events.on(CREATE, () => {
157 | for (const cam of cameras.cameras) { AddCamera(cam, camerasFolder); }
158 | });
159 |
160 | if (arcadePhysics) {
161 | if (sceneStatus < STATUS_START || sceneStatus === STATUS_SHUTDOWN) {
162 | events.on(START, () => { AddArcadePhysicsWorld(arcadePhysics.world, this.folder); });
163 | } else {
164 | AddArcadePhysicsWorld(arcadePhysics.world, this.folder);
165 | }
166 | }
167 |
168 | if (matterPhysics) {
169 | if (sceneStatus < STATUS_START || sceneStatus === STATUS_SHUTDOWN) {
170 | events.on(START, () => { AddMatterPhysicsWorld(matterPhysics.world, this.folder); });
171 | } else {
172 | AddMatterPhysicsWorld(matterPhysics.world, this.folder);
173 | }
174 | }
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/src/Install.js:
--------------------------------------------------------------------------------
1 | import { InspectorGlobalPlugin } from './InspectorGlobalPlugin';
2 | import { InspectorScenePlugin } from './InspectorScenePlugin';
3 | import {
4 | GLOBAL_PLUGIN_KEY,
5 | GLOBAL_PLUGIN_MAPPING,
6 | SCENE_PLUGIN_KEY,
7 | SCENE_PLUGIN_SCENE_MAPPING,
8 | SCENE_PLUGIN_SYS_MAPPING
9 | } from './const';
10 |
11 | export function Install (pluginsManager) {
12 | pluginsManager.install(GLOBAL_PLUGIN_KEY, InspectorGlobalPlugin, true, GLOBAL_PLUGIN_MAPPING);
13 | pluginsManager.installScenePlugin(SCENE_PLUGIN_KEY, InspectorScenePlugin, SCENE_PLUGIN_SCENE_MAPPING);
14 |
15 | for (const scene of pluginsManager.game.scene.scenes) {
16 | const plugin = new InspectorScenePlugin(scene, pluginsManager);
17 |
18 | scene[SCENE_PLUGIN_SCENE_MAPPING] = plugin;
19 | scene.sys[SCENE_PLUGIN_SYS_MAPPING] = plugin;
20 |
21 | plugin.boot();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/const.js:
--------------------------------------------------------------------------------
1 |
2 | export const GLOBAL_PLUGIN_KEY = 'InspectorGlobalPlugin';
3 | export const GLOBAL_PLUGIN_MAPPING = 'inspectorGame';
4 | export const SCENE_PLUGIN_KEY = 'InspectorScenePlugin';
5 | export const SCENE_PLUGIN_SCENE_MAPPING = 'inspectorScene';
6 | export const SCENE_PLUGIN_SYS_MAPPING = 'inspectorScene';
7 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | export { InspectorGlobalPlugin } from './InspectorGlobalPlugin';
2 | export { InspectorScenePlugin } from './InspectorScenePlugin';
3 | export { DefaultPluginsConfig } from './DefaultPluginsConfig';
4 | export { Install } from './Install';
5 | export {
6 | AddActive,
7 | AddAlpha,
8 | AddAnimationState,
9 | AddArcadeBody,
10 | AddArcadePhysicsWorld,
11 | AddCamera,
12 | AddChain,
13 | AddFXComponent,
14 | AddFXController,
15 | AddGameObject,
16 | AddGroup,
17 | AddInput,
18 | AddKey,
19 | AddKeys,
20 | AddLight,
21 | AddMatterPhysicsWorld,
22 | AddParticleEmitter,
23 | AddPipeline,
24 | AddPointer,
25 | AddScenes,
26 | AddSound,
27 | AddTimeline,
28 | AddTimerEvent,
29 | AddTween,
30 | AddVideo,
31 | AddVisible
32 | } from './util';
33 |
--------------------------------------------------------------------------------
/src/util.js:
--------------------------------------------------------------------------------
1 | import Phaser from 'phaser';
2 | import { FXMap } from './FXMap';
3 |
4 | const TAU = 2 * Math.PI;
5 | const CacheNames = ['audio', 'binary', 'bitmapFont', 'html', 'json', 'obj', 'physics', 'shader', 'text', 'tilemap', 'video', 'xml'];
6 | const CameraEvents = Phaser.Cameras.Scene2D.Events;
7 | const SceneEvents = Phaser.Scenes.Events;
8 | const GameObjectEvents = Phaser.GameObjects.Events;
9 | const { BlendModes } = Phaser;
10 | const { GetFirst } = Phaser.Utils.Array;
11 |
12 | export function animToPrint ({ key, delay, duration, frameRate, repeat, repeatDelay }) {
13 | return { key, delay, duration, frameRate, repeat, repeatDelay };
14 | }
15 |
16 | export function sceneToPrint (scene) {
17 | const { key, status, active, visible } = scene.sys.settings;
18 |
19 | return { key, status, active, visible };
20 | }
21 |
22 | export function soundToPrint ({ key, isPaused, isPlaying, seek, totalDuration, volume }) {
23 | return { key, isPaused, isPlaying, seek, totalDuration, volume };
24 | }
25 |
26 | export function textureToPrint ({ key, firstFrame, frameTotal }) {
27 | return { key, firstFrame, frameTotal };
28 | }
29 |
30 | export function copyToSafeObj (obj) {
31 | const out = {};
32 |
33 | for (const key in obj) {
34 | const val = obj[key];
35 | const typ = typeof val;
36 |
37 | if (!val || typ === 'boolean' || typ === 'number' || typ === 'string') {
38 | out[key] = val;
39 | }
40 | }
41 |
42 | return out;
43 | }
44 |
45 | export function copyToSafeTable (obj) {
46 | const out = {};
47 |
48 | for (const key in obj) {
49 | const val = obj[key];
50 |
51 | out[key] = typeof val === 'object' ? copyToSafeObj(obj[key]) : val;
52 | }
53 |
54 | return out;
55 | }
56 |
57 | export function printCaches (manager) {
58 | for (const name of CacheNames) {
59 | printCache(name, manager[name]);
60 | }
61 |
62 | for (const name in manager.custom) {
63 | printCache(name, manager.custom[name]);
64 | }
65 | }
66 |
67 | export function printCache (name, cache) {
68 | const { size } = cache.entries;
69 |
70 | if (size > 0) {
71 | console.info(`${name} cache (${size})`);
72 |
73 | console.table(copyToSafeTable(cache.entries.entries));
74 | } else {
75 | console.info(`${name} cache is empty`);
76 | }
77 | }
78 |
79 | export function printDevice (device) {
80 | for (const key in device) {
81 | console.info(key);
82 | console.table(copyToSafeObj(device[key]));
83 | }
84 | }
85 |
86 | export function snapshot (img) {
87 | img.style.width = '256px';
88 | img.style.height = 'auto';
89 | document.body.appendChild(img);
90 | }
91 |
92 | export function AddPointer (pointer, pane) {
93 | const folder = pane.addFolder({ title: `Pointer ${pointer.id}`, expanded: false });
94 |
95 | folder.addMonitor(pointer, 'active');
96 | folder.addMonitor(pointer, 'angle');
97 | folder.addMonitor(pointer, 'buttons');
98 | folder.addMonitor(pointer, 'deltaX');
99 | folder.addMonitor(pointer, 'deltaY');
100 | folder.addMonitor(pointer, 'deltaZ');
101 | folder.addMonitor(pointer, 'distance');
102 | folder.addMonitor(pointer, 'downX');
103 | folder.addMonitor(pointer, 'downY');
104 | folder.addMonitor(pointer, 'id');
105 | folder.addMonitor(pointer, 'isDown');
106 | folder.addMonitor(pointer, 'locked');
107 | folder.addMonitor(pointer, 'movementX');
108 | folder.addMonitor(pointer, 'movementY');
109 | folder.addMonitor(pointer, 'primaryDown');
110 | folder.addMonitor(pointer, 'upX');
111 | folder.addMonitor(pointer, 'upY');
112 | folder.addMonitor(pointer.velocity, 'x', { label: 'velocity x' });
113 | folder.addMonitor(pointer.velocity, 'y', { label: 'velocity y' });
114 | folder.addMonitor(pointer, 'worldX');
115 | folder.addMonitor(pointer, 'worldY');
116 | folder.addMonitor(pointer, 'x');
117 | folder.addMonitor(pointer, 'y');
118 |
119 | return folder;
120 | }
121 |
122 | export function AddSound (sound, pane) {
123 | const folder = pane.addFolder({ title: `Sound “${sound.key}”`, expanded: false });
124 |
125 | sound.once('destroy', () => { folder.dispose(); });
126 |
127 | if (sound.currentMarker) {
128 | folder.addMonitor(sound.currentMarker, 'name');
129 | }
130 |
131 | folder.addMonitor(sound, 'duration');
132 | folder.addMonitor(sound, 'isPaused');
133 | folder.addMonitor(sound, 'isPlaying');
134 | folder.addMonitor(sound, 'seek');
135 | folder.addMonitor(sound, 'totalDuration');
136 |
137 | folder.addMonitor(sound, 'loop');
138 | folder.addInput(sound, 'mute');
139 | folder.addInput(sound, 'volume', { min: 0, max: 1 });
140 |
141 | folder.addButton({ title: 'Play' }).on('click', () => { console.info('Play sound “%s”', sound.key); sound.play(); });
142 | folder.addButton({ title: 'Pause' }).on('click', () => { console.info('Pause sound “%s”', sound.key); sound.pause(); });
143 | folder.addButton({ title: 'Resume' }).on('click', () => { console.info('Resume sound “%s”', sound.key); sound.resume(); });
144 | folder.addButton({ title: 'Stop' }).on('click', () => { console.info('Stop sound “%s”', sound.key); sound.stop(); });
145 | folder.addButton({ title: 'Remove' }).on('click', () => { console.info('Remove sound “%s”', sound.key); sound.destroy(); });
146 |
147 | for (const name in sound.markers) {
148 | folder.addButton({ title: `Play “${name}”` }).on('click', () => { console.info('Play sound “%s” marker “%s”', sound.key, name); sound.play(name); });
149 | }
150 |
151 | return folder;
152 | }
153 |
154 | export function displayListItemToPrint ({ name, type, x, y, visible, depth }) {
155 | return { name, type, x, y, visible, depth };
156 | }
157 |
158 | export function updateListItemToPrint ({ name, type, active }) {
159 | return { name, type, active };
160 | }
161 |
162 | export function tweenToPrint ({ duration, elapsed, paused, progress, state, totalElapsed, totalProgress }) {
163 | return { duration, elapsed, paused, progress, state, totalElapsed, totalProgress };
164 | }
165 |
166 | export function timerEventToPrint ({ delay, elapsed, loop, paused, repeat, repeatCount }) {
167 | return { delay, elapsed, loop, paused, repeat, repeatCount };
168 | }
169 |
170 | export function keyToPrint ({ duration, emitOnRepeat, enabled, isDown, isUp, location, repeats, timeDown, timeUp }) {
171 | return { duration, emitOnRepeat, enabled, isDown, isUp, location, repeats, timeDown, timeUp };
172 | }
173 |
174 | export function cameraToPrint ({ name, id, x, y, width, height, visible, alpha }) {
175 | return { name, id, x, y, width, height, visible, alpha };
176 | }
177 |
178 | export function lightToPrint ({ x, y, radius, color, intensity, visible }) {
179 | return { x, y, radius, color: `rgb(${color.r.toFixed(2)}, ${color.g.toFixed(2)}, ${color.b.toFixed(2)})`, intensity, visible };
180 | }
181 |
182 | export function AddCamera (camera, pane) {
183 | const defaultCamera = camera.cameraManager.default;
184 | const w = defaultCamera.width;
185 | const h = defaultCamera.height;
186 | const folder = pane.addFolder({ title: `Camera ${camera.id} ${camera.name || ''}`, expanded: false });
187 |
188 | folder.addMonitor(camera, 'name');
189 | folder.addInput(camera, 'alpha', { min: 0, max: 1, step: 0.05 });
190 | folder.addInput(camera, 'backgroundColor');
191 | folder.addInput(camera, 'x', { min: -w, max: w, step: 10 });
192 | folder.addInput(camera, 'y', { min: -h, max: h, step: 10 });
193 | folder.addInput(camera, 'width', { min: 0, max: w, step: 10 });
194 | folder.addInput(camera, 'height', { min: 0, max: h, step: 10 });
195 | folder.addInput(camera, 'scrollX', { min: -w, max: w, step: 10 });
196 | folder.addInput(camera, 'scrollY', { min: -h, max: h, step: 10 });
197 | folder.addInput(camera, 'originX', { min: 0, max: 1, step: 0.05 });
198 | folder.addInput(camera, 'originY', { min: 0, max: 1, step: 0.05 });
199 | folder.addInput(camera, 'rotation', { min: 0, max: TAU });
200 | folder.addInput(camera, 'zoom', { min: 0.1, max: 10, step: 0.05 });
201 | folder.addInput(camera, 'followOffset');
202 | folder.addInput(camera, 'disableCull');
203 | folder.addInput(camera, 'inputEnabled');
204 | folder.addInput(camera, 'roundPixels');
205 | folder.addInput(camera, 'useBounds');
206 | folder.addInput(camera, 'visible');
207 | folder.addMonitor(camera, 'centerX');
208 | folder.addMonitor(camera, 'centerY');
209 | folder.addMonitor(camera.midPoint, 'x', { label: 'midPoint x' });
210 | folder.addMonitor(camera.midPoint, 'y', { label: 'midPoint y' });
211 | folder.addMonitor(camera.worldView, 'x', { label: 'world x' });
212 | folder.addMonitor(camera.worldView, 'y', { label: 'world y' });
213 | folder.addMonitor(camera.worldView, 'width', { label: 'world width' });
214 | folder.addMonitor(camera.worldView, 'height', { label: 'world height' });
215 |
216 | // TODO
217 | const { deadzone } = camera;
218 | if (deadzone) {
219 | folder.addMonitor(deadzone, 'x', { label: 'deadzone x' });
220 | folder.addMonitor(deadzone, 'y', { label: 'deadzone y' });
221 | folder.addMonitor(deadzone, 'width', { label: 'deadzone width' });
222 | folder.addMonitor(deadzone, 'height', { label: 'deadzone height' });
223 | }
224 |
225 | if (camera.hasPostPipeline) {
226 | AddPipelines(camera.postPipelines, folder, { title: 'Post Pipelines' });
227 | }
228 |
229 | folder.addButton({ title: 'Fade in' }).on('click', () => { camera.fadeIn(); });
230 | folder.addButton({ title: 'Fade out' }).on('click', () => { camera.fadeOut(); });
231 | folder.addButton({ title: 'Flash' }).on('click', () => { camera.flash(); });
232 | folder.addButton({ title: 'Shake' }).on('click', () => { camera.shake(); });
233 | folder.addButton({ title: 'Reset effects' }).on('click', () => { camera.resetFX(); });
234 | folder.addButton({ title: 'Reset post pipeline' }).on('click', () => { camera.resetPostPipeline(); });
235 |
236 | camera.on(CameraEvents.DESTROY, () => {
237 | folder.dispose();
238 | });
239 |
240 | return folder;
241 | }
242 |
243 | export function AddArcadePhysicsWorld (world, pane) {
244 | const { arcadePhysics, events } = world.scene.sys;
245 | const folder = pane.addFolder({ title: 'Arcade Physics', expanded: false });
246 |
247 | folder.addMonitor(world.bodies, 'size', { label: 'bodies.size' });
248 | folder.addInput(world, 'fixedStep');
249 | folder.addInput(world, 'forceX');
250 | folder.addInput(world, 'fps', { min: 5, max: 300, step: 5 }).on('change', ({ value }) => { world.setFPS(value); });
251 | folder.addMonitor(world, '_frameTimeMS');
252 | folder.addInput(world, 'gravity', { x: { min: -1000, max: 1000 }, y: { min: -1000, max: 1000 } });
253 | folder.addInput(world, 'isPaused');
254 | folder.addInput(world, 'OVERLAP_BIAS', { label: 'OVERLAP_BIAS', min: 0, max: 32, step: 1 });
255 | folder.addMonitor(world.staticBodies, 'size', { label: 'staticBodies.size' });
256 | folder.addInput(world, 'TILE_BIAS', { label: 'TILE_BIAS', min: 0, max: 32, step: 1 });
257 | folder.addInput(world, 'timeScale', { min: 0.1, max: 10, step: 0.1 });
258 | folder.addInput(world, 'useTree');
259 | if (world.debugGraphic) {
260 | folder.addInput(world.debugGraphic, 'visible', { label: 'debugGraphic.visible' });
261 | }
262 | folder.addButton({ title: 'Enable update' }).on('click', () => { arcadePhysics.enableUpdate(); });
263 | folder.addButton({ title: 'Disable update' }).on('click', () => { arcadePhysics.disableUpdate(); });
264 | folder.addButton({ title: 'Update' }).on('click', () => { world.update(0, world._frameTimeMS || (1000 / 60)); });
265 | folder.addButton({ title: 'Print colliders' }).on('click', () => { console.info('Colliders', world.colliders.getActive()); });
266 |
267 | events.once(SceneEvents.SHUTDOWN, () => {
268 | folder.dispose();
269 | });
270 |
271 | return folder;
272 | }
273 |
274 | export function AddMatterPhysicsWorld (world, pane) {
275 | const { events } = world.scene.sys;
276 | const folder = pane.addFolder({ title: 'Matter Physics', expanded: false });
277 | folder.addInput(world, 'autoUpdate');
278 | folder.addInput(world, 'enabled');
279 | folder.addInput(world.localWorld, 'gravity');
280 | folder.addInput(world.localWorld.gravity, 'scale', { label: 'gravity scale', min: 0, max: 0.1, step: 0.001 });
281 | if (world.debugGraphic) {
282 | folder.addInput(world.debugGraphic, 'visible', { label: 'debugGraphic.visible' });
283 | }
284 | folder.addButton({ title: 'Pause' }).on('click', () => { world.pause(); });
285 | folder.addButton({ title: 'Resume' }).on('click', () => { world.resume(); });
286 | folder.addButton({ title: 'Step' }).on('click', () => { world.step(); });
287 |
288 | events.once(SceneEvents.SHUTDOWN, () => {
289 | folder.dispose();
290 | });
291 |
292 | return folder;
293 | }
294 |
295 | export function AddGameObject (obj, pane, options = { title: `${obj.type} “${obj.name}”` }) {
296 | const folder = pane.addFolder(options);
297 |
298 | folder.addInput(obj, 'active');
299 | folder.addMonitor(obj, 'cameraFilter');
300 | folder.addMonitor(obj, 'state');
301 |
302 | if ('texture' in obj && obj.texture && obj.texture.key) {
303 | const proxy = {
304 | get 'texture.key' () { return obj.texture.key; },
305 | get 'frame.name' () { return obj.frame.name; }
306 | };
307 |
308 | folder.addMonitor(proxy, 'texture.key');
309 | folder.addMonitor(proxy, 'frame.name', { format: String });
310 | }
311 |
312 | if ('displayTexture' in obj) {
313 | const proxy = {
314 | get 'displayTexture.key' () { return obj.displayTexture.key; },
315 | get 'displayFrame.name' () { return obj.displayFrame.name; }
316 | };
317 |
318 | folder.addMonitor(proxy, 'displayTexture.key');
319 | folder.addMonitor(proxy, 'displayFrame.name', { format: String });
320 | }
321 |
322 | if ('alpha' in obj) {
323 | folder.addInput(obj, 'alpha', { min: 0, max: 1, step: 0.05 });
324 | }
325 |
326 | if ('blendMode' in obj) {
327 | folder.addInput(obj, 'blendMode', { options: BlendModes });
328 | }
329 |
330 | if ('depth' in obj) {
331 | folder.addMonitor(obj, 'depth');
332 | }
333 |
334 | if ('width' in obj) {
335 | folder.addMonitor(obj, 'width');
336 | folder.addMonitor(obj, 'height');
337 | }
338 |
339 | if ('displayWidth' in obj) {
340 | folder.addMonitor(obj, 'displayWidth');
341 | folder.addMonitor(obj, 'displayHeight');
342 | }
343 |
344 | if ('originX' in obj) {
345 | folder.addMonitor(obj, 'originX');
346 | folder.addMonitor(obj, 'originY');
347 | }
348 |
349 | if ('displayOriginX' in obj) {
350 | folder.addMonitor(obj, 'displayOriginX');
351 | folder.addMonitor(obj, 'displayOriginY');
352 | }
353 |
354 | if ('scaleX' in obj) {
355 | folder.addMonitor(obj, 'scaleX');
356 | folder.addMonitor(obj, 'scaleY');
357 | folder.addInput(obj, 'scale', { min: 0.1, max: 10, step: 0.1 });
358 | }
359 |
360 | if ('flipX' in obj) {
361 | folder.addInput(obj, 'flipX');
362 | folder.addInput(obj, 'flipY');
363 | }
364 |
365 | if ('angle' in obj) {
366 | folder.addMonitor(obj, 'angle');
367 | }
368 |
369 | if ('rotation' in obj) {
370 | folder.addInput(obj, 'rotation', { min: 0, max: TAU, step: 0.01 * TAU });
371 | }
372 |
373 | if ('visible' in obj) {
374 | folder.addInput(obj, 'visible');
375 | }
376 |
377 | if ('x' in obj) {
378 | folder.addMonitor(obj, 'x');
379 | folder.addMonitor(obj, 'y');
380 | folder.addMonitor(obj, 'z');
381 | folder.addMonitor(obj, 'w');
382 | }
383 |
384 | if ('modelPosition' in obj) {
385 | folder.addInput(obj, 'modelPosition');
386 | folder.addInput(obj, 'modelScale');
387 | folder.addInput(obj, 'modelRotation');
388 | }
389 |
390 | if ('fov' in obj) {
391 | folder.addMonitor(obj, 'fov');
392 | }
393 |
394 | if ('faces' in obj && 'length' in obj.faces) {
395 | folder.addMonitor(obj.faces, 'length', { label: 'faces.length', format: FormatLength });
396 | }
397 |
398 | if ('vertices' in obj && 'length' in obj.vertices) {
399 | folder.addMonitor(obj.vertices, 'length', { label: 'vertices.length', format: FormatLength });
400 | }
401 |
402 | if ('totalRendered' in obj) {
403 | folder.addMonitor(obj, 'totalRendered', { format: FormatLength });
404 | }
405 |
406 | if ('tilesDrawn' in obj) {
407 | folder.addMonitor(obj, 'tilesDrawn', { format: FormatLength });
408 | }
409 |
410 | if ('tilesTotal' in obj) {
411 | folder.addMonitor(obj, 'tilesTotal', { format: FormatLength });
412 | }
413 |
414 | if (obj.pipeline) {
415 | // WebGL only
416 |
417 | if ('getPipelineName' in obj) {
418 | const proxy = { get 'getPipelineName()' () { return obj.getPipelineName(); } };
419 |
420 | folder.addMonitor(proxy, 'getPipelineName()', { label: 'getPipelineName()' });
421 | }
422 |
423 | if ('hasPostPipeline' in obj) {
424 | folder.addMonitor(obj, 'hasPostPipeline');
425 |
426 | if (obj.hasPostPipeline) {
427 | AddPipelines(obj.postPipelines, folder, { title: 'Post Pipelines' });
428 | }
429 | }
430 |
431 | if ('resetPipeline' in obj) {
432 | folder.addButton({ title: 'Reset pipeline' }).on('click', () => { console.info('Reset pipeline', obj.type, obj.name); obj.resetPipeline(); });
433 | }
434 |
435 | if ('resetPostPipeline' in obj) {
436 | folder.addButton({ title: 'Reset post pipeline' }).on('click', () => { console.info('Reset post pipeline', obj.type, obj.name); obj.resetPostPipeline(); });
437 | }
438 | }
439 |
440 | if ('preFX' in obj && obj.preFX && obj.preFX.list.length > 0) {
441 | AddFXComponent(obj.preFX, folder);
442 | }
443 |
444 | // The `postFX` controller doesn't seem to show any relevant state.
445 |
446 | if ('children' in obj && 'length' in obj.children) {
447 | folder.addMonitor(obj.children, 'length', { label: 'children.length', format: FormatLength });
448 | }
449 |
450 | if ('displayList' in obj) {
451 | const { displayList } = obj;
452 |
453 | folder.addButton({ title: 'Bring to top' }).on('click', () => { console.info('Bring to top', obj.type, obj.name); displayList.bringToTop(obj); });
454 | folder.addButton({ title: 'Move down' }).on('click', () => { console.info('Move down', obj.type, obj.name); displayList.moveDown(obj); });
455 | folder.addButton({ title: 'Move to …' }).on('click', () => { const idx = prompt(`Move to index (0 to ${displayList.length - 1}):`); if (!idx) { return; } console.info('Move to index', idx, obj.type, obj.name); displayList.moveTo(obj, idx); });
456 | folder.addButton({ title: 'Move up' }).on('click', () => { console.info('Move up', obj.type, obj.name); displayList.moveUp(obj); });
457 | folder.addButton({ title: 'Send to back' }).on('click', () => { console.info('Send to back', obj.type, obj.name); displayList.sendToBack(obj); });
458 | }
459 |
460 | folder.addButton({ title: 'Destroy' }).on('click', () => { console.info('Destroy', obj.type, obj.name); obj.destroy(); });
461 |
462 | obj.once(GameObjectEvents.DESTROY, () => { folder.dispose(); });
463 |
464 | return folder;
465 | }
466 |
467 | export function AddGroup (group, pane, options = { title: `${group.type} “${group.name}”` }) {
468 | const folder = pane.addFolder(options);
469 | const graphOptions = { view: 'graph', min: 0, max: group.maxSize === -1 ? 100 : group.maxSize };
470 |
471 | folder.addMonitor(group.getChildren(), 'length', graphOptions);
472 |
473 | const proxy = {
474 | get active () { return group.countActive(true); },
475 | get inactive () { return group.countActive(false); },
476 | get free () { return group.getTotalFree(); },
477 | get full () { return group.isFull(); }
478 | };
479 |
480 | folder.addMonitor(proxy, 'active', graphOptions);
481 | folder.addMonitor(proxy, 'inactive', graphOptions);
482 | if (group.maxSize > -1) { folder.addMonitor(proxy, 'free', graphOptions); }
483 | folder.addMonitor(group, 'maxSize');
484 | folder.addMonitor(proxy, 'full');
485 |
486 | folder.addButton({ title: 'Clear' }).on('click', () => { console.info('Clear group', group.name); group.clear(); });
487 | folder.addButton({ title: 'Destroy' }).on('click', () => { console.info('Destroy group', group.name); group.destroy(); });
488 | folder.addButton({ title: 'Destroy group members' }).on('click', () => { console.info('Destroy group members', group.name); group.clear(true, true); });
489 |
490 | group.once(GameObjectEvents.DESTROY, () => { folder.dispose(); });
491 |
492 | return folder;
493 | }
494 |
495 | export function AddLight (light, pane, options = { title: 'Light' }) {
496 | const folder = pane.addFolder(options);
497 |
498 | folder.addInput(light, 'color', { color: { type: 'float' } });
499 | folder.addInput(light, 'intensity', { min: 0, max: 10, step: 0.1 });
500 | folder.addInput(light, 'radius', { min: 0, max: 1024, step: 8 });
501 | folder.addInput(light, 'visible');
502 | folder.addMonitor(light, 'x');
503 | folder.addMonitor(light, 'y');
504 |
505 | return folder;
506 | }
507 |
508 | export function AddParticleEmitter (emitter, pane, options = { title: `Particle Emitter “${emitter.name}”` }) {
509 | const folder = pane.addFolder(options);
510 |
511 | const max = emitter.maxParticles || 100;
512 |
513 | const proxy = {
514 | get 'atLimit()' () { return emitter.atLimit(); },
515 | get 'getParticleCount()' () { return emitter.getParticleCount(); }
516 | };
517 |
518 | folder.addMonitor(emitter, 'active');
519 | folder.addMonitor(emitter, 'animQuantity');
520 | folder.addMonitor(proxy, 'atLimit()');
521 | folder.addMonitor(emitter, 'delay');
522 | folder.addMonitor(emitter, 'duration');
523 | folder.addMonitor(emitter, 'emitting');
524 | folder.addMonitor(emitter, 'frameQuantity');
525 | folder.addMonitor(emitter, 'maxAliveParticles');
526 | folder.addMonitor(emitter, 'maxParticles');
527 | folder.addMonitor(emitter, 'quantity');
528 | folder.addMonitor(emitter, 'stopAfter');
529 |
530 | folder.addInput(emitter, 'blendMode', { options: BlendModes });
531 | folder.addInput(emitter, 'frequency', { min: -1, max: 1000 });
532 | folder.addInput(emitter, 'moveTo');
533 | folder.addInput(emitter, 'particleBringToTop');
534 | folder.addInput(emitter, 'radial');
535 | folder.addInput(emitter, 'randomFrame');
536 | folder.addInput(emitter, 'timeScale', { min: 0.1, max: 10, step: 0.1 });
537 | folder.addInput(emitter, 'visible');
538 |
539 | const opsFolder = folder.addFolder({ title: 'Ops', expanded: false });
540 |
541 | for (const op of Object.values(emitter.ops)) {
542 | const { propertyKey, start, end, current, method } = op;
543 | const opFolder = opsFolder.addFolder({ title: propertyKey, expanded: false });
544 |
545 | if (typeof current === 'number') {
546 | if (method === 1) {
547 | opFolder.addInput(op, 'current');
548 | } else {
549 | opFolder.addMonitor(op, 'current');
550 | }
551 | }
552 |
553 | if (method === 4 || method === 5 || method === 6) {
554 | opFolder.addInput(op, 'start');
555 | opFolder.addInput(op, 'end');
556 | }
557 |
558 | if (method === 4) {
559 | opFolder.addInput(op, 'steps', { step: 1 });
560 | opFolder.addInput(op, 'yoyo');
561 | opFolder.addInput(op, 'direction', { min: 0, max: 1, step: 1 });
562 | opFolder.addMonitor(op, 'counter', { min: start, max: end, view: 'graph' });
563 | }
564 | }
565 |
566 | const graphsFolder = folder.addFolder({ title: 'Counters', expanded: false });
567 |
568 | graphsFolder.addMonitor(emitter.alive, 'length', { view: 'graph', min: 0, max: max, label: 'getAliveParticleCount()', format: FormatLength });
569 | graphsFolder.addMonitor(emitter.dead, 'length', { view: 'graph', min: 0, max: max, label: 'getDeadParticleCount()', format: FormatLength });
570 | graphsFolder.addMonitor(proxy, 'getParticleCount()', { view: 'graph', min: 0, max: max, format: FormatLength });
571 |
572 | if (emitter.frequency > 0) {
573 | graphsFolder.addMonitor(emitter, 'flowCounter', { view: 'graph', min: 0, max: emitter.frequency });
574 | }
575 |
576 | if (emitter.frameQuantity > 1) {
577 | graphsFolder.addMonitor(emitter, 'frameCounter', { view: 'graph', min: 0, max: emitter.frameQuantity });
578 | }
579 |
580 | if (emitter.animQuantity > 1) {
581 | graphsFolder.addMonitor(emitter, 'animCounter', { view: 'graph', min: 0, max: emitter.animQuantity });
582 | }
583 |
584 | if (emitter.duration > 0) {
585 | graphsFolder.addMonitor(emitter, 'elapsed', { view: 'graph', min: 0, max: emitter.duration });
586 | }
587 |
588 | if (emitter.stopAfter > 0) {
589 | graphsFolder.addMonitor(emitter, 'stopCounter', { view: 'graph', min: 0, max: emitter.stopAfter });
590 | }
591 |
592 | if (emitter.emitZones.length > 1) {
593 | graphsFolder.addMonitor(emitter, 'zoneIndex', { view: 'graph', min: 0, max: emitter.emitZones.length });
594 | }
595 |
596 | if (emitter.frames.length > 1) {
597 | graphsFolder.addMonitor(emitter, 'currentFrame', { view: 'graph', min: 0, max: emitter.frames.length });
598 | }
599 |
600 | if (emitter.anims.length > 1) {
601 | graphsFolder.addMonitor(emitter, 'currentAnim', { view: 'graph', min: 0, max: emitter.anims.length });
602 | }
603 |
604 | const { processors } = emitter;
605 |
606 | if (processors.length > 0) {
607 | const processorsFolder = folder.addFolder({ title: 'Processors' });
608 |
609 | for (const processor of processors.list) {
610 | processorsFolder.addInput(processor, 'active', { label: `${processor.name || 'Processor'} active` });
611 | }
612 | }
613 |
614 | folder.addButton({ title: 'Start' }).on('click', () => { emitter.start(); });
615 | folder.addButton({ title: 'Stop' }).on('click', () => { emitter.stop(); });
616 | folder.addButton({ title: 'Pause' }).on('click', () => { emitter.pause(); });
617 | folder.addButton({ title: 'Resume' }).on('click', () => { emitter.resume(); });
618 | folder.addButton({ title: 'Kill all' }).on('click', () => { emitter.killAll(); });
619 | folder.addButton({ title: 'Print JSON' }).on('click', () => { console.log(JSON.stringify(emitter.toJSON())); });
620 |
621 | emitter.once(GameObjectEvents.DESTROY, () => { folder.dispose(); });
622 |
623 | return folder;
624 | }
625 |
626 | export function AddVideo (video, pane, options = { title: `Video “${video.name}”` }) {
627 | const folder = pane.addFolder(options);
628 |
629 | const videoProxy = {
630 | get 'getCurrentTime()' () { return video.getCurrentTime(); },
631 | get 'getDuration()' () { return video.getDuration(); },
632 | get 'getLoop()' () { return video.getLoop(); },
633 | get 'getPlaybackRate()' () { return video.getPlaybackRate(); },
634 | get 'getProgress()' () { return video.getProgress(); },
635 | get 'getVolume()' () { return video.getVolume(); },
636 | get 'isMuted()' () { return video.isMuted(); },
637 | get 'isPaused()' () { return video.isPaused(); },
638 | get 'isPlaying()' () { return video.isPlaying(); },
639 |
640 | get 'seekTo()' () { return video.getProgress(); },
641 | set 'seekTo()' (v) { video.seekTo(v); },
642 | get 'setPlaybackRate()' () { return video.getPlaybackRate(); },
643 | set 'setPlaybackRate()' (v) { video.setPlaybackRate(v); },
644 | get 'setVolume()' () { return video.getVolume(); },
645 | set 'setVolume()' (v) { video.setVolume(v); }
646 | };
647 |
648 | folder.addMonitor(video, 'failedPlayAttempts');
649 | folder.addMonitor(video, 'frameReady');
650 | folder.addMonitor(videoProxy, 'getCurrentTime()');
651 | folder.addMonitor(videoProxy, 'getDuration()');
652 | folder.addMonitor(videoProxy, 'getLoop()');
653 | folder.addMonitor(videoProxy, 'getPlaybackRate()');
654 | folder.addMonitor(videoProxy, 'getProgress()');
655 | folder.addMonitor(videoProxy, 'getVolume()');
656 | folder.addMonitor(videoProxy, 'isMuted()');
657 | folder.addMonitor(videoProxy, 'isPaused()');
658 | folder.addMonitor(videoProxy, 'isPlaying()');
659 | folder.addMonitor(video, 'isSeeking');
660 | folder.addMonitor(video, 'isStalled');
661 | folder.addMonitor(video, 'retry');
662 | folder.addInput(videoProxy, 'seekTo()', { min: 0, max: 1 });
663 | folder.addInput(videoProxy, 'setPlaybackRate()', { min: 0.25, max: 4, step: 0.25 });
664 | folder.addInput(videoProxy, 'setVolume()', { min: 0, max: 1 });
665 | folder.addMonitor(video, 'touchLocked');
666 |
667 | folder.addButton({ title: 'Play' }).on('click', () => { console.info('Play video'); video.play(); });
668 | folder.addButton({ title: 'Stop' }).on('click', () => { console.info('Stop video'); video.stop(); });
669 | folder.addButton({ title: 'Pause' }).on('click', () => { console.info('Pause video'); video.pause(); });
670 | folder.addButton({ title: 'Resume' }).on('click', () => { console.info('Resume video'); video.resume(); });
671 |
672 | folder.addButton({ title: 'Change source …' }).on('click', () => { const src = prompt(`Change source (from '${video.cacheKey}')`); if (src) video.changeSource(src); });
673 | folder.addButton({ title: 'Set current time …' }).on('click', () => { video.setCurrentTime(prompt(`Set current time (0 to ${video.getDuration()})`)); });
674 | folder.addButton({ title: 'Set loop true' }).on('click', () => { video.setLoop(true); });
675 | folder.addButton({ title: 'Set loop false' }).on('click', () => { video.setLoop(false); });
676 | folder.addButton({ title: 'Set mute true' }).on('click', () => { video.setMute(true); });
677 | folder.addButton({ title: 'Set mute false' }).on('click', () => { video.setMute(false); });
678 |
679 | video.once(GameObjectEvents.DESTROY, () => { folder.dispose(); });
680 |
681 | return folder;
682 | }
683 |
684 | export function AddTween (tween, pane, options = { title: 'Tween' }) {
685 | const folder = pane.addFolder(options);
686 |
687 | // > When creating a Tween, you can no longer pass a function for the following properties:
688 | // > duration, hold, repeat and repeatDelay.
689 | // > These should be numbers only. You can, however, still provide a function for delay, to keep it compatible with the StaggerBuilder.
690 |
691 | folder.addMonitor(tween, 'countdown');
692 | folder.addMonitor(tween, 'duration');
693 | folder.addMonitor(tween, 'elapsed');
694 | folder.addMonitor(tween, 'loop');
695 | folder.addMonitor(tween, 'loopCounter');
696 | folder.addMonitor(tween, 'state');
697 | folder.addInput(tween, 'timeScale', { min: 0.1, max: 10, step: 0.1 });
698 | folder.addMonitor(tween, 'totalData');
699 | folder.addMonitor(tween, 'totalDuration');
700 | folder.addMonitor(tween, 'totalElapsed');
701 | folder.addMonitor(tween, 'totalProgress', { view: 'graph', min: 0, max: 1 });
702 |
703 | for (const dat of tween.data) {
704 | folder.addMonitor(dat, 'progress', { view: 'graph', min: 0, max: 1, label: `${dat.key} progress` });
705 | }
706 |
707 | for (const dat of tween.data) {
708 | folder.addMonitor(dat, 'current', { label: `${dat.key} current` });
709 | }
710 |
711 | folder.addButton({ title: 'Play' }).on('click', () => { console.info('Play tween'); tween.play(); });
712 | folder.addButton({ title: 'Pause' }).on('click', () => { console.info('Pause tween'); tween.pause(); });
713 | folder.addButton({ title: 'Resume' }).on('click', () => { console.info('Resume tween'); tween.resume(); });
714 | folder.addButton({ title: 'Stop' }).on('click', () => { console.info('Stop tween'); tween.stop(); });
715 | folder.addButton({ title: 'Restart' }).on('click', () => { console.info('Restart tween'); tween.restart(); });
716 | folder.addButton({ title: 'Remove' }).on('click', () => { console.info('Remove tween'); tween.remove(); });
717 |
718 | return folder;
719 | }
720 |
721 | export function AddChain (chain, pane, options = { title: 'Tween Chain' }) {
722 | const folder = pane.addFolder(options);
723 |
724 | folder.addMonitor(chain, 'currentIndex', { min: 0, max: chain.totalData, view: 'graph' });
725 | folder.addMonitor(chain, 'hasStarted');
726 | folder.addMonitor(chain, 'loop');
727 | folder.addMonitor(chain, 'loopCounter');
728 | folder.addMonitor(chain, 'state');
729 | folder.addInput(chain, 'timeScale', { min: 0.1, max: 10, step: 0.1 });
730 | folder.addMonitor(chain, 'totalData');
731 |
732 | folder.addButton({ title: 'Play' }).on('click', () => { console.info('Play chain'); chain.play(); });
733 | folder.addButton({ title: 'Stop' }).on('click', () => { console.info('Stop chain'); chain.stop(); });
734 | folder.addButton({ title: 'Restart' }).on('click', () => { console.info('Restart chain'); chain.restart(); });
735 | folder.addButton({ title: 'Pause' }).on('click', () => { console.info('Pause chain'); chain.pause(); });
736 | folder.addButton({ title: 'Resume' }).on('click', () => { console.info('Resume chain'); chain.resume(); });
737 | folder.addButton({ title: 'Destroy' }).on('click', () => { console.info('Destroy chain'); chain.destroy(); });
738 |
739 | return folder;
740 | }
741 |
742 | export function AddTimeline (timeline, pane, options = { title: 'Timeline' }) {
743 | const folder = pane.addFolder(options);
744 | const proxy = {
745 | get 'getProgress()' () { return timeline.getProgress(); },
746 | get 'isPlaying()' () { return timeline.isPlaying(); }
747 | };
748 |
749 | folder.addMonitor(timeline, 'complete');
750 | folder.addMonitor(timeline, 'elapsed');
751 | folder.addMonitor(proxy, 'getProgress()', { min: 0, max: 1, view: 'graph' });
752 | folder.addMonitor(proxy, 'isPlaying()');
753 | folder.addMonitor(timeline, 'paused');
754 | folder.addMonitor(timeline, 'totalComplete');
755 |
756 | folder.addButton({ title: 'Clear' }).on('click', () => { console.info('Clear timeline'); timeline.clear(); });
757 | folder.addButton({ title: 'Destroy' }).on('click', () => { console.info('Destroy timeline'); timeline.destroy(); });
758 | folder.addButton({ title: 'Pause' }).on('click', () => { console.info('Pause timeline'); timeline.pause(); });
759 | folder.addButton({ title: 'Play' }).on('click', () => { console.info('Play timeline'); timeline.play(); });
760 | folder.addButton({ title: 'Reset' }).on('click', () => { console.info('Reset timeline'); timeline.reset(); });
761 | folder.addButton({ title: 'Resume' }).on('click', () => { console.info('Resume timeline'); timeline.resume(); });
762 | folder.addButton({ title: 'Stop' }).on('click', () => { console.info('Stop timeline'); timeline.stop(); });
763 |
764 | return folder;
765 | }
766 |
767 | export function AddTimerEvent (timer, pane, options = { title: 'Timer Event' }) {
768 | const folder = pane.addFolder(options);
769 | const proxy = {
770 | get 'getOverallProgress()' () { return timer.getOverallProgress(); },
771 | get 'getProgress()' () { return timer.getProgress(); },
772 | get 'getOverallRemaining()' () { return timer.getOverallRemaining(); },
773 | get 'getRemaining()' () { return timer.getRemaining(); }
774 | };
775 | folder.addMonitor(timer, 'elapsed');
776 | folder.addMonitor(timer, 'hasDispatched');
777 | folder.addMonitor(proxy, 'getOverallProgress()', { min: 0, max: 1, view: 'graph' });
778 | folder.addMonitor(proxy, 'getProgress()', { min: 0, max: 1, view: 'graph' });
779 | folder.addMonitor(proxy, 'getOverallRemaining()');
780 | folder.addMonitor(proxy, 'getRemaining()');
781 | folder.addMonitor(timer, 'loop');
782 | folder.addMonitor(timer, 'paused');
783 | folder.addInput(timer, 'paused');
784 | folder.addMonitor(timer, 'repeat');
785 | folder.addMonitor(timer, 'repeatCount');
786 |
787 | folder.addButton({ title: 'Dispatch and remove' }).on('click', () => { console.info('Dispatch and remove timer'); timer.remove(true); });
788 | folder.addButton({ title: 'Remove' }).on('click', () => { console.info('Remove timer'); timer.remove(); });
789 | folder.addButton({ title: 'Reset with current config' }).on('click', () => { console.info('Reset timer with current config', timer); timer.reset(timer); });
790 |
791 | return folder;
792 | }
793 |
794 | export function AddInput (input, pane, options = { title: `Input (${input.gameObject.type} “${input.gameObject.name}”)` }) {
795 | const folder = pane.addFolder(options);
796 | const { gameObject } = input;
797 | const inputPlugin = gameObject.scene.sys.input;
798 |
799 | folder.addMonitor(input, 'cursor');
800 | folder.addMonitor(input, 'customHitArea');
801 | folder.addMonitor(input, 'draggable');
802 | folder.addMonitor(input, 'dragStartX');
803 | folder.addMonitor(input, 'dragStartXGlobal');
804 | folder.addMonitor(input, 'dragStartY');
805 | folder.addMonitor(input, 'dragStartYGlobal');
806 | folder.addMonitor(input, 'dragState');
807 | folder.addMonitor(input, 'dragX');
808 | folder.addMonitor(input, 'dragY');
809 | folder.addMonitor(input, 'dropZone');
810 | folder.addMonitor(input, 'enabled');
811 | folder.addMonitor(input, 'localX');
812 | folder.addMonitor(input, 'localY');
813 |
814 | folder.addButton({ title: 'Enable debug' }).on('click', () => { inputPlugin.enableDebug(gameObject); });
815 | folder.addButton({ title: 'Remove debug' }).on('click', () => { inputPlugin.removeDebug(gameObject); });
816 |
817 | input.gameObject.once(GameObjectEvents.DESTROY, () => { folder.dispose(); });
818 |
819 | return folder;
820 | }
821 |
822 | export function AddArcadeBody (body, pane, options = { title: `Body (${body.gameObject.type} “${body.gameObject.name}”)` }) {
823 | const folder = pane.addFolder(options);
824 |
825 | // body.physicsType === Phaser.Physics.Arcade.DYNAMIC_BODY
826 |
827 | folder.addMonitor(body, 'enable');
828 | folder.addInput(body, 'enable');
829 | folder.addInput(body, 'debugShowBody');
830 | folder.addInput(body, 'debugShowVelocity');
831 | folder.addInput(body, 'debugBodyColor', { view: 'color' });
832 | folder.addMonitor(body.velocity, 'x', { label: 'velocity x' });
833 | folder.addMonitor(body.velocity, 'y', { label: 'velocity y' });
834 | folder.addMonitor(body, 'speed');
835 | folder.addMonitor(body, 'angle');
836 | folder.addMonitor(body, '_dx', { label: 'deltaX()' });
837 | folder.addMonitor(body, '_dy', { label: 'deltaY()' });
838 | folder.addMonitor(body, '_tx', { label: 'deltaXFinal()' });
839 | folder.addMonitor(body, '_ty', { label: 'deltaYFinal()' });
840 | folder.addMonitor(body, 'left');
841 | folder.addMonitor(body, 'top');
842 | folder.addMonitor(body, 'right');
843 | folder.addMonitor(body, 'bottom');
844 | folder.addMonitor(body.center, 'x', { label: 'center.x' });
845 | folder.addMonitor(body.center, 'y', { label: 'center.y' });
846 |
847 | body.gameObject.once(GameObjectEvents.DESTROY, () => { folder.dispose(); });
848 |
849 | return folder;
850 | }
851 |
852 | export function AddAnimationState (state, pane, options = { title: `Animation (${state.parent.type} “${state.parent.name}”)` }) {
853 | const folder = pane.addFolder(options);
854 |
855 | const proxy = {
856 | get 'getName()' () { return state.getName(); },
857 | get 'getFrameName()' () { return state.getFrameName(); },
858 | get nextAnim () { return state.nextAnim ? (state.nextAnim.key || state.nextAnim) : ''; }
859 | };
860 |
861 | folder.addMonitor(proxy, 'getName()');
862 | folder.addMonitor(proxy, 'getFrameName()');
863 | folder.addMonitor(state, 'delay');
864 | folder.addMonitor(state, 'delayCounter');
865 | folder.addMonitor(state, 'duration');
866 | folder.addMonitor(state, 'forward');
867 | folder.addMonitor(state, 'frameRate');
868 | folder.addMonitor(state, 'hasStarted');
869 | folder.addMonitor(state, 'isPaused');
870 | folder.addMonitor(state, 'isPlaying');
871 | folder.addMonitor(state, 'msPerFrame');
872 | folder.addMonitor(proxy, 'nextAnim', { label: 'nextAnim (key)' });
873 | folder.addMonitor(state.nextAnimsQueue, 'length', { label: 'nextAnimsQueue.length', format: FormatLength });
874 | folder.addMonitor(state, 'repeat');
875 | folder.addMonitor(state, 'repeatCounter');
876 | folder.addMonitor(state, 'repeatDelay');
877 | folder.addInput(state, 'skipMissedFrames');
878 | folder.addInput(state, 'timeScale', { min: 0.1, max: 10, step: 0.1 });
879 | folder.addMonitor(state, 'yoyo');
880 |
881 | folder.addButton({ title: 'Stop' }).on('click', () => { console.info('Stop animation'); state.stop(); });
882 | folder.addButton({ title: 'Pause' }).on('click', () => { console.info('Pause animation'); state.pause(); });
883 | folder.addButton({ title: 'Resume' }).on('click', () => { console.info('Resume animation'); state.resume(); });
884 | folder.addButton({ title: 'Restart' }).on('click', () => { console.info('Restart animation'); state.restart(); });
885 | folder.addButton({ title: 'Reverse' }).on('click', () => { console.info('Reverse animation'); state.reverse(); });
886 | folder.addButton({ title: 'Next frame' }).on('click', () => { console.info('Next animation frame'); state.nextFrame(); });
887 | folder.addButton({ title: 'Previous frame' }).on('click', () => { console.info('Previous animation frame'); state.previousFrame(); });
888 |
889 | state.parent.once(GameObjectEvents.DESTROY, () => { folder.dispose(); });
890 |
891 | return folder;
892 | }
893 |
894 | export function AddKey (key, pane, options = { title: `Key (${key.keyCode})` }) {
895 | const folder = pane.addFolder(options);
896 |
897 | folder.addMonitor(key, 'duration');
898 | folder.addInput(key, 'emitOnRepeat');
899 | folder.addInput(key, 'enabled');
900 | folder.addMonitor(key, 'isDown');
901 | folder.addMonitor(key, 'isUp');
902 | folder.addMonitor(key, 'location');
903 | folder.addMonitor(key, 'repeats');
904 | folder.addMonitor(key, 'timeDown');
905 | folder.addMonitor(key, 'timeUp');
906 |
907 | folder.addButton({ title: 'Destroy' }).on('click', () => { console.info('Destroy key'); key.destroy(); folder.dispose(); });
908 |
909 | return folder;
910 | }
911 |
912 | export function AddKeys (keys, pane, options = { title: 'Keys' }) {
913 | const folder = pane.addFolder(options);
914 |
915 | for (const name in keys) {
916 | const key = keys[name];
917 |
918 | folder.addMonitor(key, 'isDown', { label: `${name} isDown` });
919 | }
920 |
921 | return folder;
922 | }
923 |
924 | export function AddFXComponent (comp, pane, options = { title: `${comp.isPost ? 'Post' : 'Pre'} FX` }) {
925 | const folder = pane.addFolder(options);
926 |
927 | folder.addMonitor(comp, 'enabled');
928 |
929 | folder.addInput(comp, 'padding', { min: 0, max: 32, step: 1 });
930 |
931 | folder.addButton({ title: 'Clear' }).on('click', () => { comp.clear(); });
932 | folder.addButton({ title: 'Disable' }).on('click', () => { comp.disable(); });
933 | folder.addButton({ title: 'Enable' }).on('click', () => { comp.enable(); });
934 |
935 | for (const ctrl of comp.list) {
936 | AddFXController(ctrl, folder);
937 | }
938 |
939 | return folder;
940 | }
941 |
942 | export function AddFXController (ctrl, pane, options = { title: `FX ${FXMap[ctrl.type]}` }) {
943 | const folder = pane.addFolder(options);
944 |
945 | for (const key in ctrl) {
946 | if (key.startsWith('_')) continue;
947 |
948 | if (key === 'type') continue;
949 |
950 | const val = ctrl[key];
951 | const typ = typeof val;
952 |
953 | if (typ !== 'number' && typ !== 'boolean') continue;
954 |
955 | if (key === 'alpha') {
956 | folder.addInput(ctrl, key, { min: 0, max: 1 });
957 |
958 | continue;
959 | }
960 |
961 | if (key === 'axis' || key === 'direction') {
962 | folder.addInput(ctrl, key, { min: 0, max: 1, step: 1 });
963 |
964 | continue;
965 | }
966 |
967 | if (key === 'color' || key === 'color1' || key === 'color2' || key === 'backgroundColor') {
968 | folder.addInput(ctrl, key, { view: 'color' });
969 |
970 | continue;
971 | }
972 |
973 | if (key === 'progress') {
974 | folder.addInput(ctrl, key, { min: 0, max: 1 });
975 |
976 | continue;
977 | }
978 |
979 | if (key === 'quality') {
980 | folder.addInput(ctrl, key, { options: { low: 0, medium: 1, high: 2 } });
981 |
982 | continue;
983 | }
984 |
985 | if (key === 'samples') {
986 | folder.addInput(ctrl, key, { min: 1, max: 12, step: 1 });
987 |
988 | continue;
989 | }
990 |
991 | if (key === 'steps') {
992 | folder.addInput(ctrl, key, { min: 1, max: 10, step: 1 });
993 |
994 | continue;
995 | }
996 |
997 | folder.addInput(ctrl, key);
998 | }
999 |
1000 | return folder;
1001 | }
1002 |
1003 | export function AddPipelines (pipelines, pane, options = { title: 'Pipelines' }) {
1004 | const folder = pane.addFolder(options);
1005 |
1006 | for (const pipeline of pipelines) {
1007 | folder.addInput(pipeline, 'active', { label: `${pipeline.name} active` });
1008 | }
1009 |
1010 | return folder;
1011 | }
1012 |
1013 | export function AddPipeline (pipeline, pane, options = { title: `${pipeline.isPost ? 'Post Pipeline' : 'Pipeline'} “${pipeline.name}”` }) {
1014 | const folder = pane.addFolder(options);
1015 |
1016 | folder.addInput(pipeline, 'active');
1017 | // What else?
1018 |
1019 | return folder;
1020 | }
1021 |
1022 | export function AddActive (items, pane, options = { title: 'Active' }) {
1023 | const folder = pane.addFolder(options);
1024 |
1025 | for (const item of items) {
1026 | folder.addInput(item, 'active', { min: 0, max: 1, label: item.name || item.type || '(Unnamed)' });
1027 | }
1028 |
1029 | return folder;
1030 | }
1031 |
1032 | export function AddAlpha (items, pane, options = { title: 'Alpha' }) {
1033 | const folder = pane.addFolder(options);
1034 |
1035 | for (const item of items) {
1036 | folder.addInput(item, 'alpha', { min: 0, max: 1, label: item.name || item.type || '(Unnamed)' });
1037 | }
1038 |
1039 | return folder;
1040 | }
1041 |
1042 | export function AddVisible (items, pane, options = { title: 'Visible' }) {
1043 | const folder = pane.addFolder(options);
1044 |
1045 | for (const item of items) {
1046 | folder.addInput(item, 'visible', { label: item.name || item.type || '(Unnamed)' });
1047 | }
1048 |
1049 | return folder;
1050 | }
1051 |
1052 | export function AddScenes (scenes, pane, options = { title: 'Scenes Visible' }) {
1053 | const folder = pane.addFolder(options);
1054 |
1055 | for (const scene of scenes) {
1056 | folder.addInput(scene.sys.settings, 'visible', { label: scene.sys.settings.key });
1057 | }
1058 |
1059 | return folder;
1060 | }
1061 |
1062 | export function FormatLength (len) {
1063 | return len.toFixed(0);
1064 | }
1065 |
1066 | export function InspectByName (name, gameObjects, pane) {
1067 | if (name === null) return;
1068 |
1069 | const gameObject = GetFirst(gameObjects, 'name', name);
1070 |
1071 | if (!gameObject) {
1072 | console.info('No game object found with name "%s"', name);
1073 |
1074 | return;
1075 | }
1076 |
1077 | const newPane = AddGameObject(gameObject, pane);
1078 |
1079 | console.info('Added folder %s to folder %s', newPane.title, pane.title);
1080 | }
1081 |
1082 | export function InspectByType (type, gameObjects, pane) {
1083 | if (!type) return;
1084 |
1085 | const gameObject = GetFirst(gameObjects, 'type', type);
1086 |
1087 | if (!gameObject) {
1088 | console.info('No game object found with type "%s"', type);
1089 |
1090 | return;
1091 | }
1092 |
1093 | const newPane = AddGameObject(gameObject, pane);
1094 |
1095 | console.info('Added folder %s to folder %s', newPane.title, pane.title);
1096 | }
1097 |
1098 | export function InspectByIndex (index, gameObjects, pane) {
1099 | if (index === null || index < 0) return;
1100 |
1101 | index = Number(index);
1102 |
1103 | const gameObject = gameObjects[index];
1104 |
1105 | if (!gameObject) {
1106 | console.info('No game object found at index %s', index);
1107 |
1108 | return;
1109 | }
1110 |
1111 | const newPane = AddGameObject(gameObject, pane);
1112 |
1113 | console.info('Added folder %s to folder %s', newPane.title, pane.title);
1114 | }
1115 |
--------------------------------------------------------------------------------
/test/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | env:
2 | browser: yes
3 | es6: no
4 | mocha: yes
5 | extends: semistandard
6 | globals:
7 | Atomics: readonly
8 | SharedArrayBuffer: readonly
9 | Phaser: readonly
10 | chai: readonly
11 | rules:
12 | no-new: off
13 |
--------------------------------------------------------------------------------
/test/test-load.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
25 | Test of Phaser 3 Inspector Plugin, script loading
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/test/test-load.js:
--------------------------------------------------------------------------------
1 | /* global Phaser */
2 |
3 | const { assert } = chai;
4 |
5 | mocha.setup('bdd');
6 |
7 | describe('Phaser', function () {
8 | it('is an object', function () {
9 | assert.isObject(Phaser);
10 | });
11 |
12 | it('is the required version', function () {
13 | assert.propertyVal(Phaser, 'VERSION', '3.80.1');
14 | });
15 | });
16 |
17 | describe('new Game', function () {
18 | let game;
19 |
20 | afterEach(function () {
21 | game.destroy(true);
22 | game.runDestroy();
23 | game = null;
24 | });
25 |
26 | describe('Load script and install', function () {
27 | it('should not error', function (done) {
28 | game = new Phaser.Game({
29 | type: Phaser.AUTO,
30 | audio: { noAudio: true },
31 | scene: [
32 | {
33 | key: 'scene1',
34 |
35 | map: {},
36 |
37 | physics: {
38 | arcade: {},
39 | matter: {}
40 | },
41 |
42 | init: function () {
43 | this.sys.scenePlugin.start('preload');
44 | }
45 | },
46 | {
47 | key: 'preload',
48 |
49 | map: {},
50 |
51 | physics: {
52 | arcade: {},
53 | matter: {}
54 | },
55 |
56 | preload: function () {
57 | this.sys.load.scripts('inspector', ['../vendor/tweakpane.js', '../dist/phaser-plugin-inspector.umd.js']);
58 | this.sys.load.once('complete', function () {
59 | // eslint-disable-next-line no-undef
60 | PhaserPluginInspector.Install(this.sys.plugins);
61 | done();
62 | }, this);
63 | },
64 |
65 | create: function () {
66 | this.sys.scenePlugin.start('scene2');
67 | }
68 | },
69 | { key: 'scene2', map: {}, physics: { arcade: {}, matter: {} } },
70 | { key: 'scene3', map: {}, physics: { arcade: {}, matter: {} } }
71 | ]
72 | });
73 | });
74 | });
75 | });
76 |
77 | // mocha.checkLeaks();
78 | mocha.globals(['Phaser']);
79 | mocha.run();
80 |
--------------------------------------------------------------------------------
/test/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
25 | Test of Phaser 3 Inspector Plugin
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | /* global Phaser, PhaserPluginInspector, Tweakpane */
2 |
3 | const { assert } = chai;
4 |
5 | mocha.setup({ allowUncaught: true, ui: 'bdd' });
6 |
7 | describe('Phaser', function () {
8 | it('is an object', function () {
9 | assert.isObject(Phaser);
10 | });
11 |
12 | it('is the required version', function () {
13 | assert.propertyVal(Phaser, 'VERSION', '3.87');
14 | });
15 | });
16 |
17 | describe('Tweakpane', function () {
18 | it('is an object', function () {
19 | assert.isObject(Tweakpane);
20 | });
21 | });
22 |
23 | describe('PhaserPluginInspector', function () {
24 | it('is an object', function () {
25 | assert.isObject(PhaserPluginInspector);
26 | });
27 |
28 | describe('PhaserPluginInspector.DefaultPluginsConfig', function () {
29 | it('is an object', function () {
30 | assert.isObject(PhaserPluginInspector.DefaultPluginsConfig);
31 | });
32 | });
33 |
34 | describe('PhaserPluginInspector.InspectorGlobalPlugin', function () {
35 | it('is a function', function () {
36 | assert.isFunction(PhaserPluginInspector.InspectorGlobalPlugin);
37 | });
38 | });
39 |
40 | describe('PhaserPluginInspector.InspectorScenePlugin', function () {
41 | it('is a function', function () {
42 | assert.isFunction(PhaserPluginInspector.InspectorScenePlugin);
43 | });
44 | });
45 |
46 | for (
47 | const name of [
48 | 'AddActive',
49 | 'AddAlpha',
50 | 'AddAnimationState',
51 | 'AddArcadeBody',
52 | 'AddArcadePhysicsWorld',
53 | 'AddCamera',
54 | 'AddChain',
55 | 'AddGameObject',
56 | 'AddGroup',
57 | 'AddFXComponent',
58 | 'AddFXController',
59 | 'AddInput',
60 | 'AddKey',
61 | 'AddKeys',
62 | 'AddLight',
63 | 'AddMatterPhysicsWorld',
64 | 'AddParticleEmitter',
65 | 'AddPointer',
66 | 'AddScenes',
67 | 'AddSound',
68 | 'AddTimeline',
69 | 'AddTimerEvent',
70 | 'AddTween',
71 | 'AddVideo',
72 | 'AddVisible'
73 | ]
74 | ) {
75 | describe(`PhaserPluginInspector.${name}`, function () {
76 | it('is a function', function () {
77 | assert.isFunction(PhaserPluginInspector[name]);
78 | });
79 | });
80 | }
81 | });
82 |
83 | describe('new Game', function () {
84 | let game;
85 |
86 | beforeEach(function () {
87 | });
88 |
89 | afterEach(function () {
90 | console.log('Destroy InspectorGlobalPlugin …');
91 | game.plugins.get('InspectorGlobalPlugin').destroy();
92 | console.log('Remove InspectorGlobalPlugin …');
93 | game.plugins.removeGlobalPlugin('InspectorGlobalPlugin');
94 | console.log('Remove InspectorScenePlugin …');
95 | game.plugins.removeScenePlugin('InspectorScenePlugin');
96 | console.log('Destroy game …');
97 | game.destroy(true);
98 | game.runDestroy();
99 | game = null;
100 | });
101 |
102 | describe('Install with DefaultPluginsConfig', function () {
103 | it('should not error', function (done) {
104 | game = new Phaser.Game({
105 | input: { activePointers: 0 },
106 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
107 | callbacks: {
108 | postBoot: function (game) {
109 | assert.isObject(game.plugins.getEntry('InspectorGlobalPlugin'));
110 | assert.include(game.plugins.getDefaultScenePlugins(), 'InspectorScenePlugin');
111 | done();
112 | }
113 | },
114 | scene: {
115 | map: {},
116 | physics: { arcade: {}, matter: {} },
117 | init: function () {
118 | assert.property(this, 'inspectorGame');
119 | assert.property(this, 'inspectorScene');
120 | assert.notProperty(this.sys, 'inspectorGame');
121 | assert.property(this.sys, 'inspectorScene');
122 | }
123 | }
124 | });
125 | });
126 | });
127 |
128 | describe('Install with DefaultPluginsConfig, Canvas renderer', function () {
129 | it('should not error', function (done) {
130 | game = new Phaser.Game({
131 | type: Phaser.CANVAS,
132 | input: { activePointers: 0 },
133 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
134 | callbacks: {
135 | postBoot: function (game) {
136 | assert.isObject(game.plugins.getEntry('InspectorGlobalPlugin'));
137 | assert.include(game.plugins.getDefaultScenePlugins(), 'InspectorScenePlugin');
138 | done();
139 | }
140 | },
141 | scene: {
142 | map: {},
143 | physics: { arcade: {}, matter: {} },
144 | init: function () {
145 | console.log('init', this);
146 | assert.property(this, 'inspectorGame');
147 | assert.property(this, 'inspectorScene');
148 | assert.notProperty(this.sys, 'inspectorGame');
149 | assert.property(this.sys, 'inspectorScene');
150 | }
151 | }
152 | });
153 | });
154 | });
155 |
156 | describe('Install with DefaultPluginsConfig, disable Web Audio', function () {
157 | it('should not error', function (done) {
158 | game = new Phaser.Game({
159 | audio: { disableWebAudio: true },
160 | input: { activePointers: 0 },
161 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
162 | callbacks: {
163 | postBoot: function (game) {
164 | assert.isObject(game.plugins.getEntry('InspectorGlobalPlugin'));
165 | assert.include(game.plugins.getDefaultScenePlugins(), 'InspectorScenePlugin');
166 | done();
167 | }
168 | },
169 | scene: {
170 | map: {},
171 | physics: { arcade: {}, matter: {} },
172 | init: function () {
173 | assert.property(this, 'inspectorGame');
174 | assert.property(this, 'inspectorScene');
175 | assert.notProperty(this.sys, 'inspectorGame');
176 | assert.property(this.sys, 'inspectorScene');
177 | }
178 | }
179 | });
180 | });
181 | });
182 |
183 | describe('Install with DefaultPluginsConfig, disable audio', function () {
184 | it('should not error', function (done) {
185 | game = new Phaser.Game({
186 | audio: { disableAudio: true },
187 | input: { activePointers: 0 },
188 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
189 | callbacks: {
190 | postBoot: function (game) {
191 | assert.isObject(game.plugins.getEntry('InspectorGlobalPlugin'));
192 | assert.include(game.plugins.getDefaultScenePlugins(), 'InspectorScenePlugin');
193 | done();
194 | }
195 | },
196 | scene: {
197 | map: {},
198 | physics: { arcade: {}, matter: {} },
199 | init: function () {
200 | assert.property(this, 'inspectorGame');
201 | assert.property(this, 'inspectorScene');
202 | assert.notProperty(this.sys, 'inspectorGame');
203 | assert.property(this.sys, 'inspectorScene');
204 | }
205 | }
206 | });
207 | });
208 | });
209 |
210 | describe('Install with DefaultPluginsConfig, disable input', function () {
211 | it('should not error', function (done) {
212 | game = new Phaser.Game({
213 | audio: { disableAudio: true },
214 | input: { gamepad: false, keyboard: false, mouse: false, touch: false, wheel: false },
215 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
216 | callbacks: {
217 | postBoot: function (game) {
218 | assert.isObject(game.plugins.getEntry('InspectorGlobalPlugin'));
219 | assert.include(game.plugins.getDefaultScenePlugins(), 'InspectorScenePlugin');
220 | done();
221 | }
222 | },
223 | scene: {
224 | map: {},
225 | physics: { arcade: {}, matter: {} },
226 | init: function () {
227 | assert.property(this, 'inspectorGame');
228 | assert.property(this, 'inspectorScene');
229 | assert.notProperty(this.sys, 'inspectorGame');
230 | assert.property(this.sys, 'inspectorScene');
231 | }
232 | }
233 | });
234 | });
235 | });
236 |
237 | describe('Install with DefaultPluginsConfig, click buttons', function () {
238 | it.skip('should not error', function (done) {
239 | game = new Phaser.Game({
240 | input: { activePointers: 0 },
241 | plugins: PhaserPluginInspector.DefaultPluginsConfig,
242 | callbacks: {
243 | postBoot: function (game) {
244 | assert.isObject(game.plugins.getEntry('InspectorGlobalPlugin'));
245 | assert.include(game.plugins.getDefaultScenePlugins(), 'InspectorScenePlugin');
246 | }
247 | },
248 | scene: {
249 | map: {},
250 | physics: { arcade: {}, matter: {} },
251 | create: function () {
252 | assert.property(this, 'inspectorGame');
253 |
254 | console.warn('Will click a lot of buttons. These have side effects.');
255 |
256 | const skipExpr = /(Destroy|Remove|…)/;
257 |
258 | for (const button of this.inspectorGame.pane.containerElem_.querySelectorAll('.tp-btnv_b')) {
259 | const { innerText } = button;
260 |
261 | if (skipExpr.test(innerText)) {
262 | console.log('Skipping button because it matches the exclude pattern', innerText);
263 |
264 | continue;
265 | }
266 |
267 | console.log('Click', button.innerText);
268 |
269 | button.click();
270 | }
271 |
272 | console.log('Wait for 0.4s');
273 |
274 | setTimeout(() => {
275 | console.log('Done waiting');
276 |
277 | done();
278 | }, 400);
279 | }
280 | }
281 | });
282 | });
283 | });
284 |
285 | describe('Install with mappings', function () {
286 | it('should not error', function (done) {
287 | game = new Phaser.Game({
288 | type: Phaser.AUTO,
289 | audio: { noAudio: true },
290 | input: { activePointers: 0 },
291 | plugins: {
292 | global: [{ key: 'InspectorGlobalPlugin', plugin: PhaserPluginInspector.InspectorGlobalPlugin, mapping: 'inspectorGadget' }],
293 | scene: [{ key: 'InspectorScenePlugin', plugin: PhaserPluginInspector.InspectorScenePlugin, mapping: 'inspectorClouseau' }]
294 | },
295 | callbacks: {
296 | postBoot: function (game) {
297 | assert.isObject(game.plugins.getEntry('InspectorGlobalPlugin'));
298 | assert.include(game.plugins.getDefaultScenePlugins(), 'InspectorScenePlugin');
299 | done();
300 | }
301 | },
302 | scene: {
303 | map: {},
304 | physics: { arcade: {}, matter: {} },
305 | init: function () {
306 | console.log('init', this);
307 | assert.property(this, 'inspectorGadget');
308 | assert.property(this, 'inspectorClouseau');
309 | assert.notProperty(this.sys, 'inspectorGadget');
310 | assert.property(this.sys, 'inspectorClouseau');
311 | }
312 | }
313 | });
314 | });
315 | });
316 |
317 | describe('Install without mappings', function () {
318 | it('should not error', function (done) {
319 | game = new Phaser.Game({
320 | type: Phaser.AUTO,
321 | audio: { noAudio: true },
322 | plugins: {
323 | global: [{ key: 'InspectorGlobalPlugin', plugin: PhaserPluginInspector.InspectorGlobalPlugin, start: true }],
324 | scene: [{ key: 'InspectorScenePlugin', plugin: PhaserPluginInspector.InspectorScenePlugin, start: true }]
325 | },
326 | callbacks: {
327 | postBoot: function (game) {
328 | assert.isObject(game.plugins.getEntry('InspectorGlobalPlugin'));
329 | assert.include(game.plugins.getDefaultScenePlugins(), 'InspectorScenePlugin');
330 | done();
331 | }
332 | },
333 | scene: {
334 | map: {},
335 | physics: { arcade: {}, matter: {} },
336 | init: function () {
337 | console.log('init', this);
338 | }
339 | }
340 | });
341 | });
342 | });
343 |
344 | describe('Install plugin from postBoot()', function () {
345 | it('should not error', function (done) {
346 | game = new Phaser.Game({
347 | type: Phaser.AUTO,
348 | audio: { noAudio: true },
349 | callbacks: {
350 | postBoot: function (game) {
351 | PhaserPluginInspector.Install(game.plugins);
352 | assert.isObject(game.plugins.getEntry('InspectorGlobalPlugin'));
353 | assert.include(game.plugins.getDefaultScenePlugins(), 'InspectorScenePlugin');
354 | done();
355 | }
356 | },
357 | scene: {
358 | map: {},
359 | physics: { arcade: {}, matter: {} },
360 | init: function () {
361 | assert.notProperty(this, 'inspectorScene', 'Plugin not in scene!');
362 | assert.notProperty(this.sys, 'inspectorScene', 'Plugin not in scene systems!');
363 | }
364 | }
365 | });
366 | });
367 | });
368 | });
369 |
370 | for (const renderType of [Phaser.CANVAS, Phaser.WEBGL]) {
371 | describe(`new Game, no install, renderer ${renderType}`, function () {
372 | const {
373 | AddActive,
374 | AddAlpha,
375 | AddAnimationState,
376 | AddArcadeBody,
377 | AddCamera,
378 | AddChain,
379 | AddFXController,
380 | AddGameObject,
381 | AddGroup,
382 | AddKey,
383 | AddKeys,
384 | AddInput,
385 | AddLight,
386 | AddParticleEmitter,
387 | AddScenes,
388 | AddTimeline,
389 | AddTimerEvent,
390 | AddTween,
391 | AddVideo,
392 | AddVisible
393 | } = PhaserPluginInspector;
394 |
395 | let pane = new Tweakpane.Pane();
396 | let game;
397 | let scene;
398 |
399 | before(function (done) {
400 | game = new Phaser.Game({
401 | type: renderType,
402 | canvasStyle: 'display: none',
403 | scene: {
404 | physics: { arcade: { debug: true }, matter: {} },
405 | init: function () {
406 | scene = this;
407 | this.scene.sleep();
408 | done();
409 | }
410 | }
411 | });
412 | });
413 |
414 | after(function () {
415 | pane.dispose();
416 | game.destroy(true);
417 | game.runDestroy();
418 | game = null;
419 | pane = null;
420 | scene = null;
421 | });
422 |
423 | afterEach(function () {
424 | console.log('Clear display list?', scene.sys.displayList.length);
425 | scene.sys.displayList.shutdown();
426 | });
427 |
428 | describe('game.config.renderType', function () {
429 | it('is the specified type', function () {
430 | assert.propertyVal(game.config, 'renderType', renderType);
431 | });
432 | });
433 |
434 | describe('game.renderer.type', function () {
435 | it('is the specified type', function () {
436 | assert.propertyVal(game.renderer, 'type', renderType);
437 | });
438 | });
439 |
440 | describe('AddActive()', function () {
441 | it('does not error', function () {
442 | AddActive(
443 | [{ name: '1', active: true }, { name: '2', active: false }],
444 | pane
445 | );
446 | });
447 | });
448 |
449 | describe('AddAlpha()', function () {
450 | it('does not error', function () {
451 | AddAlpha(
452 | [{ name: '1', alpha: 1 }, { name: '2', alpha: 0 }],
453 | pane
454 | );
455 | });
456 | });
457 |
458 | describe('AddAnimationState(sprite.anims)', function () {
459 | it('does not error', function () {
460 | AddAnimationState(scene.add.sprite(0, 0, '__DEFAULT').anims, pane);
461 | });
462 | });
463 |
464 | describe('AddAnimationState() with chained key', function () {
465 | it('does not error', function () {
466 | scene.anims.create('anim1', { frames: [{ key: '__DEFAULT', frame: '__BASE' }] });
467 | const sprite = scene.add.sprite(0, 0, '__DEFAULT');
468 | sprite.anims.chain('anim1');
469 | AddAnimationState(sprite.anims, pane);
470 | });
471 | });
472 |
473 | describe('AddAnimationState() with chained anim', function () {
474 | it('does not error', function () {
475 | const anim = scene.anims.create('anim2', { frames: [{ key: '__DEFAULT', frame: '__BASE' }] });
476 | const sprite = scene.add.sprite(0, 0, '__DEFAULT');
477 | sprite.anims.chain(anim);
478 | AddAnimationState(sprite.anims, pane);
479 | });
480 | });
481 |
482 | describe('AddAnimationState() with chained play config', function () {
483 | it('does not error', function () {
484 | scene.anims.create('anim3', { frames: [{ key: '__DEFAULT', frame: '__BASE' }] });
485 | const sprite = scene.add.sprite(0, 0, '__DEFAULT');
486 | sprite.anims.chain({ key: 'anim3' });
487 | AddAnimationState(sprite.anims, pane);
488 | });
489 | });
490 |
491 | describe('AddArcadeBody(body)', function () {
492 | it('does not error', function () {
493 | AddArcadeBody(scene.physics.add.image(0, 0, '__DEFAULT').body, pane);
494 | });
495 | });
496 |
497 | describe('AddCamera()', function () {
498 | it('does not error', function () {
499 | const cam = scene.cameras.add();
500 |
501 | AddCamera(cam, pane);
502 |
503 | scene.cameras.remove(cam);
504 | });
505 | });
506 |
507 | // this.cameras.main.setPostPipeline(Phaser.FX.BLUR);
508 |
509 | describe('AddCamera(), setPostPipeline()', function () {
510 | it('does not error', function () {
511 | const cam = scene.cameras.add().setPostPipeline(Phaser.FX.BLUR);
512 |
513 | AddCamera(cam, pane);
514 |
515 | scene.cameras.remove(cam);
516 | });
517 | });
518 |
519 | describe('AddChain()', function () {
520 | it('does not error', function () {
521 | const chain = scene.tweens.chain({
522 | targets: { x: 0, y: 0 },
523 | tweens: [{ x: 1 }, { y: 1 }]
524 | });
525 |
526 | AddChain(chain, pane);
527 |
528 | chain.destroy();
529 | });
530 | });
531 |
532 | describe('AddGameObject(bitmap text)', function () {
533 | it('does not error', function () {
534 | scene.cache.bitmapFont.add('bitmapFont', Phaser.GameObjects.RetroFont.Parse(scene, {
535 | image: '__DEFAULT',
536 | width: 1,
537 | height: 1,
538 | chars: Phaser.GameObjects.RetroFont.TEXT_SET6,
539 | charsPerRow: 32
540 | }));
541 |
542 | AddGameObject(scene.add.bitmapText(0, 0, 'bitmapFont', 'Hello'), pane);
543 | });
544 | });
545 |
546 | describe('AddGameObject(blitter)', function () {
547 | it('does not error', function () {
548 | AddGameObject(scene.add.blitter(0, 0, '__DEFAULT'), pane);
549 | });
550 | });
551 |
552 | describe('AddGameObject(container)', function () {
553 | it('does not error', function () {
554 | AddGameObject(scene.add.container(0, 0, [scene.add.sprite(0, 0, '__DEFAULT')]), pane);
555 | });
556 | });
557 |
558 | describe('AddGameObject(dom)', function () {
559 | it('does not error', function () {
560 | AddGameObject(scene.add.dom(0, 0, 'b', '', 'Hello'), pane);
561 | });
562 | });
563 |
564 | describe('AddGameObject(graphics)', function () {
565 | it('does not error', function () {
566 | AddGameObject(scene.add.graphics(), pane);
567 | });
568 | });
569 |
570 | describe('AddGameObject(image)', function () {
571 | it('does not error', function () {
572 | AddGameObject(scene.add.image(0, 0, '__DEFAULT'), pane);
573 | });
574 | });
575 |
576 | describe('AddGameObject(layer)', function () {
577 | it('does not error', function () {
578 | AddGameObject(scene.add.layer(scene.add.sprite(0, 0, '__DEFAULT')), pane);
579 | });
580 | });
581 |
582 | describe('AddGameObject(nineslice)', function () {
583 | it('does not error', function () {
584 | AddGameObject(scene.add.nineslice(0, 0, '__DEFAULT'), pane);
585 | });
586 | });
587 |
588 | describe('AddGameObject(point light)', function () {
589 | it('does not error', function () {
590 | AddGameObject(scene.add.pointlight(0, 0), pane);
591 | });
592 | });
593 |
594 | describe('AddGameObject(render texture)', function () {
595 | it('does not error', function () {
596 | AddGameObject(scene.add.renderTexture(0, 0, 128, 128), pane);
597 | });
598 | });
599 |
600 | describe('AddGameObject(rope)', function () {
601 | it('does not error', function () {
602 | AddGameObject(scene.add.rope(0, 0, '__DEFAULT'), pane);
603 | });
604 | });
605 |
606 | describe('AddGameObject(shader)', function () {
607 | it('does not error', function () {
608 | if (game.config.renderType === Phaser.WEBGL) {
609 | AddGameObject(scene.add.shader(new Phaser.Display.BaseShader('test'), 0, 0, 1, 1), pane);
610 | } else {
611 | this.skip();
612 | }
613 | });
614 | });
615 |
616 | describe('AddGameObject(sprite)', function () {
617 | it('does not error', function () {
618 | AddGameObject(scene.add.sprite(0, 0, '__DEFAULT'), pane);
619 | });
620 | });
621 |
622 | describe('AddGameObject(star)', function () {
623 | it('does not error', function () {
624 | AddGameObject(scene.add.star(0, 0, 5, 10, 20), pane);
625 | });
626 | });
627 |
628 | describe('AddGameObject(text)', function () {
629 | it('does not error', function () {
630 | AddGameObject(scene.add.text(0, 0, 'Hello'), pane);
631 | });
632 | });
633 |
634 | describe('AddGameObject(tilemap layer)', function () {
635 | it('does not error', function () {
636 | const map = scene.make.tilemap({ width: 64, height: 64, tileWidth: 16, tileHeight: 16 });
637 | const tileset = map.addTilesetImage('__DEFAULT');
638 |
639 | AddGameObject(map.createBlankLayer('layer', tileset), pane);
640 | });
641 | });
642 |
643 | describe('AddGameObject(tilesprite)', function () {
644 | it('does not error', function () {
645 | AddGameObject(scene.add.tileSprite(0, 0, 32, 32, '__DEFAULT'), pane);
646 | });
647 | });
648 |
649 | describe('AddGameObject(mesh)', function () {
650 | it('does not error', function () {
651 | AddGameObject(scene.add.mesh(0, 0, '__DEFAULT').addVertices([-1, 1, 1, 1, -1, -1, 1, -1], [0, 0, 1, 0, 0, 1, 1, 1], [0, 2, 1, 2, 3, 1]), pane);
652 | });
653 | });
654 |
655 | describe('AddGameObject(plane)', function () {
656 | it('does not error', function () {
657 | AddGameObject(scene.add.plane(400, 300, '__DEFAULT', null, 8, 8, true), pane);
658 | });
659 | });
660 |
661 | describe('AddGameObject(image), preFX.addShadow()', function () {
662 | it('does not error', function () {
663 | const img = scene.add.image(0, 0, '__DEFAULT');
664 |
665 | img.preFX.addShadow(0, 0, 0.006, 2, 0x333333, 10);
666 |
667 | AddGameObject(img, pane);
668 | });
669 | });
670 |
671 | describe('AddGameObject(image), postFX.addShine()', function () {
672 | it('does not error', function () {
673 | if (game.config.renderType === Phaser.WEBGL) {
674 | const img = scene.add.image(0, 0, '__DEFAULT');
675 |
676 | img.postFX.addShine(1, 0.2, 5);
677 |
678 | AddGameObject(img, pane);
679 | } else {
680 | this.skip();
681 | }
682 | });
683 | });
684 |
685 | describe('AddFXController(preFX.addBarrel())', function () {
686 | it('does not error', function () {
687 | const fx = scene.add.image(0, 0, '__DEFAULT').preFX.addBarrel();
688 |
689 | AddFXController(fx, pane);
690 | });
691 | });
692 |
693 | describe('AddFXController(preFX.addBloom())', function () {
694 | it('does not error', function () {
695 | const fx = scene.add.image(0, 0, '__DEFAULT').preFX.addBloom();
696 | AddFXController(fx, pane);
697 | });
698 | });
699 |
700 | describe('AddFXController(preFX.addBlur())', function () {
701 | it('does not error', function () {
702 | const fx = scene.add.image(0, 0, '__DEFAULT').preFX.addBlur();
703 | AddFXController(fx, pane);
704 | });
705 | });
706 |
707 | describe('AddFXController(preFX.addBokeh())', function () {
708 | it('does not error', function () {
709 | const fx = scene.add.image(0, 0, '__DEFAULT').preFX.addBokeh();
710 | AddFXController(fx, pane);
711 | });
712 | });
713 |
714 | describe('AddFXController(preFX.addCircle())', function () {
715 | it('does not error', function () {
716 | const fx = scene.add.image(0, 0, '__DEFAULT').preFX.addCircle();
717 | AddFXController(fx, pane);
718 | });
719 | });
720 |
721 | describe('AddFXController(preFX.addColorMatrix())', function () {
722 | it('does not error', function () {
723 | const fx = scene.add.image(0, 0, '__DEFAULT').preFX.addColorMatrix();
724 | AddFXController(fx, pane);
725 | });
726 | });
727 |
728 | describe('AddFXController(preFX.addDisplacement())', function () {
729 | it('does not error', function () {
730 | const fx = scene.add.image(0, 0, '__DEFAULT').preFX.addDisplacement();
731 | AddFXController(fx, pane);
732 | });
733 | });
734 |
735 | describe('AddFXController(preFX.addGlow())', function () {
736 | it('does not error', function () {
737 | const fx = scene.add.image(0, 0, '__DEFAULT').preFX.addGlow();
738 | AddFXController(fx, pane);
739 | });
740 | });
741 |
742 | describe('AddFXController(preFX.addGradient())', function () {
743 | it('does not error', function () {
744 | const fx = scene.add.image(0, 0, '__DEFAULT').preFX.addGradient();
745 | AddFXController(fx, pane);
746 | });
747 | });
748 |
749 | describe('AddFXController(preFX.addPixelate())', function () {
750 | it('does not error', function () {
751 | const fx = scene.add.image(0, 0, '__DEFAULT').preFX.addPixelate();
752 | AddFXController(fx, pane);
753 | });
754 | });
755 |
756 | describe('AddFXController(preFX.addReveal())', function () {
757 | it('does not error', function () {
758 | const fx = scene.add.image(0, 0, '__DEFAULT').preFX.addReveal();
759 | AddFXController(fx, pane);
760 | });
761 | });
762 |
763 | describe('AddFXController(preFX.addShadow())', function () {
764 | it('does not error', function () {
765 | const fx = scene.add.image(0, 0, '__DEFAULT').preFX.addShadow();
766 | AddFXController(fx, pane);
767 | });
768 | });
769 |
770 | describe('AddFXController(preFX.addShine())', function () {
771 | it('does not error', function () {
772 | const fx = scene.add.image(0, 0, '__DEFAULT').preFX.addShine();
773 | AddFXController(fx, pane);
774 | });
775 | });
776 |
777 | describe('AddFXController(preFX.addTiltShift())', function () {
778 | it('does not error', function () {
779 | const fx = scene.add.image(0, 0, '__DEFAULT').preFX.addTiltShift();
780 | AddFXController(fx, pane);
781 | });
782 | });
783 |
784 | describe('AddFXController(preFX.addVignette())', function () {
785 | it('does not error', function () {
786 | const fx = scene.add.image(0, 0, '__DEFAULT').preFX.addVignette();
787 | AddFXController(fx, pane);
788 | });
789 | });
790 |
791 | describe('AddFXController(preFX.addWipe())', function () {
792 | it('does not error', function () {
793 | const fx = scene.add.image(0, 0, '__DEFAULT').preFX.addWipe();
794 | AddFXController(fx, pane);
795 | });
796 | });
797 |
798 | describe('AddFXController(postFX.addBarrel())', function () {
799 | it('does not error', function () {
800 | if (game.config.renderType === Phaser.WEBGL) {
801 | const fx = scene.add.image(0, 0, '__DEFAULT').postFX.addBarrel();
802 |
803 | AddFXController(fx, pane);
804 | } else {
805 | this.skip();
806 | }
807 | });
808 | });
809 |
810 | describe('AddGroup(group)', function () {
811 | it('does not error', function () {
812 | AddGroup(scene.add.group(), pane);
813 | });
814 | });
815 |
816 | describe('AddGroup(group with maxSize)', function () {
817 | it('does not error', function () {
818 | AddGroup(scene.add.group({ maxSize: 1 }), pane);
819 | });
820 | });
821 |
822 | describe('AddGroup(physics group)', function () {
823 | it('does not error', function () {
824 | AddGroup(scene.physics.add.group(), pane);
825 | });
826 | });
827 |
828 | describe('AddGroup(static physics group)', function () {
829 | it('does not error', function () {
830 | AddGroup(scene.physics.add.staticGroup(), pane);
831 | });
832 | });
833 |
834 | describe('AddInput(sprite.input)', function () {
835 | it('does not error', function () {
836 | AddInput(scene.add.sprite(0, 0, '__DEFAULT').setInteractive().input, pane);
837 | });
838 | });
839 |
840 | describe('AddKey(key)', function () {
841 | it('does not error', function () {
842 | AddKey(scene.input.keyboard.addKey('SPACE'), pane);
843 | });
844 | });
845 |
846 | describe('AddKeys(key)', function () {
847 | it('does not error', function () {
848 | AddKeys(scene.input.keyboard.addKeys('W,A,S,D'), pane);
849 | });
850 | });
851 |
852 | describe('AddLight(light)', function () {
853 | it('does not error', function () {
854 | AddLight(scene.lights.addLight(), pane);
855 | });
856 | });
857 |
858 | describe('AddParticleEmitter(particle emitter)', function () {
859 | it('does not error', function () {
860 | const particles = scene.add.particles(0, 0, '__DEFAULT');
861 |
862 | AddParticleEmitter(particles, pane);
863 | });
864 | });
865 |
866 | describe('AddParticleEmitter(particle emitter) ops', function () {
867 | describe('static value', function () {
868 | it('does not error', function () {
869 | AddParticleEmitter(scene.add.particles(0, 0, '__DEFAULT', { alpha: 0 }), pane);
870 | });
871 | });
872 | describe('random array', function () {
873 | it('does not error', function () {
874 | AddParticleEmitter(scene.add.particles(0, 0, '__DEFAULT', { alpha: [0, 1] }), pane);
875 | });
876 | });
877 | describe('custom emit', function () {
878 | it('does not error', function () {
879 | AddParticleEmitter(scene.add.particles(0, 0, '__DEFAULT', { alpha: { onEmit: () => 1 } }), pane);
880 | });
881 | });
882 | describe('stepped start-end', function () {
883 | it('does not error', function () {
884 | AddParticleEmitter(scene.add.particles(0, 0, '__DEFAULT', { alpha: { start: 0, end: 1, steps: 2 } }), pane);
885 | });
886 | });
887 | describe('eased start-end', function () {
888 | it('does not error', function () {
889 | AddParticleEmitter(scene.add.particles(0, 0, '__DEFAULT', { alpha: { start: 0, end: 1 } }), pane);
890 | });
891 | });
892 | describe('random min-max', function () {
893 | it('does not error', function () {
894 | AddParticleEmitter(scene.add.particles(0, 0, '__DEFAULT', { alpha: { min: 0, max: 1 } }), pane);
895 | });
896 | });
897 | describe('random integer', function () {
898 | it('does not error', function () {
899 | AddParticleEmitter(scene.add.particles(0, 0, '__DEFAULT', { alpha: { random: [0, 1] } }), pane);
900 | });
901 | });
902 | describe('custom emit update', function () {
903 | it('does not error', function () {
904 | AddParticleEmitter(scene.add.particles(0, 0, '__DEFAULT', { alpha: { onEmit: () => 0, onUpdate: () => 1 } }), pane);
905 | });
906 | });
907 | describe('interpolated', function () {
908 | it('does not error', function () {
909 | AddParticleEmitter(scene.add.particles(0, 0, '__DEFAULT', { alpha: { values: [0, 1], interpolation: 'catmull' } }), pane);
910 | });
911 | });
912 | describe('color', function () {
913 | it('does not error', function () {
914 | AddParticleEmitter(scene.add.particles(0, 0, '__DEFAULT', { color: [0, 1, 2] }), pane);
915 | });
916 | });
917 | });
918 |
919 | describe('AddScenes()', function () {
920 | it('does not error', function () {
921 | AddScenes(
922 | [new Phaser.Scene('1'), new Phaser.Scene('2')],
923 | pane
924 | );
925 | });
926 | });
927 |
928 | describe('AddTimeline()', function () {
929 | it('does not error', function () {
930 | const timeline = scene.add.timeline([
931 | { at: 0 },
932 | { at: 1 }
933 | ]);
934 |
935 | AddTimeline(timeline, pane);
936 |
937 | timeline.destroy();
938 | });
939 | });
940 |
941 | describe('AddTimerEvent(timer event)', function () {
942 | it('does not error', function () {
943 | AddTimerEvent(scene.time.addEvent({ delay: 1000 }), pane);
944 | });
945 | });
946 |
947 | describe('AddTween(tween)', function () {
948 | it('does not error', function () {
949 | AddTween(scene.add.tween({ targets: {} }), pane);
950 | });
951 | });
952 |
953 | describe('AddTween(counter tween)', function () {
954 | it('does not error', function () {
955 | AddTween(scene.tweens.addCounter({ from: 1, to: 10 }), pane);
956 | });
957 | });
958 |
959 | describe('AddVideo(video)', function () {
960 | it('does not error', function () {
961 | const video = scene.add.video(0, 0).loadURL('data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAAAr9tZGF0AAACoAYF//+c3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDEyNSAtIEguMjY0L01QRUctNCBBVkMgY29kZWMgLSBDb3B5bGVmdCAyMDAzLTIwMTIgLSBodHRwOi8vd3d3LnZpZGVvbGFuLm9yZy94MjY0Lmh0bWwgLSBvcHRpb25zOiBjYWJhYz0xIHJlZj0zIGRlYmxvY2s9MTowOjAgYW5hbHlzZT0weDM6MHgxMTMgbWU9aGV4IHN1Ym1lPTcgcHN5PTEgcHN5X3JkPTEuMDA6MC4wMCBtaXhlZF9yZWY9MSBtZV9yYW5nZT0xNiBjaHJvbWFfbWU9MSB0cmVsbGlzPTEgOHg4ZGN0PTEgY3FtPTAgZGVhZHpvbmU9MjEsMTEgZmFzdF9wc2tpcD0xIGNocm9tYV9xcF9vZmZzZXQ9LTIgdGhyZWFkcz02IGxvb2thaGVhZF90aHJlYWRzPTEgc2xpY2VkX3RocmVhZHM9MCBucj0wIGRlY2ltYXRlPTEgaW50ZXJsYWNlZD0wIGJsdXJheV9jb21wYXQ9MCBjb25zdHJhaW5lZF9pbnRyYT0wIGJmcmFtZXM9MyBiX3B5cmFtaWQ9MiBiX2FkYXB0PTEgYl9iaWFzPTAgZGlyZWN0PTEgd2VpZ2h0Yj0xIG9wZW5fZ29wPTAgd2VpZ2h0cD0yIGtleWludD0yNTAga2V5aW50X21pbj0yNCBzY2VuZWN1dD00MCBpbnRyYV9yZWZyZXNoPTAgcmNfbG9va2FoZWFkPTQwIHJjPWNyZiBtYnRyZWU9MSBjcmY9MjMuMCBxY29tcD0wLjYwIHFwbWluPTAgcXBtYXg9NjkgcXBzdGVwPTQgaXBfcmF0aW89MS40MCBhcT0xOjEuMDAAgAAAAA9liIQAV/0TAAYdeBTXzg8AAALvbW9vdgAAAGxtdmhkAAAAAAAAAAAAAAAAAAAD6AAAACoAAQAAAQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAhl0cmFrAAAAXHRraGQAAAAPAAAAAAAAAAAAAAABAAAAAAAAACoAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAgAAAAIAAAAAAAkZWR0cwAAABxlbHN0AAAAAAAAAAEAAAAqAAAAAAABAAAAAAGRbWRpYQAAACBtZGhkAAAAAAAAAAAAAAAAAAAwAAAAAgBVxAAAAAAALWhkbHIAAAAAAAAAAHZpZGUAAAAAAAAAAAAAAABWaWRlb0hhbmRsZXIAAAABPG1pbmYAAAAUdm1oZAAAAAEAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAPxzdGJsAAAAmHN0c2QAAAAAAAAAAQAAAIhhdmMxAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAgACABIAAAASAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGP//AAAAMmF2Y0MBZAAK/+EAGWdkAAqs2V+WXAWyAAADAAIAAAMAYB4kSywBAAZo6+PLIsAAAAAYc3R0cwAAAAAAAAABAAAAAQAAAgAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAEAAAABAAAAFHN0c3oAAAAAAAACtwAAAAEAAAAUc3RjbwAAAAAAAAABAAAAMAAAAGJ1ZHRhAAAAWm1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAALWlsc3QAAAAlqXRvbwAAAB1kYXRhAAAAAQAAAABMYXZmNTQuNjMuMTA0');
962 |
963 | AddVideo(video, pane);
964 |
965 | video.destroy();
966 | });
967 | });
968 |
969 | describe('AddVisible()', function () {
970 | it('does not error', function () {
971 | AddVisible(
972 | [{ name: '1', visible: true }, { name: '2', visible: false }],
973 | pane
974 | );
975 | });
976 | });
977 | });
978 | }
979 |
980 | mocha.checkLeaks();
981 | mocha.globals(['Phaser']);
982 | mocha.run();
983 |
--------------------------------------------------------------------------------