@vpmedia/phaser 1.119.0 → 1.121.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 +2 -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 +12 -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 +8 -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 +2 -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 +14 -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 +30 -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
|
@@ -11,12 +11,13 @@ import {
|
|
|
11
11
|
POINTER_CURSOR,
|
|
12
12
|
TOUCH_OVERRIDES_MOUSE,
|
|
13
13
|
} from './const.js';
|
|
14
|
+
import type { AppliedCallback, Callback } from './callback.js';
|
|
14
15
|
|
|
15
16
|
/** A callback deferred until the click that triggered it has finished dispatching. */
|
|
16
17
|
export type ClickTrampoline = {
|
|
17
18
|
name: string;
|
|
18
19
|
targetObject: InputHandler | null;
|
|
19
|
-
callback:
|
|
20
|
+
callback: Callback;
|
|
20
21
|
callbackContext: unknown;
|
|
21
22
|
callbackArgs: unknown[];
|
|
22
23
|
};
|
|
@@ -281,7 +282,7 @@ export class Pointer {
|
|
|
281
282
|
while (i) {
|
|
282
283
|
i -= 1;
|
|
283
284
|
const moveCallback = input.moveCallbacks[i]!;
|
|
284
|
-
moveCallback.callback.call(moveCallback.context, this, this.x, this.y, fromClick);
|
|
285
|
+
(moveCallback.callback as AppliedCallback).call(moveCallback.context, this, this.x, this.y, fromClick);
|
|
285
286
|
}
|
|
286
287
|
// Easy out if we're dragging something and it still exists
|
|
287
288
|
if (this.targetObject !== null && this.targetObject.isDragged) {
|
|
@@ -331,26 +332,26 @@ export class Pointer {
|
|
|
331
332
|
// (A node that was previously checked did not request a pixel-perfect check.)
|
|
332
333
|
currentNode = this.game.input.interactiveItems.first;
|
|
333
334
|
while (currentNode) {
|
|
334
|
-
if (
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
335
|
+
if (
|
|
336
|
+
!currentNode.checked &&
|
|
337
|
+
currentNode.validForInput(highestInputPriorityID, highestRenderOrderID, true) &&
|
|
338
|
+
((fromClick && currentNode.checkPointerDown(this, false)) ||
|
|
339
|
+
(!fromClick && currentNode.checkPointerOver(this, false)))
|
|
340
|
+
) {
|
|
341
|
+
highestRenderOrderID = currentNode.sprite.renderOrderID;
|
|
342
|
+
highestInputPriorityID = currentNode.priorityID;
|
|
343
|
+
candidateTarget = currentNode;
|
|
344
|
+
this.interactiveCandidates.push(currentNode);
|
|
344
345
|
}
|
|
345
346
|
currentNode = this.game.input.interactiveItems.next;
|
|
346
347
|
}
|
|
347
348
|
if (this.game.input.customCandidateHandler) {
|
|
348
|
-
candidateTarget = this.game.input.customCandidateHandler.call(
|
|
349
|
+
candidateTarget = (this.game.input.customCandidateHandler as AppliedCallback).call(
|
|
349
350
|
this.game.input.customCandidateHandlerContext,
|
|
350
351
|
this,
|
|
351
352
|
this.interactiveCandidates,
|
|
352
353
|
candidateTarget
|
|
353
|
-
);
|
|
354
|
+
) as InputHandler | null;
|
|
354
355
|
}
|
|
355
356
|
this.swapTarget(candidateTarget, false);
|
|
356
357
|
return this.targetObject !== null;
|
|
@@ -456,8 +457,8 @@ export class Pointer {
|
|
|
456
457
|
* @returns {boolean} TBD.
|
|
457
458
|
*/
|
|
458
459
|
public justPressed(duration: number): boolean {
|
|
459
|
-
|
|
460
|
-
return this.isDown && this.timeDown +
|
|
460
|
+
const window = duration || this.game.input.justPressedRate;
|
|
461
|
+
return this.isDown && this.timeDown + window > this.game.time.time;
|
|
461
462
|
}
|
|
462
463
|
|
|
463
464
|
/**
|
|
@@ -466,8 +467,8 @@ export class Pointer {
|
|
|
466
467
|
* @returns {boolean} TBD.
|
|
467
468
|
*/
|
|
468
469
|
public justReleased(duration: number): boolean {
|
|
469
|
-
|
|
470
|
-
return this.isUp && this.timeUp +
|
|
470
|
+
const window = duration || this.game.input.justReleasedRate;
|
|
471
|
+
return this.isUp && this.timeUp + window > this.game.time.time;
|
|
471
472
|
}
|
|
472
473
|
|
|
473
474
|
/**
|
|
@@ -477,11 +478,11 @@ export class Pointer {
|
|
|
477
478
|
* @param {object} callbackContext - TBD.
|
|
478
479
|
* @param {...any} callbackArgs - TBD.
|
|
479
480
|
*/
|
|
480
|
-
public addClickTrampoline(name: string, callback:
|
|
481
|
+
public addClickTrampoline(name: string, callback: Callback, callbackContext: unknown, callbackArgs: unknown[]): void {
|
|
481
482
|
if (!this.isDown) {
|
|
482
483
|
return;
|
|
483
484
|
}
|
|
484
|
-
this._clickTrampolines
|
|
485
|
+
this._clickTrampolines ??= [];
|
|
485
486
|
const trampolines = this._clickTrampolines;
|
|
486
487
|
for (let i = 0; i < trampolines.length; i += 1) {
|
|
487
488
|
if (trampolines[i]!.name === name) {
|
|
@@ -508,7 +509,7 @@ export class Pointer {
|
|
|
508
509
|
}
|
|
509
510
|
for (const trampoline of trampolines) {
|
|
510
511
|
if (trampoline.targetObject === this._trampolineTargetObject) {
|
|
511
|
-
trampoline.callback.apply(trampoline.callbackContext, trampoline.callbackArgs);
|
|
512
|
+
(trampoline.callback as AppliedCallback).apply(trampoline.callbackContext, trampoline.callbackArgs);
|
|
512
513
|
}
|
|
513
514
|
}
|
|
514
515
|
this._clickTrampolines = null;
|
|
@@ -51,24 +51,23 @@ export class Touch {
|
|
|
51
51
|
if (!this.game.device.touch || this._onTouchStart !== null) {
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
|
-
const scope = this;
|
|
55
54
|
this._onTouchStart = (event): void => {
|
|
56
|
-
|
|
55
|
+
this.onTouchStart(event);
|
|
57
56
|
};
|
|
58
57
|
this._onTouchMove = (event): void => {
|
|
59
|
-
|
|
58
|
+
this.onTouchMove(event);
|
|
60
59
|
};
|
|
61
60
|
this._onTouchEnd = (event): void => {
|
|
62
|
-
|
|
61
|
+
this.onTouchEnd(event);
|
|
63
62
|
};
|
|
64
63
|
this._onTouchEnter = (event): void => {
|
|
65
|
-
|
|
64
|
+
this.onTouchEnter(event);
|
|
66
65
|
};
|
|
67
66
|
this._onTouchLeave = (event): void => {
|
|
68
|
-
|
|
67
|
+
this.onTouchLeave(event);
|
|
69
68
|
};
|
|
70
69
|
this._onTouchCancel = (event): void => {
|
|
71
|
-
|
|
70
|
+
this.onTouchCancel(event);
|
|
72
71
|
};
|
|
73
72
|
this.game.canvas.addEventListener('touchstart', this._onTouchStart, false);
|
|
74
73
|
this.game.canvas.addEventListener('touchmove', this._onTouchMove, false);
|
|
@@ -132,8 +131,8 @@ export class Touch {
|
|
|
132
131
|
// event.touches = list of all touches on the ENTIRE DOCUMENT, not just the target element
|
|
133
132
|
// event.changedTouches = the touches that CHANGED in this event, not the total number of them
|
|
134
133
|
const changed = event.changedTouches ?? [];
|
|
135
|
-
for (
|
|
136
|
-
this.game.input.startPointer(
|
|
134
|
+
for (const touch of changed) {
|
|
135
|
+
this.game.input.startPointer(touch);
|
|
137
136
|
}
|
|
138
137
|
}
|
|
139
138
|
|
|
@@ -153,8 +152,8 @@ export class Touch {
|
|
|
153
152
|
// Touch cancel - touches that were disrupted (perhaps by moving into a plugin or browser chrome)
|
|
154
153
|
// http://www.w3.org/TR/touch-events/#dfn-touchcancel
|
|
155
154
|
const changed = event.changedTouches ?? [];
|
|
156
|
-
for (
|
|
157
|
-
this.game.input.stopPointer(
|
|
155
|
+
for (const touch of changed) {
|
|
156
|
+
this.game.input.stopPointer(touch);
|
|
158
157
|
}
|
|
159
158
|
}
|
|
160
159
|
|
|
@@ -196,8 +195,8 @@ export class Touch {
|
|
|
196
195
|
}
|
|
197
196
|
this.eventPreventDefault(event);
|
|
198
197
|
const changed = event.changedTouches ?? [];
|
|
199
|
-
for (
|
|
200
|
-
this.game.input.updatePointer(
|
|
198
|
+
for (const touch of changed) {
|
|
199
|
+
this.game.input.updatePointer(touch);
|
|
201
200
|
}
|
|
202
201
|
}
|
|
203
202
|
|
|
@@ -215,8 +214,8 @@ export class Touch {
|
|
|
215
214
|
// https://developer.mozilla.org/en-US/docs/DOM/TouchList
|
|
216
215
|
// event.changedTouches = the touches that CHANGED in this event, not the total number of them
|
|
217
216
|
const changed = event.changedTouches ?? [];
|
|
218
|
-
for (
|
|
219
|
-
this.game.input.stopPointer(
|
|
217
|
+
for (const touch of changed) {
|
|
218
|
+
this.game.input.stopPointer(touch);
|
|
220
219
|
}
|
|
221
220
|
}
|
|
222
221
|
|
|
@@ -225,10 +224,8 @@ export class Touch {
|
|
|
225
224
|
* @param {TouchEvent} event - TBD.
|
|
226
225
|
*/
|
|
227
226
|
public eventPreventDefault(event: InputEvent): void {
|
|
228
|
-
if (this.preventDefault) {
|
|
229
|
-
|
|
230
|
-
event.preventDefault();
|
|
231
|
-
}
|
|
227
|
+
if (this.preventDefault && (typeof event.cancelable !== 'boolean' || event.cancelable)) {
|
|
228
|
+
event.preventDefault();
|
|
232
229
|
}
|
|
233
230
|
}
|
|
234
231
|
}
|
|
@@ -5,6 +5,7 @@ import type { Cache } from './cache.js';
|
|
|
5
5
|
import type { Game } from './game.js';
|
|
6
6
|
import type { Image } from '../display/image.js';
|
|
7
7
|
import { Signal } from './signal.js';
|
|
8
|
+
import type { AppliedCallback, Callback } from './callback.js';
|
|
8
9
|
|
|
9
10
|
const TEXTURE_ATLAS_JSON_HASH = 1;
|
|
10
11
|
|
|
@@ -163,13 +164,8 @@ export class Loader {
|
|
|
163
164
|
height: sprite.height,
|
|
164
165
|
rect: null,
|
|
165
166
|
};
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
this.preloadSprite.rect = new Rectangle(0, 0, 1, sprite.height);
|
|
169
|
-
} else {
|
|
170
|
-
// Vertical rect
|
|
171
|
-
this.preloadSprite.rect = new Rectangle(0, 0, sprite.width, 1);
|
|
172
|
-
}
|
|
167
|
+
this.preloadSprite.rect =
|
|
168
|
+
direction === 0 ? new Rectangle(0, 0, 1, sprite.height) : new Rectangle(0, 0, sprite.width, 1);
|
|
173
169
|
sprite.crop(this.preloadSprite.rect);
|
|
174
170
|
sprite.visible = true;
|
|
175
171
|
}
|
|
@@ -585,10 +581,10 @@ export class Loader {
|
|
|
585
581
|
* @param {object} callbackContext - The context in which to call the callback.
|
|
586
582
|
* @returns {Loader} This Loader instance for chaining.
|
|
587
583
|
*/
|
|
588
|
-
public withSyncPoint(callback:
|
|
584
|
+
public withSyncPoint(callback: Callback, callbackContext: unknown): this {
|
|
589
585
|
this._withSyncPointDepth += 1;
|
|
590
586
|
try {
|
|
591
|
-
callback.call(callbackContext ?? this, this);
|
|
587
|
+
(callback as AppliedCallback).call(callbackContext ?? this, this);
|
|
592
588
|
} finally {
|
|
593
589
|
this._withSyncPointDepth -= 1;
|
|
594
590
|
}
|
|
@@ -616,10 +612,8 @@ export class Loader {
|
|
|
616
612
|
*/
|
|
617
613
|
public removeFile(type: string, key: string): void {
|
|
618
614
|
const asset = this.getAsset(type, key);
|
|
619
|
-
if (asset) {
|
|
620
|
-
|
|
621
|
-
this._fileList.splice(asset.index, 1);
|
|
622
|
-
}
|
|
615
|
+
if (asset && !asset.file.loaded && !asset.file.loading) {
|
|
616
|
+
this._fileList.splice(asset.index, 1);
|
|
623
617
|
}
|
|
624
618
|
}
|
|
625
619
|
|
|
@@ -735,9 +729,8 @@ export class Loader {
|
|
|
735
729
|
// Flight queue is empty but file list is not done being processed.
|
|
736
730
|
// This indicates a critical internal error with no known recovery.
|
|
737
731
|
this.game.logger.warn('Aborting: processing queue empty, loading may have stalled');
|
|
738
|
-
const scope = this;
|
|
739
732
|
setTimeout((): void => {
|
|
740
|
-
|
|
733
|
+
this.finishedLoading(true);
|
|
741
734
|
}, 2000);
|
|
742
735
|
}
|
|
743
736
|
}
|
|
@@ -929,32 +922,34 @@ export class Loader {
|
|
|
929
922
|
*/
|
|
930
923
|
public loadImageTag(file: LoaderFile): void {
|
|
931
924
|
this.log('loadImageTag', file);
|
|
932
|
-
const scope = this;
|
|
933
925
|
const image = new globalThis.Image();
|
|
934
926
|
file.data = image;
|
|
935
|
-
image.
|
|
927
|
+
image.dataset['key'] = file.key;
|
|
936
928
|
if (typeof this.crossOrigin === 'string' && this.crossOrigin) {
|
|
937
929
|
image.crossOrigin = this.crossOrigin;
|
|
938
930
|
}
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
931
|
+
let settled = false;
|
|
932
|
+
image.addEventListener(
|
|
933
|
+
'load',
|
|
934
|
+
(): void => {
|
|
935
|
+
if (!settled) {
|
|
936
|
+
settled = true;
|
|
937
|
+
this.fileComplete(file);
|
|
938
|
+
}
|
|
939
|
+
},
|
|
940
|
+
{ once: true }
|
|
941
|
+
);
|
|
942
|
+
image.addEventListener('error', (): void => {
|
|
943
|
+
if (this.isUseRetry && (!file.numRetry || file.numRetry < this.maxRetry)) {
|
|
948
944
|
setTimeout((): void => {
|
|
949
|
-
file.numRetry =
|
|
950
|
-
|
|
945
|
+
file.numRetry = file.numRetry ? file.numRetry + 1 : 1;
|
|
946
|
+
this.loadImageTag(file);
|
|
951
947
|
}, 1000);
|
|
952
|
-
} else if (
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
scope.fileError(file);
|
|
948
|
+
} else if (!settled) {
|
|
949
|
+
settled = true;
|
|
950
|
+
this.fileError(file);
|
|
956
951
|
}
|
|
957
|
-
};
|
|
952
|
+
});
|
|
958
953
|
const src = this.transformUrl(file.url, file);
|
|
959
954
|
if (src === false) {
|
|
960
955
|
this.fileError(file, null, 'Could not resolve the file URL');
|
|
@@ -975,15 +970,14 @@ export class Loader {
|
|
|
975
970
|
file: LoaderFile,
|
|
976
971
|
url: string | false,
|
|
977
972
|
type: XMLHttpRequestResponseType,
|
|
978
|
-
onload:
|
|
979
|
-
onerror:
|
|
973
|
+
onload: Callback,
|
|
974
|
+
onerror: Callback | null = null
|
|
980
975
|
): void {
|
|
981
976
|
if (url === false) {
|
|
982
977
|
this.fileError(file, null, 'Could not resolve the file URL');
|
|
983
978
|
return;
|
|
984
979
|
}
|
|
985
980
|
this.log('xhrLoad', file);
|
|
986
|
-
const scope = this;
|
|
987
981
|
const xhr = new XMLHttpRequest();
|
|
988
982
|
xhr.open('GET', url, true);
|
|
989
983
|
xhr.responseType = type;
|
|
@@ -995,53 +989,51 @@ export class Loader {
|
|
|
995
989
|
if (acceptHeader) {
|
|
996
990
|
xhr.setRequestHeader('Accept', acceptHeader);
|
|
997
991
|
}
|
|
998
|
-
|
|
999
|
-
|
|
992
|
+
const handleError = onerror ?? this.fileError;
|
|
993
|
+
const retry = (): boolean => {
|
|
994
|
+
if (!this.isUseRetry || (file.numRetry && file.numRetry >= this.maxRetry)) {
|
|
995
|
+
return false;
|
|
996
|
+
}
|
|
997
|
+
setTimeout((): void => {
|
|
998
|
+
file.numRetry = file.numRetry ? file.numRetry + 1 : 1;
|
|
999
|
+
this.xhrLoad(file, url, type, onload, handleError);
|
|
1000
|
+
}, 1000);
|
|
1001
|
+
return true;
|
|
1002
|
+
};
|
|
1003
|
+
const reportException = (error: unknown): void => {
|
|
1004
|
+
const typedError = error instanceof Error ? error : new Error(String(error));
|
|
1005
|
+
// If this was the last file in the queue and an error is thrown in the create method
|
|
1006
|
+
// then it's caught here, so be sure we don't carry on processing it
|
|
1007
|
+
if (this.hasLoaded) {
|
|
1008
|
+
this.game.logger.fatal('Loader', { error: typedError });
|
|
1009
|
+
} else {
|
|
1010
|
+
this.asyncComplete(file, typedError.message || 'Exception');
|
|
1011
|
+
}
|
|
1012
|
+
};
|
|
1013
|
+
xhr.addEventListener('load', (): void => {
|
|
1000
1014
|
try {
|
|
1015
|
+
// Handle HTTP status codes of 4xx and 5xx as errors, even if xhr.onerror was not called.
|
|
1001
1016
|
if (xhr.readyState === 4 && xhr.status >= 400 && xhr.status <= 599) {
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
setTimeout((): void => {
|
|
1005
|
-
file.numRetry = !file.numRetry ? 1 : (file.numRetry += 1);
|
|
1006
|
-
scope.xhrLoad(file, url, type, onload, onerror);
|
|
1007
|
-
}, 1000);
|
|
1008
|
-
return null;
|
|
1017
|
+
if (!retry()) {
|
|
1018
|
+
(handleError as AppliedCallback).call(this, file, xhr);
|
|
1009
1019
|
}
|
|
1010
|
-
return
|
|
1020
|
+
return;
|
|
1011
1021
|
}
|
|
1012
|
-
|
|
1022
|
+
(onload as AppliedCallback).call(this, file, xhr);
|
|
1013
1023
|
} catch (error) {
|
|
1014
|
-
|
|
1015
|
-
// If this was the last file in the queue and an error is thrown in the create method
|
|
1016
|
-
// then it's caught here, so be sure we don't carry on processing it
|
|
1017
|
-
if (!scope.hasLoaded) {
|
|
1018
|
-
scope.asyncComplete(file, typedError.message || 'Exception');
|
|
1019
|
-
} else {
|
|
1020
|
-
scope.game.logger.fatal('Loader', { error: typedError });
|
|
1021
|
-
}
|
|
1024
|
+
reportException(error);
|
|
1022
1025
|
}
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
setTimeout((): void => {
|
|
1028
|
-
file.numRetry = !file.numRetry ? 1 : (file.numRetry += 1);
|
|
1029
|
-
scope.xhrLoad(file, url, type, onload, onerror);
|
|
1030
|
-
}, 1000);
|
|
1031
|
-
} else {
|
|
1032
|
-
try {
|
|
1033
|
-
return onerror.call(scope, file, xhr);
|
|
1034
|
-
} catch (error) {
|
|
1035
|
-
const typedError = error instanceof Error ? error : new Error(String(error));
|
|
1036
|
-
if (!scope.hasLoaded) {
|
|
1037
|
-
scope.asyncComplete(file, typedError.message || 'Exception');
|
|
1038
|
-
} else {
|
|
1039
|
-
scope.game.logger.fatal('Loader', { error: typedError });
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
1026
|
+
});
|
|
1027
|
+
xhr.addEventListener('error', (): void => {
|
|
1028
|
+
if (retry()) {
|
|
1029
|
+
return;
|
|
1042
1030
|
}
|
|
1043
|
-
|
|
1044
|
-
|
|
1031
|
+
try {
|
|
1032
|
+
(handleError as AppliedCallback).call(this, file, xhr);
|
|
1033
|
+
} catch (error) {
|
|
1034
|
+
reportException(error);
|
|
1035
|
+
}
|
|
1036
|
+
});
|
|
1045
1037
|
file.requestObject = xhr;
|
|
1046
1038
|
file.requestUrl = url;
|
|
1047
1039
|
xhr.send();
|
|
@@ -1051,7 +1043,6 @@ export class Loader {
|
|
|
1051
1043
|
* Placeholder for XDomainRequest loading (not implemented).
|
|
1052
1044
|
*/
|
|
1053
1045
|
public xhrLoadWithXDR(): void {
|
|
1054
|
-
// TODO
|
|
1055
1046
|
this.game.logger.warn('loader.xhrLoadWithXDR() is not implemented');
|
|
1056
1047
|
}
|
|
1057
1048
|
|
|
@@ -1065,8 +1056,7 @@ export class Loader {
|
|
|
1065
1056
|
return null;
|
|
1066
1057
|
}
|
|
1067
1058
|
const candidates = typeof urls === 'string' ? [urls] : urls;
|
|
1068
|
-
for (
|
|
1069
|
-
const candidate = candidates[i]!;
|
|
1059
|
+
for (const candidate of candidates) {
|
|
1070
1060
|
let url: string;
|
|
1071
1061
|
let audioType = null;
|
|
1072
1062
|
if (typeof candidate !== 'string') {
|
|
@@ -1107,7 +1097,7 @@ export class Loader {
|
|
|
1107
1097
|
if (!reason && xhr) {
|
|
1108
1098
|
reason = xhr.status;
|
|
1109
1099
|
}
|
|
1110
|
-
const message = `Error loading asset (${reason})`;
|
|
1100
|
+
const message = `Error loading asset (${String(reason)})`;
|
|
1111
1101
|
this.asyncComplete(file, message);
|
|
1112
1102
|
}
|
|
1113
1103
|
|
|
@@ -1153,7 +1143,7 @@ export class Loader {
|
|
|
1153
1143
|
if (file.format === TEXTURE_ATLAS_JSON_HASH) {
|
|
1154
1144
|
this.xhrLoad(file, this.transformUrl(file.atlasURL, file), 'text', this.jsonLoadComplete);
|
|
1155
1145
|
} else {
|
|
1156
|
-
throw new Error(`Invalid Texture Atlas format: ${file.format}`);
|
|
1146
|
+
throw new Error(`Invalid Texture Atlas format: ${String(file.format)}`);
|
|
1157
1147
|
}
|
|
1158
1148
|
}
|
|
1159
1149
|
break;
|
|
@@ -1201,7 +1191,7 @@ export class Loader {
|
|
|
1201
1191
|
file.data = audio;
|
|
1202
1192
|
this.cache.addSound(file.key, url, audio);
|
|
1203
1193
|
if (file.autoDecode) {
|
|
1204
|
-
this.game.sound.decode(file.key);
|
|
1194
|
+
void this.game.sound.decode(file.key);
|
|
1205
1195
|
}
|
|
1206
1196
|
break;
|
|
1207
1197
|
}
|
|
@@ -1251,7 +1241,6 @@ export class Loader {
|
|
|
1251
1241
|
* TBD.
|
|
1252
1242
|
*/
|
|
1253
1243
|
public csvLoadComplete(): void {
|
|
1254
|
-
// TODO
|
|
1255
1244
|
this.game.logger.warn('loader.csvLoadComplete() is not implemented');
|
|
1256
1245
|
}
|
|
1257
1246
|
|
|
@@ -1337,13 +1326,13 @@ export class Loader {
|
|
|
1337
1326
|
/**
|
|
1338
1327
|
* Logs a message to the console if logging is enabled.
|
|
1339
1328
|
* @param {string} message - The message to log.
|
|
1340
|
-
* @param {
|
|
1329
|
+
* @param {object} file - The file the message is about.
|
|
1341
1330
|
*/
|
|
1342
|
-
public log(message: string,
|
|
1331
|
+
public log(message: string, file: LoaderFile): void {
|
|
1343
1332
|
if (!this.isUseLog) {
|
|
1344
1333
|
return;
|
|
1345
1334
|
}
|
|
1346
|
-
this.game.logger.info(message,
|
|
1335
|
+
this.game.logger.info(message, { key: file.key, type: file.type });
|
|
1347
1336
|
}
|
|
1348
1337
|
|
|
1349
1338
|
/**
|
|
@@ -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
|
};
|