@vpmedia/phaser 1.120.0 → 1.122.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +499 -607
- package/dist/index.js.map +1 -1
- package/dist/phaser/core/animation.d.ts.map +1 -1
- package/dist/phaser/core/animation_manager.d.ts.map +1 -1
- package/dist/phaser/core/animation_parser.d.ts +1 -1
- package/dist/phaser/core/array_set.d.ts.map +1 -1
- package/dist/phaser/core/callback.d.ts +24 -0
- package/dist/phaser/core/callback.d.ts.map +1 -0
- package/dist/phaser/core/device.d.ts +1 -5
- package/dist/phaser/core/device.d.ts.map +1 -1
- package/dist/phaser/core/dom.d.ts.map +1 -1
- package/dist/phaser/core/factory.d.ts +2 -1
- package/dist/phaser/core/factory.d.ts.map +1 -1
- package/dist/phaser/core/game.d.ts +3 -0
- package/dist/phaser/core/game.d.ts.map +1 -1
- package/dist/phaser/core/input.d.ts +11 -9
- package/dist/phaser/core/input.d.ts.map +1 -1
- package/dist/phaser/core/input_event.d.ts +1 -1
- package/dist/phaser/core/input_event.d.ts.map +1 -1
- package/dist/phaser/core/input_handler.d.ts.map +1 -1
- package/dist/phaser/core/input_mouse.d.ts.map +1 -1
- package/dist/phaser/core/input_mspointer.d.ts.map +1 -1
- package/dist/phaser/core/input_pointer.d.ts +3 -2
- package/dist/phaser/core/input_pointer.d.ts.map +1 -1
- package/dist/phaser/core/input_touch.d.ts.map +1 -1
- package/dist/phaser/core/loader.d.ts +5 -4
- package/dist/phaser/core/loader.d.ts.map +1 -1
- package/dist/phaser/core/scale_manager.d.ts +5 -4
- package/dist/phaser/core/scale_manager.d.ts.map +1 -1
- package/dist/phaser/core/scene_manager.d.ts.map +1 -1
- package/dist/phaser/core/signal.d.ts +14 -7
- package/dist/phaser/core/signal.d.ts.map +1 -1
- package/dist/phaser/core/signal_binding.d.ts +10 -10
- package/dist/phaser/core/signal_binding.d.ts.map +1 -1
- package/dist/phaser/core/sound.d.ts +3 -3
- package/dist/phaser/core/sound.d.ts.map +1 -1
- package/dist/phaser/core/sound_manager.d.ts +9 -3
- package/dist/phaser/core/sound_manager.d.ts.map +1 -1
- package/dist/phaser/core/sound_sprite.d.ts +19 -7
- package/dist/phaser/core/sound_sprite.d.ts.map +1 -1
- package/dist/phaser/core/timer.d.ts +5 -4
- package/dist/phaser/core/timer.d.ts.map +1 -1
- package/dist/phaser/core/timer_event.d.ts +3 -2
- package/dist/phaser/core/timer_event.d.ts.map +1 -1
- package/dist/phaser/core/tween.d.ts +7 -6
- package/dist/phaser/core/tween.d.ts.map +1 -1
- package/dist/phaser/core/tween_data.d.ts +2 -1
- package/dist/phaser/core/tween_data.d.ts.map +1 -1
- package/dist/phaser/core/tween_easing.d.ts +31 -31
- package/dist/phaser/core/tween_manager.d.ts.map +1 -1
- package/dist/phaser/display/bitmap_text.d.ts.map +1 -1
- package/dist/phaser/display/button.d.ts +2 -1
- package/dist/phaser/display/button.d.ts.map +1 -1
- package/dist/phaser/display/canvas/pool.d.ts.map +1 -1
- package/dist/phaser/display/canvas/renderer.d.ts +1 -1
- package/dist/phaser/display/canvas/renderer.d.ts.map +1 -1
- package/dist/phaser/display/canvas/tinter.d.ts.map +1 -1
- package/dist/phaser/display/canvas/util.d.ts +2 -2
- package/dist/phaser/display/canvas/util.d.ts.map +1 -1
- package/dist/phaser/display/display_object.d.ts +9 -6
- package/dist/phaser/display/display_object.d.ts.map +1 -1
- package/dist/phaser/display/graphics.d.ts +7 -3
- package/dist/phaser/display/graphics.d.ts.map +1 -1
- package/dist/phaser/display/group.d.ts +1 -1
- package/dist/phaser/display/group.d.ts.map +1 -1
- package/dist/phaser/display/image.d.ts.map +1 -1
- package/dist/phaser/display/sprite_util.d.ts.map +1 -1
- package/dist/phaser/display/text.d.ts +5 -0
- package/dist/phaser/display/text.d.ts.map +1 -1
- package/dist/phaser/display/webgl/base_texture.d.ts.map +1 -1
- package/dist/phaser/display/webgl/earcut.d.ts.map +1 -1
- package/dist/phaser/display/webgl/fast_sprite_batch.d.ts.map +1 -1
- package/dist/phaser/display/webgl/filter_manager.d.ts.map +1 -1
- package/dist/phaser/display/webgl/graphics.d.ts.map +1 -1
- package/dist/phaser/display/webgl/graphics_data.d.ts.map +1 -1
- package/dist/phaser/display/webgl/render_texture.d.ts.map +1 -1
- package/dist/phaser/display/webgl/renderer.d.ts.map +1 -1
- package/dist/phaser/display/webgl/sprite_batch.d.ts.map +1 -1
- package/dist/phaser/display/webgl/texture.d.ts.map +1 -1
- package/dist/phaser/geom/polygon.d.ts +11 -5
- package/dist/phaser/geom/polygon.d.ts.map +1 -1
- package/dist/phaser/geom/rectangle.d.ts.map +1 -1
- package/dist/phaser/geom/rounded_rectangle.d.ts.map +1 -1
- package/dist/phaser/util/math.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +9 -0
- package/src/phaser/core/animation.ts +1 -2
- package/src/phaser/core/animation_manager.ts +3 -11
- package/src/phaser/core/animation_parser.ts +2 -2
- package/src/phaser/core/array_set.ts +8 -10
- package/src/phaser/core/cache.ts +2 -2
- package/src/phaser/core/callback.ts +34 -0
- package/src/phaser/core/device.ts +24 -53
- package/src/phaser/core/device_util.ts +6 -6
- package/src/phaser/core/dom.ts +10 -7
- package/src/phaser/core/factory.ts +3 -2
- package/src/phaser/core/game.ts +4 -5
- package/src/phaser/core/input.ts +16 -12
- package/src/phaser/core/input_event.ts +1 -1
- package/src/phaser/core/input_handler.ts +21 -22
- package/src/phaser/core/input_mouse.ts +12 -17
- package/src/phaser/core/input_mspointer.ts +8 -11
- package/src/phaser/core/input_pointer.ts +22 -21
- package/src/phaser/core/input_touch.ts +16 -19
- package/src/phaser/core/loader.ts +75 -86
- package/src/phaser/core/loader_parser.ts +6 -6
- package/src/phaser/core/scale_manager.ts +34 -42
- package/src/phaser/core/scene_manager.ts +2 -1
- package/src/phaser/core/signal.ts +21 -13
- package/src/phaser/core/signal_binding.ts +20 -21
- package/src/phaser/core/sound.ts +9 -11
- package/src/phaser/core/sound_manager.ts +53 -47
- package/src/phaser/core/sound_sprite.ts +34 -21
- package/src/phaser/core/stage.ts +4 -4
- package/src/phaser/core/timer.ts +13 -30
- package/src/phaser/core/timer_event.ts +3 -2
- package/src/phaser/core/tween.ts +9 -8
- package/src/phaser/core/tween_data.ts +15 -41
- package/src/phaser/core/tween_easing.test.ts +35 -35
- package/src/phaser/core/tween_easing.ts +33 -33
- package/src/phaser/core/tween_manager.ts +77 -75
- package/src/phaser/display/bitmap_text.ts +7 -11
- package/src/phaser/display/button.ts +3 -2
- package/src/phaser/display/canvas/graphics.ts +7 -7
- package/src/phaser/display/canvas/pool.ts +5 -6
- package/src/phaser/display/canvas/renderer.ts +7 -4
- package/src/phaser/display/canvas/tinter.ts +9 -11
- package/src/phaser/display/canvas/util.test.ts +122 -0
- package/src/phaser/display/canvas/util.ts +34 -35
- package/src/phaser/display/display_object.ts +31 -43
- package/src/phaser/display/graphics.ts +30 -45
- package/src/phaser/display/group.ts +1 -1
- package/src/phaser/display/image.ts +9 -16
- package/src/phaser/display/sprite_util.ts +0 -1
- package/src/phaser/display/text.ts +27 -43
- package/src/phaser/display/webgl/base_texture.ts +3 -3
- package/src/phaser/display/webgl/earcut.ts +2 -3
- package/src/phaser/display/webgl/fast_sprite_batch.ts +1 -2
- package/src/phaser/display/webgl/filter_manager.ts +6 -18
- package/src/phaser/display/webgl/filter_texture.ts +3 -3
- package/src/phaser/display/webgl/graphics.ts +28 -38
- package/src/phaser/display/webgl/graphics_data.ts +0 -1
- package/src/phaser/display/webgl/render_texture.ts +4 -13
- package/src/phaser/display/webgl/renderer.ts +0 -1
- package/src/phaser/display/webgl/sprite_batch.ts +2 -9
- package/src/phaser/display/webgl/texture.ts +12 -15
- package/src/phaser/geom/point.ts +1 -1
- package/src/phaser/geom/polygon.test.ts +59 -0
- package/src/phaser/geom/polygon.ts +43 -45
- package/src/phaser/geom/rectangle.ts +3 -15
- package/src/phaser/geom/rounded_rectangle.ts +2 -4
- package/src/phaser/geom/util/point.ts +1 -1
- package/src/phaser/geom/util/rectangle.ts +2 -2
- package/src/phaser/util/math.ts +1 -5
|
@@ -50,8 +50,8 @@ export const xmlBitmapFont = (
|
|
|
50
50
|
xSpacing: number,
|
|
51
51
|
ySpacing: number
|
|
52
52
|
): BitmapFontData => {
|
|
53
|
-
const info = xml.querySelectorAll('info')
|
|
54
|
-
const common = xml.querySelectorAll('common')
|
|
53
|
+
const [info] = xml.querySelectorAll('info');
|
|
54
|
+
const [common] = xml.querySelectorAll('common');
|
|
55
55
|
const attr = (element: Element | undefined, name: string): number => Math.trunc(Number(element?.getAttribute(name)));
|
|
56
56
|
const data: BitmapFontData = {
|
|
57
57
|
font: info?.getAttribute('face') ?? '',
|
|
@@ -115,7 +115,7 @@ export const jsonBitmapFont = (
|
|
|
115
115
|
lineHeight: Math.trunc(Number(json.font.common._lineHeight)) + ySpacing,
|
|
116
116
|
chars: {},
|
|
117
117
|
};
|
|
118
|
-
json.font.chars.char
|
|
118
|
+
for (const letter of json.font.chars.char as Record<string, string>[]) {
|
|
119
119
|
const charCode = Math.trunc(Number(letter['_id']));
|
|
120
120
|
data.chars[charCode] = {
|
|
121
121
|
x: Math.trunc(Number(letter['_x'])),
|
|
@@ -127,14 +127,14 @@ export const jsonBitmapFont = (
|
|
|
127
127
|
xAdvance: Math.trunc(Number(letter['_xadvance'])) + xSpacing,
|
|
128
128
|
kerning: {},
|
|
129
129
|
};
|
|
130
|
-
}
|
|
130
|
+
}
|
|
131
131
|
if (json.font.kernings && json.font.kernings.kerning) {
|
|
132
|
-
json.font.kernings.kerning
|
|
132
|
+
for (const kerning of json.font.kernings.kerning as Record<string, string>[]) {
|
|
133
133
|
const char = data.chars[Math.trunc(Number(kerning['_second']))];
|
|
134
134
|
if (char) {
|
|
135
135
|
char.kerning[Math.trunc(Number(kerning['_first']))] = Math.trunc(Number(kerning['_amount']));
|
|
136
136
|
}
|
|
137
|
-
}
|
|
137
|
+
}
|
|
138
138
|
}
|
|
139
139
|
return finalizeBitmapFont(baseTexture, data);
|
|
140
140
|
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Point } from '../geom/point.js';
|
|
2
2
|
import { Rectangle } from '../geom/rectangle.js';
|
|
3
3
|
import { RENDER_CANVAS, SCALE_EXACT_FIT, SCALE_OFF, SCALE_RESIZE, SCALE_SHOW_ALL, SCALE_USER } from './const.js';
|
|
4
|
-
import type { Game } from './game.js';
|
|
4
|
+
import type { Game, GameConfig } from './game.js';
|
|
5
5
|
import { DOM } from './dom.js';
|
|
6
6
|
import { Signal } from './signal.js';
|
|
7
|
+
import type { AppliedCallback, Callback } from './callback.js';
|
|
7
8
|
|
|
8
9
|
/** The gap the canvas leaves around itself inside its parent. */
|
|
9
10
|
export type ScaleMargin = { left: number; top: number; right: number; bottom: number; x: number; y: number };
|
|
@@ -61,7 +62,7 @@ export class ScaleManager {
|
|
|
61
62
|
public parentScaleFactor!: Point;
|
|
62
63
|
public trackParentInterval!: number;
|
|
63
64
|
public onSizeChange!: Signal;
|
|
64
|
-
public onResize!:
|
|
65
|
+
public onResize!: Callback | null;
|
|
65
66
|
public onResizeContext!: unknown;
|
|
66
67
|
public _pendingScaleMode!: number | null;
|
|
67
68
|
public _fullScreenRestore!: { targetWidth: string; targetHeight: string } | null;
|
|
@@ -179,22 +180,21 @@ export class ScaleManager {
|
|
|
179
180
|
compat.clickTrampoline = '';
|
|
180
181
|
}
|
|
181
182
|
// Configure event listeners
|
|
182
|
-
const scope = this;
|
|
183
183
|
this._orientationChange = (event): void => {
|
|
184
|
-
|
|
184
|
+
this.orientationChange(event);
|
|
185
185
|
};
|
|
186
186
|
this._windowResize = (event): void => {
|
|
187
|
-
|
|
187
|
+
this.windowResize(event);
|
|
188
188
|
};
|
|
189
189
|
// This does not appear to be on the standards track
|
|
190
190
|
globalThis.addEventListener('orientationchange', this._orientationChange, false);
|
|
191
191
|
window.addEventListener('resize', this._windowResize, false);
|
|
192
192
|
if (this.compatibility.supportsFullScreen) {
|
|
193
193
|
this._fullScreenChange = (event): void => {
|
|
194
|
-
|
|
194
|
+
this.fullScreenChange(event);
|
|
195
195
|
};
|
|
196
196
|
this._fullScreenError = (event): void => {
|
|
197
|
-
|
|
197
|
+
this.fullScreenError(event);
|
|
198
198
|
};
|
|
199
199
|
document.addEventListener('webkitfullscreenchange', this._fullScreenChange, false);
|
|
200
200
|
document.addEventListener('mozfullscreenchange', this._fullScreenChange, false);
|
|
@@ -223,7 +223,7 @@ export class ScaleManager {
|
|
|
223
223
|
* TBD.
|
|
224
224
|
* @param {object} config - TBD.
|
|
225
225
|
*/
|
|
226
|
-
public parseConfig(config:
|
|
226
|
+
public parseConfig(config: GameConfig): void {
|
|
227
227
|
if (config.scaleMode !== undefined) {
|
|
228
228
|
if (this._booted) {
|
|
229
229
|
this.scaleMode = config.scaleMode;
|
|
@@ -234,11 +234,7 @@ export class ScaleManager {
|
|
|
234
234
|
if (config.fullScreenScaleMode !== undefined) {
|
|
235
235
|
this.fullScreenScaleMode = config.fullScreenScaleMode;
|
|
236
236
|
}
|
|
237
|
-
|
|
238
|
-
this.fullScreenTarget = config.fullScreenTarget;
|
|
239
|
-
} else {
|
|
240
|
-
this.fullScreenTarget = document.documentElement;
|
|
241
|
-
}
|
|
237
|
+
this.fullScreenTarget = config.fullScreenTarget ?? document.documentElement;
|
|
242
238
|
}
|
|
243
239
|
|
|
244
240
|
/**
|
|
@@ -252,7 +248,7 @@ export class ScaleManager {
|
|
|
252
248
|
if (this.game.parent !== '') {
|
|
253
249
|
if (typeof this.game.parent === 'string') {
|
|
254
250
|
// hopefully an element ID
|
|
255
|
-
target = document.
|
|
251
|
+
target = document.querySelector<HTMLElement>(`#${CSS.escape(this.game.parent)}`);
|
|
256
252
|
} else if (this.game.parent && this.game.parent.nodeType === 1) {
|
|
257
253
|
// quick test for a HTMLelement
|
|
258
254
|
target = this.game.parent;
|
|
@@ -334,7 +330,7 @@ export class ScaleManager {
|
|
|
334
330
|
* @param {Function} callback - TBD.
|
|
335
331
|
* @param {object} context - TBD.
|
|
336
332
|
*/
|
|
337
|
-
public setResizeCallback(callback:
|
|
333
|
+
public setResizeCallback(callback: Callback, context: unknown): void {
|
|
338
334
|
this.onResize = callback;
|
|
339
335
|
this.onResizeContext = context;
|
|
340
336
|
}
|
|
@@ -398,7 +394,7 @@ export class ScaleManager {
|
|
|
398
394
|
const orientationChanged = this.updateOrientationState();
|
|
399
395
|
if (boundsChanged || orientationChanged) {
|
|
400
396
|
if (this.onResize) {
|
|
401
|
-
this.onResize.call(this.onResizeContext, this, bounds);
|
|
397
|
+
(this.onResize as AppliedCallback).call(this.onResizeContext, this, bounds);
|
|
402
398
|
}
|
|
403
399
|
this.updateLayout();
|
|
404
400
|
this.signalSizeChange();
|
|
@@ -572,8 +568,8 @@ export class ScaleManager {
|
|
|
572
568
|
this.height = Math.min(this.height, bounds.height);
|
|
573
569
|
}
|
|
574
570
|
// Always truncate / force to integer
|
|
575
|
-
this.width
|
|
576
|
-
this.height
|
|
571
|
+
this.width = Math.trunc(this.width);
|
|
572
|
+
this.height = Math.trunc(this.height);
|
|
577
573
|
this.reflowCanvas();
|
|
578
574
|
}
|
|
579
575
|
|
|
@@ -743,12 +739,9 @@ export class ScaleManager {
|
|
|
743
739
|
const bounds = this.getParentBounds(this._tempBounds);
|
|
744
740
|
const { width } = bounds;
|
|
745
741
|
const { height } = bounds;
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
} else {
|
|
750
|
-
multiplier = Math.min(height / this.game.height, width / this.game.width);
|
|
751
|
-
}
|
|
742
|
+
const multiplier = expanding
|
|
743
|
+
? Math.max(height / this.game.height, width / this.game.width)
|
|
744
|
+
: Math.min(height / this.game.height, width / this.game.width);
|
|
752
745
|
this.width = Math.round(this.game.width * multiplier);
|
|
753
746
|
this.height = Math.round(this.game.height * multiplier);
|
|
754
747
|
}
|
|
@@ -796,9 +789,8 @@ export class ScaleManager {
|
|
|
796
789
|
}
|
|
797
790
|
if (!this.compatibility.supportsFullScreen) {
|
|
798
791
|
// Error is called in timeout to emulate the real fullscreenerror event better
|
|
799
|
-
const scope = this;
|
|
800
792
|
setTimeout((): void => {
|
|
801
|
-
|
|
793
|
+
this.fullScreenError(new Event('fullscreenerror'));
|
|
802
794
|
}, 10);
|
|
803
795
|
return false;
|
|
804
796
|
}
|
|
@@ -863,9 +855,8 @@ export class ScaleManager {
|
|
|
863
855
|
if (fsTarget && fsTarget.parentNode) {
|
|
864
856
|
// Make sure to cleanup synthetic target for sure;
|
|
865
857
|
// swap the canvas back to the parent.
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
parent.removeChild(fsTarget);
|
|
858
|
+
fsTarget.before(this.game.canvas);
|
|
859
|
+
fsTarget.remove();
|
|
869
860
|
}
|
|
870
861
|
this._createdFullScreenTarget = null;
|
|
871
862
|
}
|
|
@@ -880,16 +871,17 @@ export class ScaleManager {
|
|
|
880
871
|
return;
|
|
881
872
|
}
|
|
882
873
|
if (enteringFullscreen) {
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
fsTarget.style.
|
|
891
|
-
|
|
892
|
-
|
|
874
|
+
// Resize target, as long as it's not the canvas
|
|
875
|
+
if (
|
|
876
|
+
(this._createdFullScreenTarget || this.fullScreenScaleMode === SCALE_EXACT_FIT) &&
|
|
877
|
+
fsTarget !== this.game.canvas
|
|
878
|
+
) {
|
|
879
|
+
this._fullScreenRestore = {
|
|
880
|
+
targetWidth: fsTarget.style.width,
|
|
881
|
+
targetHeight: fsTarget.style.height,
|
|
882
|
+
};
|
|
883
|
+
fsTarget.style.width = '100%';
|
|
884
|
+
fsTarget.style.height = '100%';
|
|
893
885
|
}
|
|
894
886
|
} else {
|
|
895
887
|
// Have restore information
|
|
@@ -1044,9 +1036,9 @@ export class ScaleManager {
|
|
|
1044
1036
|
public get isFullScreen(): boolean {
|
|
1045
1037
|
return Boolean(
|
|
1046
1038
|
document.fullscreenElement ??
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1039
|
+
document.webkitFullscreenElement ??
|
|
1040
|
+
document.mozFullScreenElement ??
|
|
1041
|
+
document.msFullscreenElement
|
|
1050
1042
|
);
|
|
1051
1043
|
}
|
|
1052
1044
|
|
|
@@ -88,7 +88,8 @@ export class SceneManager {
|
|
|
88
88
|
public add(key: string, state: SceneDefinition, autoStart = false): SceneState {
|
|
89
89
|
let newState: SceneState;
|
|
90
90
|
if (typeof state === 'function') {
|
|
91
|
-
|
|
91
|
+
const SceneClass = state;
|
|
92
|
+
newState = new SceneClass(this.game);
|
|
92
93
|
} else {
|
|
93
94
|
newState = state;
|
|
94
95
|
if (!(state instanceof Scene)) {
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { SignalBinding } from './signal_binding.js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* A signal listener. The rest parameter is `never[]` so a handler with concrete parameters is
|
|
5
|
+
* assignable; the dispatcher widens it before applying the arguments.
|
|
6
|
+
*/
|
|
7
|
+
export type SignalListener = (...args: never[]) => unknown;
|
|
8
|
+
|
|
9
|
+
/** The listener as the dispatcher calls it, once the concrete parameter types are behind us. */
|
|
10
|
+
export type DispatchedListener = (...args: unknown[]) => unknown;
|
|
11
|
+
|
|
3
12
|
export class Signal {
|
|
4
13
|
public _bindings: SignalBinding[] | null = null;
|
|
5
14
|
public _prevParams: unknown[] | null = null;
|
|
@@ -19,7 +28,7 @@ export class Signal {
|
|
|
19
28
|
* @param {string} fnName - The name of the function this validation is for.
|
|
20
29
|
* @throws {Error} If the listener is not a function.
|
|
21
30
|
*/
|
|
22
|
-
public validateListener(listener:
|
|
31
|
+
public validateListener(listener: SignalListener, fnName: string): void {
|
|
23
32
|
if (typeof listener !== 'function') {
|
|
24
33
|
throw new TypeError(
|
|
25
34
|
'Signal: listener is a required param of {fn}() and should be a Function.'.replace('{fn}', fnName)
|
|
@@ -38,11 +47,11 @@ export class Signal {
|
|
|
38
47
|
* @throws {Error} If the listener is already registered with a different once setting.
|
|
39
48
|
*/
|
|
40
49
|
public _registerListener(
|
|
41
|
-
listener:
|
|
50
|
+
listener: SignalListener,
|
|
42
51
|
isOnce = false,
|
|
43
|
-
listenerContext: unknown
|
|
52
|
+
listenerContext: unknown = null,
|
|
44
53
|
priority = 0,
|
|
45
|
-
args:
|
|
54
|
+
args: unknown[] | null = null
|
|
46
55
|
): SignalBinding {
|
|
47
56
|
const prevIndex = this._indexOfListener(listener, listenerContext);
|
|
48
57
|
let binding;
|
|
@@ -86,7 +95,7 @@ export class Signal {
|
|
|
86
95
|
* @param {object} context - The context of the listener.
|
|
87
96
|
* @returns {number} The index of the listener in the bindings array, or -1 if not found.
|
|
88
97
|
*/
|
|
89
|
-
public _indexOfListener(listener:
|
|
98
|
+
public _indexOfListener(listener: SignalListener, context: unknown = null): number {
|
|
90
99
|
if (!this._bindings) {
|
|
91
100
|
return -1;
|
|
92
101
|
}
|
|
@@ -108,7 +117,7 @@ export class Signal {
|
|
|
108
117
|
* @param {object} context - The context of the listener.
|
|
109
118
|
* @returns {boolean} True if the listener is registered, false otherwise.
|
|
110
119
|
*/
|
|
111
|
-
public has(listener:
|
|
120
|
+
public has(listener: SignalListener, context: unknown = null): boolean {
|
|
112
121
|
return this._indexOfListener(listener, context) !== -1;
|
|
113
122
|
}
|
|
114
123
|
|
|
@@ -121,8 +130,8 @@ export class Signal {
|
|
|
121
130
|
* @returns {SignalBinding} The binding for this listener.
|
|
122
131
|
*/
|
|
123
132
|
public add(
|
|
124
|
-
listener:
|
|
125
|
-
listenerContext: unknown
|
|
133
|
+
listener: SignalListener,
|
|
134
|
+
listenerContext: unknown = null,
|
|
126
135
|
priority = 0,
|
|
127
136
|
...args: unknown[]
|
|
128
137
|
): SignalBinding {
|
|
@@ -139,8 +148,8 @@ export class Signal {
|
|
|
139
148
|
* @returns {SignalBinding} The binding for this listener.
|
|
140
149
|
*/
|
|
141
150
|
public addOnce(
|
|
142
|
-
listener:
|
|
143
|
-
listenerContext: unknown
|
|
151
|
+
listener: SignalListener,
|
|
152
|
+
listenerContext: unknown = null,
|
|
144
153
|
priority = 0,
|
|
145
154
|
...args: unknown[]
|
|
146
155
|
): SignalBinding {
|
|
@@ -154,7 +163,7 @@ export class Signal {
|
|
|
154
163
|
* @param {object} context - The context of the listener.
|
|
155
164
|
* @returns {Function} The removed listener function.
|
|
156
165
|
*/
|
|
157
|
-
public remove(listener:
|
|
166
|
+
public remove(listener: SignalListener, context: unknown = null): SignalListener {
|
|
158
167
|
this.validateListener(listener, 'remove');
|
|
159
168
|
const i = this._indexOfListener(listener, context);
|
|
160
169
|
if (i !== -1 && this._bindings) {
|
|
@@ -267,9 +276,8 @@ export class Signal {
|
|
|
267
276
|
* @returns {Function} A function that will dispatch the signal with the correct context.
|
|
268
277
|
*/
|
|
269
278
|
public get boundDispatch() {
|
|
270
|
-
const _this = this;
|
|
271
279
|
this._boundDispatch ??= (...rest: unknown[]): void => {
|
|
272
|
-
|
|
280
|
+
this.dispatch(...rest);
|
|
273
281
|
};
|
|
274
282
|
return this._boundDispatch;
|
|
275
283
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import type { Signal } from './signal.js';
|
|
1
|
+
import type { DispatchedListener, Signal, SignalListener } from './signal.js';
|
|
2
2
|
export class SignalBinding {
|
|
3
|
-
public _signal:
|
|
4
|
-
public _listener:
|
|
5
|
-
public _args:
|
|
3
|
+
public _signal: Signal | null;
|
|
4
|
+
public _listener: SignalListener | null;
|
|
5
|
+
public _args: unknown[] | null;
|
|
6
6
|
public _priority: number;
|
|
7
7
|
public _isOnce: boolean;
|
|
8
8
|
public context: unknown;
|
|
9
9
|
public callCount: number;
|
|
10
10
|
public active: boolean;
|
|
11
|
-
public params:
|
|
11
|
+
public params: unknown[] | null;
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* TBD.
|
|
@@ -21,11 +21,11 @@ export class SignalBinding {
|
|
|
21
21
|
*/
|
|
22
22
|
public constructor(
|
|
23
23
|
signal: Signal,
|
|
24
|
-
listener:
|
|
24
|
+
listener: SignalListener,
|
|
25
25
|
isOnce = false,
|
|
26
|
-
listenerContext: unknown
|
|
26
|
+
listenerContext: unknown = null,
|
|
27
27
|
priority = 0,
|
|
28
|
-
args:
|
|
28
|
+
args: unknown[] | null = null
|
|
29
29
|
) {
|
|
30
30
|
this._signal = signal;
|
|
31
31
|
this._listener = listener;
|
|
@@ -43,15 +43,14 @@ export class SignalBinding {
|
|
|
43
43
|
* @param {any[]} paramsArr - TBD.
|
|
44
44
|
* @returns {Function} TBD.
|
|
45
45
|
*/
|
|
46
|
-
public execute(paramsArr:
|
|
46
|
+
public execute(paramsArr: unknown[]): unknown {
|
|
47
47
|
let handlerReturn;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
params = this.params ? this.params.concat(paramsArr) : paramsArr;
|
|
48
|
+
if (this.active && this._listener) {
|
|
49
|
+
let params = this.params ? [...this.params, ...paramsArr] : paramsArr;
|
|
51
50
|
if (this._args) {
|
|
52
|
-
params = params
|
|
51
|
+
params = [...params, ...this._args];
|
|
53
52
|
}
|
|
54
|
-
handlerReturn = this._listener.apply(this.context, params);
|
|
53
|
+
handlerReturn = (this._listener as DispatchedListener).apply(this.context, params);
|
|
55
54
|
this.callCount += 1;
|
|
56
55
|
if (this._isOnce) {
|
|
57
56
|
this.detach();
|
|
@@ -64,8 +63,8 @@ export class SignalBinding {
|
|
|
64
63
|
* TBD.
|
|
65
64
|
* @returns {Function} TBD.
|
|
66
65
|
*/
|
|
67
|
-
public detach() {
|
|
68
|
-
return this.isBound() ? this._signal
|
|
66
|
+
public detach(): SignalListener | null {
|
|
67
|
+
return this.isBound() ? this._signal!.remove(this._listener!, this.context) : null;
|
|
69
68
|
}
|
|
70
69
|
|
|
71
70
|
/**
|
|
@@ -88,7 +87,7 @@ export class SignalBinding {
|
|
|
88
87
|
* TBD.
|
|
89
88
|
* @returns {Function} TBD.
|
|
90
89
|
*/
|
|
91
|
-
public getListener() {
|
|
90
|
+
public getListener(): SignalListener | null {
|
|
92
91
|
return this._listener;
|
|
93
92
|
}
|
|
94
93
|
|
|
@@ -96,7 +95,7 @@ export class SignalBinding {
|
|
|
96
95
|
* TBD.
|
|
97
96
|
* @returns {Signal} TBD.
|
|
98
97
|
*/
|
|
99
|
-
public getSignal() {
|
|
98
|
+
public getSignal(): Signal | null {
|
|
100
99
|
return this._signal;
|
|
101
100
|
}
|
|
102
101
|
|
|
@@ -104,9 +103,9 @@ export class SignalBinding {
|
|
|
104
103
|
* TBD.
|
|
105
104
|
*/
|
|
106
105
|
public _destroy(): void {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
this._signal = null;
|
|
107
|
+
this._listener = null;
|
|
108
|
+
this.context = null;
|
|
110
109
|
}
|
|
111
110
|
|
|
112
111
|
/**
|
package/src/phaser/core/sound.ts
CHANGED
|
@@ -70,7 +70,6 @@ export class Sound {
|
|
|
70
70
|
* @param {boolean} connect - Whether to connect to the master gain node.
|
|
71
71
|
*/
|
|
72
72
|
public constructor(game: Game, key: string, volume = 1, loop = false, connect: boolean | null = null) {
|
|
73
|
-
// TODO
|
|
74
73
|
// https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Migrating_from_webkitAudioContext
|
|
75
74
|
connect ??= game.sound.connectToMaster;
|
|
76
75
|
this.game = game;
|
|
@@ -173,8 +172,7 @@ export class Sound {
|
|
|
173
172
|
/**
|
|
174
173
|
* Handler for when the sound ends.
|
|
175
174
|
*/
|
|
176
|
-
public onEndedHandler(): void {
|
|
177
|
-
this._sound.onended = null;
|
|
175
|
+
public onEndedHandler = (): void => {
|
|
178
176
|
this.isPlaying = false;
|
|
179
177
|
this.currentTime = this.durationMS;
|
|
180
178
|
this.stop();
|
|
@@ -202,7 +200,7 @@ export class Sound {
|
|
|
202
200
|
this.onMarkerComplete.dispose();
|
|
203
201
|
this.onFadeComplete.dispose();
|
|
204
202
|
}
|
|
205
|
-
}
|
|
203
|
+
};
|
|
206
204
|
|
|
207
205
|
/**
|
|
208
206
|
* Updates the sound state.
|
|
@@ -341,7 +339,7 @@ export class Sound {
|
|
|
341
339
|
this._sound.loop = true;
|
|
342
340
|
}
|
|
343
341
|
if (!this.loop && marker === '') {
|
|
344
|
-
this._sound.
|
|
342
|
+
this._sound.addEventListener('ended', this.onEndedHandler, { once: true });
|
|
345
343
|
}
|
|
346
344
|
this.totalDuration = this._sound.buffer?.duration ?? 0;
|
|
347
345
|
if (this.duration === 0) {
|
|
@@ -364,7 +362,7 @@ export class Sound {
|
|
|
364
362
|
} else {
|
|
365
363
|
this.pendingPlayback = true;
|
|
366
364
|
if (this.game.cache.getSound(this.key)?.isDecoding === false) {
|
|
367
|
-
this.game.sound.decode(this.key);
|
|
365
|
+
void this.game.sound.decode(this.key);
|
|
368
366
|
}
|
|
369
367
|
}
|
|
370
368
|
return this;
|
|
@@ -412,7 +410,7 @@ export class Sound {
|
|
|
412
410
|
this._sound.loop = true;
|
|
413
411
|
}
|
|
414
412
|
if (!this.loop && this.currentMarker === '') {
|
|
415
|
-
this._sound.
|
|
413
|
+
this._sound.addEventListener('ended', this.onEndedHandler, { once: true });
|
|
416
414
|
}
|
|
417
415
|
const duration = this.duration - this.pausedPosition / 1000;
|
|
418
416
|
if (this._sound.start === undefined) {
|
|
@@ -540,12 +538,12 @@ export class Sound {
|
|
|
540
538
|
/**
|
|
541
539
|
* Sets the muted state of the sound.
|
|
542
540
|
*/
|
|
543
|
-
public set mute(value) {
|
|
544
|
-
|
|
545
|
-
if (
|
|
541
|
+
public set mute(value: boolean | null) {
|
|
542
|
+
const muted = value ?? false;
|
|
543
|
+
if (muted === this._muted) {
|
|
546
544
|
return;
|
|
547
545
|
}
|
|
548
|
-
if (
|
|
546
|
+
if (muted) {
|
|
549
547
|
this._muted = true;
|
|
550
548
|
this._muteVolume = this._tempVolume;
|
|
551
549
|
this.gainNode.gain.value = 0;
|
|
@@ -11,6 +11,7 @@ import { ENGINE_ERROR_CREATING_AUDIO_CONTEXT } from './error_code.js';
|
|
|
11
11
|
import { Signal } from './signal.js';
|
|
12
12
|
import { Sound } from './sound.js';
|
|
13
13
|
import { SoundSprite } from './sound_sprite.js';
|
|
14
|
+
import type { Callback } from './callback.js';
|
|
14
15
|
|
|
15
16
|
export class SoundManager {
|
|
16
17
|
public game!: Game;
|
|
@@ -28,7 +29,7 @@ export class SoundManager {
|
|
|
28
29
|
public _sounds!: Sound[];
|
|
29
30
|
public _watchList!: ArraySet;
|
|
30
31
|
public _watching!: boolean;
|
|
31
|
-
public _watchCallback!:
|
|
32
|
+
public _watchCallback!: Callback | null;
|
|
32
33
|
public _watchContext!: unknown;
|
|
33
34
|
public masterGain!: GainNode;
|
|
34
35
|
public _muteVolume!: number;
|
|
@@ -83,10 +84,11 @@ export class SoundManager {
|
|
|
83
84
|
const typedError = error instanceof Error ? error : new Error(String(error));
|
|
84
85
|
this.game.logger.fatal('SoundManager', { error: typedError });
|
|
85
86
|
}
|
|
86
|
-
} else if (
|
|
87
|
+
} else if (globalThis.webkitAudioContext) {
|
|
87
88
|
try {
|
|
88
89
|
this.game.logger.info('initWebkitAudioContext');
|
|
89
|
-
|
|
90
|
+
const WebkitAudioContext = globalThis.webkitAudioContext;
|
|
91
|
+
this.context = new WebkitAudioContext();
|
|
90
92
|
this.type = AUDIO_WEBKIT;
|
|
91
93
|
} catch (error) {
|
|
92
94
|
this.context = null;
|
|
@@ -101,11 +103,10 @@ export class SoundManager {
|
|
|
101
103
|
return;
|
|
102
104
|
}
|
|
103
105
|
this.baseLatency = this.context.baseLatency ?? 256 / (this.context.sampleRate ?? 44_100);
|
|
104
|
-
|
|
105
|
-
this.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
106
|
+
this.masterGain =
|
|
107
|
+
this.context.createGain === undefined
|
|
108
|
+
? (this.context as unknown as { createGainNode: () => GainNode }).createGainNode()
|
|
109
|
+
: this.context.createGain();
|
|
109
110
|
this.masterGain.gain.value = 1;
|
|
110
111
|
this.masterGain.connect(this.context.destination);
|
|
111
112
|
// handle audio state unlock
|
|
@@ -185,6 +186,14 @@ export class SoundManager {
|
|
|
185
186
|
* @param {Event} event - The DOM event that triggered the unlock.
|
|
186
187
|
*/
|
|
187
188
|
public onUnlockEvent = (event: Event): void => {
|
|
189
|
+
void this.resumeContext(event);
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Resumes the audio context a user gesture has just unlocked.
|
|
194
|
+
* @param {Event} event - The DOM event that triggered the unlock.
|
|
195
|
+
*/
|
|
196
|
+
public async resumeContext(event: Event): Promise<void> {
|
|
188
197
|
const initialState = this.context!.state;
|
|
189
198
|
if (initialState !== 'suspended' && initialState !== 'interrupted') {
|
|
190
199
|
this.game.logger.info('onUnlockResumeDenied', {
|
|
@@ -200,29 +209,28 @@ export class SoundManager {
|
|
|
200
209
|
isLocked: this.isLocked,
|
|
201
210
|
event,
|
|
202
211
|
});
|
|
203
|
-
|
|
204
|
-
.
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
});
|
|
210
|
-
this.removeUnlockHandlers();
|
|
211
|
-
})
|
|
212
|
-
.catch((error: unknown): void => {
|
|
213
|
-
this.game.logger.info('onContextResumeReject', {
|
|
214
|
-
initialState,
|
|
215
|
-
state: this.context!.state,
|
|
216
|
-
isLocked: this.isLocked,
|
|
217
|
-
error,
|
|
218
|
-
});
|
|
219
|
-
this.removeUnlockHandlers();
|
|
220
|
-
this.game.logger.fatal('SoundManager', {
|
|
221
|
-
error,
|
|
222
|
-
tags: { 'audio.initialState': initialState, 'audio.state': this.context!.state },
|
|
223
|
-
});
|
|
212
|
+
try {
|
|
213
|
+
await this.context!.resume();
|
|
214
|
+
this.game.logger.info('onContextResumeResult', {
|
|
215
|
+
initialState,
|
|
216
|
+
state: this.context!.state,
|
|
217
|
+
isLocked: this.isLocked,
|
|
224
218
|
});
|
|
225
|
-
|
|
219
|
+
this.removeUnlockHandlers();
|
|
220
|
+
} catch (error: unknown) {
|
|
221
|
+
this.game.logger.info('onContextResumeReject', {
|
|
222
|
+
initialState,
|
|
223
|
+
state: this.context!.state,
|
|
224
|
+
isLocked: this.isLocked,
|
|
225
|
+
error,
|
|
226
|
+
});
|
|
227
|
+
this.removeUnlockHandlers();
|
|
228
|
+
this.game.logger.fatal('SoundManager', {
|
|
229
|
+
error,
|
|
230
|
+
tags: { 'audio.initialState': initialState, 'audio.state': this.context!.state },
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
226
234
|
|
|
227
235
|
/**
|
|
228
236
|
* Stops all sounds in the manager.
|
|
@@ -270,7 +278,7 @@ export class SoundManager {
|
|
|
270
278
|
* Decodes an audio file for playback.
|
|
271
279
|
* @param {string} key - The key of the sound to decode.
|
|
272
280
|
*/
|
|
273
|
-
public decode(key: string): void {
|
|
281
|
+
public async decode(key: string): Promise<void> {
|
|
274
282
|
const soundData = this.game.cache.getSoundData(key);
|
|
275
283
|
if (!(soundData instanceof ArrayBuffer)) {
|
|
276
284
|
return;
|
|
@@ -279,21 +287,19 @@ export class SoundManager {
|
|
|
279
287
|
return;
|
|
280
288
|
}
|
|
281
289
|
this.game.cache.updateSound(key, 'isDecoding', true);
|
|
282
|
-
|
|
283
|
-
.
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
.
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
296
|
-
});
|
|
290
|
+
try {
|
|
291
|
+
this.game.cache.decodedSound(key, await this.context!.decodeAudioData(soundData));
|
|
292
|
+
} catch (error: unknown) {
|
|
293
|
+
const typedError = error instanceof Error ? error : new Error(String(error));
|
|
294
|
+
this.game.logger.fatal('SoundManager', { error: typedError, tags: { 'asset.key': key } });
|
|
295
|
+
if (typedError.name === 'InvalidStateError') {
|
|
296
|
+
addPageLifecycleCallback(PAGE_LIFECYCLE_STATE_ACTIVE, (): void => {
|
|
297
|
+
void this.decode(key);
|
|
298
|
+
});
|
|
299
|
+
} else if (typedError.name === 'EncodingError') {
|
|
300
|
+
this._watchList.remove(key);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
297
303
|
}
|
|
298
304
|
|
|
299
305
|
/**
|
|
@@ -304,7 +310,7 @@ export class SoundManager {
|
|
|
304
310
|
*/
|
|
305
311
|
public setDecodedCallback(
|
|
306
312
|
files: string | string[] | Sound | Sound[],
|
|
307
|
-
callback:
|
|
313
|
+
callback: Callback,
|
|
308
314
|
callbackContext: unknown
|
|
309
315
|
): void {
|
|
310
316
|
const candidates: (string | Sound)[] = typeof files === 'string' ? [files] : Array.isArray(files) ? files : [files];
|