@vpmedia/phaser 1.123.0 → 1.125.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.
Files changed (221) hide show
  1. package/dist/index.js +635 -623
  2. package/dist/index.js.map +1 -1
  3. package/dist/phaser/core/animation.d.ts +3 -3
  4. package/dist/phaser/core/animation.d.ts.map +1 -1
  5. package/dist/phaser/core/animation_manager.d.ts.map +1 -1
  6. package/dist/phaser/core/animation_parser.d.ts +27 -2
  7. package/dist/phaser/core/animation_parser.d.ts.map +1 -1
  8. package/dist/phaser/core/array_set.d.ts +11 -11
  9. package/dist/phaser/core/array_set.d.ts.map +1 -1
  10. package/dist/phaser/core/cache.d.ts.map +1 -1
  11. package/dist/phaser/core/callback.d.ts.map +1 -1
  12. package/dist/phaser/core/dom.d.ts +125 -19
  13. package/dist/phaser/core/dom.d.ts.map +1 -1
  14. package/dist/phaser/core/factory.d.ts +3 -2
  15. package/dist/phaser/core/factory.d.ts.map +1 -1
  16. package/dist/phaser/core/frame_data.d.ts.map +1 -1
  17. package/dist/phaser/core/input.d.ts +3 -2
  18. package/dist/phaser/core/input.d.ts.map +1 -1
  19. package/dist/phaser/core/input_handler.d.ts.map +1 -1
  20. package/dist/phaser/core/input_mouse.d.ts +5 -1
  21. package/dist/phaser/core/input_mouse.d.ts.map +1 -1
  22. package/dist/phaser/core/input_pointer.d.ts +3 -3
  23. package/dist/phaser/core/input_pointer.d.ts.map +1 -1
  24. package/dist/phaser/core/input_touch.d.ts +8 -8
  25. package/dist/phaser/core/input_touch.d.ts.map +1 -1
  26. package/dist/phaser/core/loader.d.ts +11 -2
  27. package/dist/phaser/core/loader.d.ts.map +1 -1
  28. package/dist/phaser/core/loader_parser.d.ts +14 -1
  29. package/dist/phaser/core/loader_parser.d.ts.map +1 -1
  30. package/dist/phaser/core/raf.d.ts +1 -1
  31. package/dist/phaser/core/raf.d.ts.map +1 -1
  32. package/dist/phaser/core/scale_manager.d.ts.map +1 -1
  33. package/dist/phaser/core/scene_manager.d.ts.map +1 -1
  34. package/dist/phaser/core/signal.d.ts.map +1 -1
  35. package/dist/phaser/core/sound.d.ts.map +1 -1
  36. package/dist/phaser/core/sound_manager.d.ts +1 -1
  37. package/dist/phaser/core/sound_manager.d.ts.map +1 -1
  38. package/dist/phaser/core/stage.d.ts +16 -6
  39. package/dist/phaser/core/stage.d.ts.map +1 -1
  40. package/dist/phaser/core/time.d.ts.map +1 -1
  41. package/dist/phaser/core/timer.d.ts +1 -1
  42. package/dist/phaser/core/timer.d.ts.map +1 -1
  43. package/dist/phaser/core/tween.d.ts +13 -5
  44. package/dist/phaser/core/tween.d.ts.map +1 -1
  45. package/dist/phaser/core/tween_data.d.ts +9 -7
  46. package/dist/phaser/core/tween_data.d.ts.map +1 -1
  47. package/dist/phaser/core/tween_manager.d.ts.map +1 -1
  48. package/dist/phaser/display/button.d.ts +6 -5
  49. package/dist/phaser/display/button.d.ts.map +1 -1
  50. package/dist/phaser/display/canvas/buffer.d.ts +1 -1
  51. package/dist/phaser/display/canvas/buffer.d.ts.map +1 -1
  52. package/dist/phaser/display/canvas/masker.d.ts +1 -1
  53. package/dist/phaser/display/canvas/masker.d.ts.map +1 -1
  54. package/dist/phaser/display/canvas/pool.d.ts +2 -2
  55. package/dist/phaser/display/canvas/pool.d.ts.map +1 -1
  56. package/dist/phaser/display/canvas/renderer.d.ts +9 -8
  57. package/dist/phaser/display/canvas/renderer.d.ts.map +1 -1
  58. package/dist/phaser/display/display_object.d.ts +5 -3
  59. package/dist/phaser/display/display_object.d.ts.map +1 -1
  60. package/dist/phaser/display/graphics.d.ts +1 -1
  61. package/dist/phaser/display/graphics.d.ts.map +1 -1
  62. package/dist/phaser/display/group.d.ts +1 -1
  63. package/dist/phaser/display/group.d.ts.map +1 -1
  64. package/dist/phaser/display/image.d.ts +6 -5
  65. package/dist/phaser/display/image.d.ts.map +1 -1
  66. package/dist/phaser/display/sprite_util.d.ts +3 -2
  67. package/dist/phaser/display/sprite_util.d.ts.map +1 -1
  68. package/dist/phaser/display/text.d.ts +2 -16
  69. package/dist/phaser/display/text.d.ts.map +1 -1
  70. package/dist/phaser/display/webgl/abstract_filter.d.ts +14 -8
  71. package/dist/phaser/display/webgl/abstract_filter.d.ts.map +1 -1
  72. package/dist/phaser/display/webgl/blend_manager.d.ts +2 -3
  73. package/dist/phaser/display/webgl/blend_manager.d.ts.map +1 -1
  74. package/dist/phaser/display/webgl/earcut.d.ts.map +1 -1
  75. package/dist/phaser/display/webgl/fast_sprite_batch.d.ts +11 -5
  76. package/dist/phaser/display/webgl/fast_sprite_batch.d.ts.map +1 -1
  77. package/dist/phaser/display/webgl/filter_manager.d.ts +6 -4
  78. package/dist/phaser/display/webgl/filter_manager.d.ts.map +1 -1
  79. package/dist/phaser/display/webgl/filter_texture.d.ts +4 -4
  80. package/dist/phaser/display/webgl/filter_texture.d.ts.map +1 -1
  81. package/dist/phaser/display/webgl/graphics.d.ts +2 -2
  82. package/dist/phaser/display/webgl/graphics.d.ts.map +1 -1
  83. package/dist/phaser/display/webgl/mask_manager.d.ts +3 -2
  84. package/dist/phaser/display/webgl/mask_manager.d.ts.map +1 -1
  85. package/dist/phaser/display/webgl/render_texture.d.ts +11 -8
  86. package/dist/phaser/display/webgl/render_texture.d.ts.map +1 -1
  87. package/dist/phaser/display/webgl/renderer.d.ts +8 -4
  88. package/dist/phaser/display/webgl/renderer.d.ts.map +1 -1
  89. package/dist/phaser/display/webgl/shader/normal.d.ts +28 -3
  90. package/dist/phaser/display/webgl/shader/normal.d.ts.map +1 -1
  91. package/dist/phaser/display/webgl/sprite_batch.d.ts +6 -5
  92. package/dist/phaser/display/webgl/sprite_batch.d.ts.map +1 -1
  93. package/dist/phaser/display/webgl/stencil_manager.d.ts +3 -3
  94. package/dist/phaser/display/webgl/stencil_manager.d.ts.map +1 -1
  95. package/dist/phaser/display/webgl/texture.d.ts.map +1 -1
  96. package/dist/phaser/display/webgl/texture_util.d.ts +2 -2
  97. package/dist/phaser/display/webgl/texture_util.d.ts.map +1 -1
  98. package/dist/phaser/display/webgl/util.d.ts +1 -1
  99. package/dist/phaser/display/webgl/util.d.ts.map +1 -1
  100. package/dist/phaser/geom/circle.d.ts.map +1 -1
  101. package/dist/phaser/geom/line.d.ts +10 -1
  102. package/dist/phaser/geom/line.d.ts.map +1 -1
  103. package/dist/phaser/geom/rectangle.d.ts.map +1 -1
  104. package/dist/phaser/geom/util/circle.d.ts +2 -1
  105. package/dist/phaser/geom/util/circle.d.ts.map +1 -1
  106. package/dist/phaser/geom/util/point.d.ts +1 -1
  107. package/dist/phaser/geom/util/point.d.ts.map +1 -1
  108. package/dist/phaser/geom/util/rectangle.d.ts +1 -1
  109. package/dist/phaser/geom/util/rectangle.d.ts.map +1 -1
  110. package/dist/phaser/util/math.d.ts.map +1 -1
  111. package/package.json +1 -1
  112. package/src/phaser/core/animation.ts +11 -11
  113. package/src/phaser/core/animation_manager.ts +12 -12
  114. package/src/phaser/core/animation_parser.ts +39 -37
  115. package/src/phaser/core/array_set.ts +28 -28
  116. package/src/phaser/core/cache.test.ts +33 -33
  117. package/src/phaser/core/cache.ts +7 -7
  118. package/src/phaser/core/callback.ts +1 -0
  119. package/src/phaser/core/callback_context.test.ts +8 -8
  120. package/src/phaser/core/device_util.ts +4 -4
  121. package/src/phaser/core/dom.ts +38 -24
  122. package/src/phaser/core/factory.ts +9 -2
  123. package/src/phaser/core/frame_data.test.ts +23 -23
  124. package/src/phaser/core/frame_data.ts +2 -5
  125. package/src/phaser/core/game.ts +12 -12
  126. package/src/phaser/core/input.ts +11 -10
  127. package/src/phaser/core/input_handler.test.ts +18 -18
  128. package/src/phaser/core/input_handler.ts +14 -14
  129. package/src/phaser/core/input_mouse.ts +13 -12
  130. package/src/phaser/core/input_pointer.test.ts +26 -26
  131. package/src/phaser/core/input_pointer.ts +4 -4
  132. package/src/phaser/core/input_touch.ts +8 -8
  133. package/src/phaser/core/loader.test.ts +26 -26
  134. package/src/phaser/core/loader.ts +63 -75
  135. package/src/phaser/core/loader_parser.test.ts +16 -16
  136. package/src/phaser/core/loader_parser.ts +16 -6
  137. package/src/phaser/core/raf.ts +1 -1
  138. package/src/phaser/core/registry.test.ts +6 -6
  139. package/src/phaser/core/scale_manager.ts +12 -11
  140. package/src/phaser/core/scene_manager.test.ts +30 -30
  141. package/src/phaser/core/scene_manager.ts +3 -3
  142. package/src/phaser/core/signal.test.ts +8 -8
  143. package/src/phaser/core/signal.ts +3 -3
  144. package/src/phaser/core/signal_dispatch.test.ts +30 -30
  145. package/src/phaser/core/sound.ts +45 -40
  146. package/src/phaser/core/sound_manager.ts +18 -22
  147. package/src/phaser/core/sound_sprite.ts +1 -1
  148. package/src/phaser/core/stage.ts +22 -12
  149. package/src/phaser/core/time.ts +1 -1
  150. package/src/phaser/core/timer.test.ts +47 -47
  151. package/src/phaser/core/timer.ts +2 -2
  152. package/src/phaser/core/tween.ts +34 -36
  153. package/src/phaser/core/tween_data.test.ts +119 -0
  154. package/src/phaser/core/tween_data.ts +54 -39
  155. package/src/phaser/core/tween_easing.test.ts +5 -5
  156. package/src/phaser/core/tween_manager.ts +2 -2
  157. package/src/phaser/display/bitmap_text.test.ts +30 -30
  158. package/src/phaser/display/bitmap_text.ts +3 -3
  159. package/src/phaser/display/button.ts +20 -18
  160. package/src/phaser/display/canvas/buffer.ts +2 -2
  161. package/src/phaser/display/canvas/graphics.ts +2 -2
  162. package/src/phaser/display/canvas/masker.ts +1 -1
  163. package/src/phaser/display/canvas/pool.test.ts +20 -20
  164. package/src/phaser/display/canvas/pool.ts +6 -6
  165. package/src/phaser/display/canvas/renderer.ts +18 -16
  166. package/src/phaser/display/canvas/tinter.ts +1 -1
  167. package/src/phaser/display/canvas/util.test.ts +25 -25
  168. package/src/phaser/display/canvas/util.ts +2 -2
  169. package/src/phaser/display/display_object.ts +16 -15
  170. package/src/phaser/display/graphics.test.ts +70 -20
  171. package/src/phaser/display/graphics.ts +46 -42
  172. package/src/phaser/display/group.ts +13 -12
  173. package/src/phaser/display/image.ts +35 -31
  174. package/src/phaser/display/sprite_util.ts +4 -3
  175. package/src/phaser/display/text.test.ts +28 -25
  176. package/src/phaser/display/text.ts +56 -62
  177. package/src/phaser/display/webgl/abstract_filter.ts +21 -11
  178. package/src/phaser/display/webgl/blend_manager.ts +4 -5
  179. package/src/phaser/display/webgl/earcut.test.ts +20 -20
  180. package/src/phaser/display/webgl/earcut.ts +46 -42
  181. package/src/phaser/display/webgl/fast_sprite_batch.ts +21 -16
  182. package/src/phaser/display/webgl/filter_manager.ts +7 -4
  183. package/src/phaser/display/webgl/filter_texture.ts +5 -5
  184. package/src/phaser/display/webgl/graphics.ts +3 -3
  185. package/src/phaser/display/webgl/mask_manager.ts +9 -14
  186. package/src/phaser/display/webgl/render_texture.ts +15 -14
  187. package/src/phaser/display/webgl/renderer.ts +10 -9
  188. package/src/phaser/display/webgl/shader/normal.ts +45 -35
  189. package/src/phaser/display/webgl/shader/shader.test.ts +24 -24
  190. package/src/phaser/display/webgl/shader_manager.test.ts +18 -18
  191. package/src/phaser/display/webgl/shader_manager.ts +1 -1
  192. package/src/phaser/display/webgl/sprite_batch.ts +10 -10
  193. package/src/phaser/display/webgl/stencil_manager.ts +4 -4
  194. package/src/phaser/display/webgl/texture.ts +2 -1
  195. package/src/phaser/display/webgl/texture_util.ts +2 -2
  196. package/src/phaser/display/webgl/util.ts +4 -4
  197. package/src/phaser/geom/circle.test.ts +38 -38
  198. package/src/phaser/geom/circle.ts +7 -7
  199. package/src/phaser/geom/ellipse.test.ts +12 -12
  200. package/src/phaser/geom/line.test.ts +15 -15
  201. package/src/phaser/geom/line.ts +5 -2
  202. package/src/phaser/geom/matrix.test.ts +31 -31
  203. package/src/phaser/geom/point.test.ts +31 -31
  204. package/src/phaser/geom/polygon.test.ts +27 -27
  205. package/src/phaser/geom/polygon.ts +2 -2
  206. package/src/phaser/geom/rectangle.test.ts +87 -87
  207. package/src/phaser/geom/rectangle.ts +12 -13
  208. package/src/phaser/geom/rounded_rectangle.test.ts +9 -9
  209. package/src/phaser/geom/util/circle.test.ts +5 -5
  210. package/src/phaser/geom/util/circle.ts +8 -11
  211. package/src/phaser/geom/util/ellipse.test.ts +2 -2
  212. package/src/phaser/geom/util/line.test.ts +2 -2
  213. package/src/phaser/geom/util/matrix.test.ts +4 -4
  214. package/src/phaser/geom/util/point.test.ts +2 -2
  215. package/src/phaser/geom/util/point.ts +6 -8
  216. package/src/phaser/geom/util/polygon.test.ts +2 -2
  217. package/src/phaser/geom/util/rectangle.test.ts +2 -2
  218. package/src/phaser/geom/util/rectangle.ts +1 -1
  219. package/src/phaser/geom/util/rounded_rectangle.test.ts +2 -2
  220. package/src/phaser/util/math.test.ts +41 -41
  221. package/src/phaser/util/math.ts +7 -5
@@ -83,6 +83,15 @@ export type LoaderFile = {
83
83
  ySpacing?: number;
84
84
  };
85
85
 
86
+ /** The sprite the loader crops as a progress bar, with the rectangle it crops to. */
87
+ export type PreloadSprite = {
88
+ sprite: Image;
89
+ direction: number;
90
+ width: number;
91
+ height: number;
92
+ rect: Rectangle;
93
+ };
94
+
86
95
  export class Loader {
87
96
  public game!: Game;
88
97
  public cache!: Cache;
@@ -91,7 +100,7 @@ export class Loader {
91
100
  public isUseRetry!: boolean;
92
101
  public maxRetry!: number;
93
102
  public hasLoaded!: boolean;
94
- public preloadSprite!: any;
103
+ public preloadSprite!: PreloadSprite | null;
95
104
  public crossOrigin!: boolean | string;
96
105
  public baseURL!: string;
97
106
  public path!: string;
@@ -162,10 +171,8 @@ export class Loader {
162
171
  direction,
163
172
  width: sprite.width,
164
173
  height: sprite.height,
165
- rect: null,
174
+ rect: direction === 0 ? new Rectangle(0, 0, 1, sprite.height) : new Rectangle(0, 0, sprite.width, 1),
166
175
  };
167
- this.preloadSprite.rect =
168
- direction === 0 ? new Rectangle(0, 0, 1, sprite.height) : new Rectangle(0, 0, sprite.width, 1);
169
176
  sprite.crop(this.preloadSprite.rect);
170
177
  sprite.visible = true;
171
178
  }
@@ -217,7 +224,7 @@ export class Loader {
217
224
  * @param {string} key - The key of the file to get.
218
225
  * @returns {{index: number, file: object} | null} The file and its index, or null if not found.
219
226
  */
220
- public getAsset(type: string, key: string) {
227
+ public getAsset(type: string, key: string): { index: number; file: LoaderFile } | null {
221
228
  const fileIndex = this.getAssetIndex(type, key);
222
229
  if (fileIndex > -1) {
223
230
  return { index: fileIndex, file: this._fileList[fileIndex]! };
@@ -275,19 +282,19 @@ export class Loader {
275
282
  this.game.logger.warn(`Loader: Invalid or no key given of type ${type}`);
276
283
  return this;
277
284
  }
278
- if (url === undefined || url === null) {
279
- if (extension) {
280
- url = key + extension;
281
- } else {
285
+ let resolvedUrl = url;
286
+ if (resolvedUrl === undefined || resolvedUrl === null) {
287
+ if (extension === null) {
282
288
  this.game.logger.warn(`Loader: No URL given for file type: ${type} key: ${key}`);
283
289
  return this;
284
290
  }
291
+ resolvedUrl = key + extension;
285
292
  }
286
293
  const file: LoaderFile = {
287
294
  type,
288
295
  key,
289
296
  path: this.path,
290
- url,
297
+ url: resolvedUrl,
291
298
  syncPoint: this._withSyncPointDepth > 0,
292
299
  data: null,
293
300
  loading: false,
@@ -344,11 +351,9 @@ export class Loader {
344
351
  error: false,
345
352
  callbackContext,
346
353
  };
347
- if (data) {
348
- if (typeof data === 'string') {
349
- data = JSON.parse(data);
350
- }
351
- pack.data = (data ?? {}) as LoaderFileData;
354
+ if (data !== null) {
355
+ const parsed: unknown = typeof data === 'string' ? JSON.parse(data) : data;
356
+ pack.data = (parsed ?? {}) as LoaderFileData;
352
357
  pack.loaded = true;
353
358
  }
354
359
  for (let i = 0; i < this._fileList.length + 1; i += 1) {
@@ -466,10 +471,8 @@ export class Loader {
466
471
  if (this.game.sound.noAudio || this.game.device.noAudioFormat) {
467
472
  return this;
468
473
  }
469
- if (typeof urls === 'string') {
470
- urls = [urls];
471
- }
472
- return this.addToFileList('audio', key, urls, { buffer: null, autoDecode });
474
+ const sources = typeof urls === 'string' ? [urls] : urls;
475
+ return this.addToFileList('audio', key, sources, { buffer: null, autoDecode });
473
476
  }
474
477
 
475
478
  /**
@@ -488,11 +491,9 @@ export class Loader {
488
491
  this.audio(key, urls, autoDecode);
489
492
  if (jsonURL) {
490
493
  this.json(`${key}-audioatlas`, jsonURL);
491
- } else if (jsonData) {
492
- if (typeof jsonData === 'string') {
493
- jsonData = JSON.parse(jsonData);
494
- }
495
- this.cache.addJSON(`${key}-audioatlas`, '', jsonData);
494
+ } else if (jsonData !== null) {
495
+ const parsed: unknown = typeof jsonData === 'string' ? JSON.parse(jsonData) : jsonData;
496
+ this.cache.addJSON(`${key}-audioatlas`, '', parsed);
496
497
  }
497
498
  return this;
498
499
  }
@@ -516,29 +517,27 @@ export class Loader {
516
517
  xSpacing = 0,
517
518
  ySpacing = 0
518
519
  ): this {
519
- textureURL ??= `${key}.png`;
520
- if (atlasURL === null && atlasData === null) {
521
- atlasURL = `${key}.xml`;
522
- }
520
+ const texture = textureURL ?? `${key}.png`;
521
+ const atlas = atlasURL === null && atlasData === null ? `${key}.xml` : atlasURL;
523
522
  // A URL to a json/xml atlas has been given
524
- if (atlasURL) {
525
- this.addToFileList('bitmapfont', key, textureURL, { atlasURL, xSpacing, ySpacing });
523
+ if (atlas !== null) {
524
+ this.addToFileList('bitmapfont', key, texture, { atlasURL: atlas, xSpacing, ySpacing });
526
525
  } else if (typeof atlasData === 'string') {
527
526
  // A stringified xml/json atlas has been given
528
- let json = null;
529
- let xml = null;
527
+ let json: unknown = null;
528
+ let xml: XMLDocument | null = null;
530
529
  try {
531
- json = JSON.parse(atlasData);
530
+ json = JSON.parse(atlasData) as unknown;
532
531
  } catch {
533
532
  xml = this.parseXml(atlasData);
534
533
  }
535
- if (!xml && !json) {
534
+ if (xml === null && json === null) {
536
535
  throw new Error(ENGINE_ERROR_INVALID_BITMAP_FONT_ATLAS);
537
536
  }
538
- this.addToFileList('bitmapfont', key, textureURL, {
537
+ this.addToFileList('bitmapfont', key, texture, {
539
538
  atlasURL: null,
540
539
  atlasData: json ?? xml,
541
- atlasType: json ? 'json' : 'xml',
540
+ atlasType: json === null ? 'xml' : 'json',
542
541
  xSpacing,
543
542
  ySpacing,
544
543
  });
@@ -562,15 +561,13 @@ export class Loader {
562
561
  atlasData: unknown = null,
563
562
  format: number = TEXTURE_ATLAS_JSON_HASH
564
563
  ): this {
565
- textureURL ??= `${key}.png`;
566
- if (!atlasURL && !atlasData) {
567
- atlasURL = `${key}.json`;
568
- }
564
+ const texture = textureURL ?? `${key}.png`;
565
+ const atlas = atlasURL === null && atlasData === null ? `${key}.json` : atlasURL;
569
566
  // A URL to a json/xml file has been given
570
- if (atlasURL) {
571
- this.addToFileList('textureatlas', key, textureURL, { atlasURL, format });
567
+ if (atlas !== null) {
568
+ this.addToFileList('textureatlas', key, texture, { atlasURL: atlas, format });
572
569
  } else {
573
- this.addToFileList('textureatlas', key, textureURL, { atlasURL: null, atlasData, format });
570
+ this.addToFileList('textureatlas', key, texture, { atlasURL: null, atlasData, format });
574
571
  }
575
572
  return this;
576
573
  }
@@ -694,7 +691,7 @@ export class Loader {
694
691
  }
695
692
  } else if (!file.loading && this._flightQueue.length < inflightLimit) {
696
693
  // -> not loaded/failed, not loading
697
- if (file.type === 'packfile' && !file.data) {
694
+ if (file.type === 'packfile' && file.data === null) {
698
695
  // Fetches the pack data: the pack is processed above as it reaches queue-start.
699
696
  // (Packs do not trigger onLoadStart or onFileStart.)
700
697
  this._flightQueue.push(file);
@@ -885,7 +882,7 @@ export class Loader {
885
882
  }
886
883
  case 'audio': {
887
884
  const resolved = this.getAudioURL(file.url);
888
- if (resolved) {
885
+ if (resolved !== null) {
889
886
  file.url = resolved;
890
887
  this.xhrLoad(file, this.transformUrl(resolved, file), 'arraybuffer', this.fileComplete);
891
888
  } else if (this.game.sound.noAudio) {
@@ -940,9 +937,9 @@ export class Loader {
940
937
  { once: true }
941
938
  );
942
939
  image.addEventListener('error', (): void => {
943
- if (this.isUseRetry && (!file.numRetry || file.numRetry < this.maxRetry)) {
940
+ if (this.isUseRetry && (file.numRetry === undefined || file.numRetry < this.maxRetry)) {
944
941
  setTimeout((): void => {
945
- file.numRetry = file.numRetry ? file.numRetry + 1 : 1;
942
+ file.numRetry = file.numRetry === undefined ? 1 : file.numRetry + 1;
946
943
  this.loadImageTag(file);
947
944
  }, 1000);
948
945
  } else if (!settled) {
@@ -986,16 +983,16 @@ export class Loader {
986
983
  xhr.setRequestHeader('X-Requested-With', requestedWith);
987
984
  }
988
985
  const acceptHeader = this.headers[file.type];
989
- if (acceptHeader) {
986
+ if (acceptHeader !== undefined && acceptHeader !== false) {
990
987
  xhr.setRequestHeader('Accept', acceptHeader);
991
988
  }
992
989
  const handleError = onerror ?? this.fileError;
993
990
  const retry = (): boolean => {
994
- if (!this.isUseRetry || (file.numRetry && file.numRetry >= this.maxRetry)) {
991
+ if (!this.isUseRetry || (file.numRetry !== undefined && file.numRetry >= this.maxRetry)) {
995
992
  return false;
996
993
  }
997
994
  setTimeout((): void => {
998
- file.numRetry = file.numRetry ? file.numRetry + 1 : 1;
995
+ file.numRetry = file.numRetry === undefined ? 1 : file.numRetry + 1;
999
996
  this.xhrLoad(file, url, type, onload, handleError);
1000
997
  }, 1000);
1001
998
  return true;
@@ -1094,10 +1091,8 @@ export class Loader {
1094
1091
  */
1095
1092
  public fileError(file: LoaderFile, xhr: XMLHttpRequest | null = null, reason: unknown = 0): void {
1096
1093
  // const url = file.requestUrl || this.transformUrl(file.url, file);
1097
- if (!reason && xhr) {
1098
- reason = xhr.status;
1099
- }
1100
- const message = `Error loading asset (${String(reason)})`;
1094
+ const cause = reason === 0 && xhr !== null ? xhr.status : reason;
1095
+ const message = `Error loading asset (${String(cause)})`;
1101
1096
  this.asyncComplete(file, message);
1102
1097
  }
1103
1098
 
@@ -1115,7 +1110,7 @@ export class Loader {
1115
1110
  switch (file.type) {
1116
1111
  case 'packfile': {
1117
1112
  // Pack data must never be false-ish after it is fetched without error
1118
- file.data = JSON.parse(response.responseText) ?? {};
1113
+ file.data = (JSON.parse(response.responseText) ?? {}) as LoaderFileData;
1119
1114
  break;
1120
1115
  }
1121
1116
  case 'image': {
@@ -1149,7 +1144,7 @@ export class Loader {
1149
1144
  break;
1150
1145
  }
1151
1146
  case 'bitmapfont': {
1152
- if (!file.atlasURL) {
1147
+ if (file.atlasURL === null || file.atlasURL === undefined) {
1153
1148
  this.cache.addBitmapFont(
1154
1149
  file.key,
1155
1150
  url,
@@ -1167,14 +1162,14 @@ export class Loader {
1167
1162
  this.transformUrl(file.atlasURL, file),
1168
1163
  'text',
1169
1164
  (bitmapFontFile: LoaderFile, bitmapFontXhr: XMLHttpRequest): void => {
1170
- let json;
1165
+ let json: unknown;
1171
1166
  try {
1172
1167
  // Try to parse as JSON, if it fails, then it's hopefully XML
1173
- json = JSON.parse(bitmapFontXhr.responseText);
1168
+ json = JSON.parse(bitmapFontXhr.responseText) as unknown;
1174
1169
  } catch {
1175
1170
  // pass
1176
1171
  }
1177
- if (json) {
1172
+ if (json !== undefined) {
1178
1173
  bitmapFontFile.atlasType = 'json';
1179
1174
  this.jsonLoadComplete(bitmapFontFile, bitmapFontXhr);
1180
1175
  } else {
@@ -1190,7 +1185,7 @@ export class Loader {
1190
1185
  const audio = response.response as ArrayBuffer;
1191
1186
  file.data = audio;
1192
1187
  this.cache.addSound(file.key, url, audio);
1193
- if (file.autoDecode) {
1188
+ if (file.autoDecode === true) {
1194
1189
  void this.game.sound.decode(file.key);
1195
1190
  }
1196
1191
  break;
@@ -1217,7 +1212,7 @@ export class Loader {
1217
1212
  * @param {XMLHttpRequest} xhr - The XMLHttpRequest object containing the file data.
1218
1213
  */
1219
1214
  public jsonLoadComplete(file: LoaderFile, xhr: XMLHttpRequest): void {
1220
- const data = JSON.parse(xhr.responseText);
1215
+ const data = JSON.parse(xhr.responseText) as unknown;
1221
1216
  const url = typeof file.url === 'string' ? file.url : '';
1222
1217
  if (file.type === 'bitmapfont') {
1223
1218
  this.cache.addBitmapFont(
@@ -1254,7 +1249,8 @@ export class Loader {
1254
1249
  const data = xhr.responseText;
1255
1250
  const xml = this.parseXml(data);
1256
1251
  if (!xml) {
1257
- const responseType = xhr.responseType || (xhr as any).contentType; // contentType for MS-XDomainRequest
1252
+ // contentType is the MS-XDomainRequest name for the same thing
1253
+ const responseType = xhr.responseType || (xhr as unknown as { contentType?: string }).contentType;
1258
1254
  this.game.logger.warn(`${file.key}: invalid XML (${responseType})`);
1259
1255
  this.asyncComplete(file, 'invalid XML');
1260
1256
  return;
@@ -1283,22 +1279,14 @@ export class Loader {
1283
1279
  * @param {object} data - The XML string data to parse.
1284
1280
  * @returns {Document} The parsed DOM Document, or null if parsing failed.
1285
1281
  */
1286
- public parseXml(data: string) {
1287
- let xml = null;
1282
+ public parseXml(data: string): XMLDocument | null {
1283
+ let xml: XMLDocument | null = null;
1288
1284
  try {
1289
- if (globalThis.DOMParser) {
1290
- const domparser = new DOMParser();
1291
- xml = domparser.parseFromString(data, 'text/xml');
1292
- } else {
1293
- xml = new globalThis.ActiveXObject('Microsoft.XMLDOM');
1294
- // Why is this 'false'?
1295
- xml.async = 'false';
1296
- xml.loadXML(data);
1297
- }
1285
+ xml = new DOMParser().parseFromString(data, 'text/xml');
1298
1286
  } catch {
1299
1287
  xml = null;
1300
1288
  }
1301
- if (!xml || !xml.documentElement || xml.querySelectorAll('parsererror').length > 0) {
1289
+ if (!xml?.documentElement || xml.querySelectorAll('parsererror').length > 0) {
1302
1290
  return null;
1303
1291
  }
1304
1292
  return xml;
@@ -1314,7 +1302,7 @@ export class Loader {
1314
1302
  } else {
1315
1303
  this.preloadSprite.rect.height = Math.floor((this.preloadSprite.height / 100) * this.progress);
1316
1304
  }
1317
- if (this.preloadSprite.sprite) {
1305
+ if (this.preloadSprite.sprite !== null) {
1318
1306
  this.preloadSprite.sprite.updateCrop();
1319
1307
  } else {
1320
1308
  // We seem to have lost our sprite - maybe it was destroyed?
@@ -33,64 +33,64 @@ const FONT_JSON = {
33
33
  },
34
34
  };
35
35
 
36
- describe('bitmap font parsing', () => {
37
- describe('xmlBitmapFont', () => {
38
- it('reads the font metrics', () => {
36
+ describe('bitmap font parsing', (): void => {
37
+ describe('xmlBitmapFont', (): void => {
38
+ it('reads the font metrics', (): void => {
39
39
  const data = xmlBitmapFont(parseXml(FONT_XML), baseTexture, 0, 0);
40
40
  expect(data.font).toBe('Arial');
41
41
  expect(data.size).toBe(32);
42
42
  expect(data.lineHeight).toBe(40);
43
43
  });
44
44
 
45
- it('reads every glyph, keyed by character code', () => {
45
+ it('reads every glyph, keyed by character code', (): void => {
46
46
  const data = xmlBitmapFont(parseXml(FONT_XML), baseTexture, 0, 0);
47
47
  expect(Object.keys(data.chars)).toStrictEqual(['65', '66']);
48
48
  expect(data.chars[65]).toMatchObject({ x: 0, y: 0, width: 20, height: 30, xOffset: 1, yOffset: 2 });
49
49
  });
50
50
 
51
- it('adds the spacing arguments to advance and line height', () => {
51
+ it('adds the spacing arguments to advance and line height', (): void => {
52
52
  const data = xmlBitmapFont(parseXml(FONT_XML), baseTexture, 5, 7);
53
53
  expect(data.chars[65]?.xAdvance).toBe(26);
54
54
  expect(data.lineHeight).toBe(47);
55
55
  });
56
56
 
57
- it('records kerning against the second character of the pair', () => {
57
+ it('records kerning against the second character of the pair', (): void => {
58
58
  const data = xmlBitmapFont(parseXml(FONT_XML), baseTexture, 0, 0);
59
59
  expect(data.chars[66]?.kerning[65]).toBe(-3);
60
60
  });
61
61
 
62
- it('attaches a texture to every glyph', () => {
62
+ it('attaches a texture to every glyph', (): void => {
63
63
  const data = xmlBitmapFont(parseXml(FONT_XML), baseTexture, 0, 0);
64
64
  expect(data.chars[65]?.texture).toBeDefined();
65
65
  expect(data.chars[66]?.texture).toBeDefined();
66
66
  });
67
67
 
68
- it('survives a font with no kerning table', () => {
68
+ it('survives a font with no kerning table', (): void => {
69
69
  const markup = FONT_XML.replace(/<kernings>[\s\S]*<\/kernings>/, '');
70
70
  expect(() => xmlBitmapFont(parseXml(markup), baseTexture, 0, 0)).not.toThrow();
71
71
  });
72
72
 
73
- it('ignores kerning that names a character the font does not have', () => {
73
+ it('ignores kerning that names a character the font does not have', (): void => {
74
74
  const markup = FONT_XML.replace('second="66"', 'second="999"');
75
75
  const data = xmlBitmapFont(parseXml(markup), baseTexture, 0, 0);
76
76
  expect(data.chars[66]?.kerning).toStrictEqual({});
77
77
  });
78
78
 
79
- it('falls back to an empty face when the info element is missing', () => {
79
+ it('falls back to an empty face when the info element is missing', (): void => {
80
80
  const markup = FONT_XML.replace(/<info[^>]*\/>/, '');
81
81
  expect(xmlBitmapFont(parseXml(markup), baseTexture, 0, 0).font).toBe('');
82
82
  });
83
83
  });
84
84
 
85
- describe('jsonBitmapFont', () => {
86
- it('reads the same metrics as the xml form', () => {
85
+ describe('jsonBitmapFont', (): void => {
86
+ it('reads the same metrics as the xml form', (): void => {
87
87
  const data = jsonBitmapFont(FONT_JSON, baseTexture, 0, 0);
88
88
  expect(data.font).toBe('Arial');
89
89
  expect(data.size).toBe(32);
90
90
  expect(data.lineHeight).toBe(40);
91
91
  });
92
92
 
93
- it('produces the same glyphs as the xml form', () => {
93
+ it('produces the same glyphs as the xml form', (): void => {
94
94
  const fromJson = jsonBitmapFont(FONT_JSON, baseTexture, 0, 0);
95
95
  const fromXml = xmlBitmapFont(parseXml(FONT_XML), baseTexture, 0, 0);
96
96
  for (const code of [65, 66]) {
@@ -102,13 +102,13 @@ describe('bitmap font parsing', () => {
102
102
  }
103
103
  });
104
104
 
105
- it('records the same kerning as the xml form', () => {
105
+ it('records the same kerning as the xml form', (): void => {
106
106
  expect(jsonBitmapFont(FONT_JSON, baseTexture, 0, 0).chars[66]?.kerning[65]).toBe(-3);
107
107
  });
108
108
  });
109
109
 
110
- describe('bitmapFont', () => {
111
- it('parses the xml form', () => {
110
+ describe('bitmapFont', (): void => {
111
+ it('parses the xml form', (): void => {
112
112
  expect(bitmapFont(parseXml(FONT_XML), baseTexture, 0, 0).font).toBe('Arial');
113
113
  });
114
114
  });
@@ -16,6 +16,16 @@ export type BitmapFontChar = {
16
16
  };
17
17
 
18
18
  /** A parsed bitmap font: its metrics and the glyphs it can draw. */
19
+ /** A bitmap font descriptor in the JSON form the packers emit, with attributes prefixed by `_`. */
20
+ export type JsonBitmapFontDescriptor = {
21
+ font: {
22
+ info: Record<string, string>;
23
+ common: Record<string, string>;
24
+ chars: { char: Record<string, string>[] };
25
+ kernings?: { kerning?: Record<string, string>[] };
26
+ };
27
+ };
28
+
19
29
  export type BitmapFontData = {
20
30
  font: string;
21
31
  size: number;
@@ -104,18 +114,18 @@ export const bitmapFont = (
104
114
  * @returns {object} The parsed bitmap font data.
105
115
  */
106
116
  export const jsonBitmapFont = (
107
- json: any,
117
+ json: JsonBitmapFontDescriptor,
108
118
  baseTexture: BaseTexture,
109
119
  xSpacing: number,
110
120
  ySpacing: number
111
121
  ): BitmapFontData => {
112
122
  const data: BitmapFontData = {
113
- font: json.font.info._face,
114
- size: Math.trunc(Number(json.font.info._size)),
115
- lineHeight: Math.trunc(Number(json.font.common._lineHeight)) + ySpacing,
123
+ font: json.font.info['_face'] ?? '',
124
+ size: Math.trunc(Number(json.font.info['_size'])),
125
+ lineHeight: Math.trunc(Number(json.font.common['_lineHeight'])) + ySpacing,
116
126
  chars: {},
117
127
  };
118
- for (const letter of json.font.chars.char as Record<string, string>[]) {
128
+ for (const letter of json.font.chars.char) {
119
129
  const charCode = Math.trunc(Number(letter['_id']));
120
130
  data.chars[charCode] = {
121
131
  x: Math.trunc(Number(letter['_x'])),
@@ -129,7 +139,7 @@ export const jsonBitmapFont = (
129
139
  };
130
140
  }
131
141
  if (json.font.kernings && json.font.kernings.kerning) {
132
- for (const kerning of json.font.kernings.kerning as Record<string, string>[]) {
142
+ for (const kerning of json.font.kernings.kerning) {
133
143
  const char = data.chars[Math.trunc(Number(kerning['_second']))];
134
144
  if (char) {
135
145
  char.kerning[Math.trunc(Number(kerning['_first']))] = Math.trunc(Number(kerning['_amount']));
@@ -1,6 +1,6 @@
1
1
  import type { Game } from './game.js';
2
2
  export class RequestAnimationFrame {
3
- public game: any;
3
+ public game: Game;
4
4
  public rafId: number;
5
5
 
6
6
  /**
@@ -1,28 +1,28 @@
1
1
  import { beforeEach, describe, expect, it } from 'vitest';
2
2
  import { getRegistry } from './registry.js';
3
3
 
4
- describe('getRegistry', () => {
5
- beforeEach(() => {
4
+ describe('getRegistry', (): void => {
5
+ beforeEach((): void => {
6
6
  // @ts-expect-error the registry is created on demand, so tests may clear it
7
7
  delete globalThis.PhaserRegistry;
8
8
  });
9
9
 
10
- it('creates the registry on first access', () => {
10
+ it('creates the registry on first access', (): void => {
11
11
  expect(globalThis.PhaserRegistry).toBeUndefined();
12
12
  expect(getRegistry()).toBeDefined();
13
13
  expect(globalThis.PhaserRegistry).toBeDefined();
14
14
  });
15
15
 
16
- it('returns the same object on repeat access', () => {
16
+ it('returns the same object on repeat access', (): void => {
17
17
  expect(getRegistry()).toBe(getRegistry());
18
18
  });
19
19
 
20
- it('preserves members written by subsystems', () => {
20
+ it('preserves members written by subsystems', (): void => {
21
21
  getRegistry().GL_CONTEXT_ID = 7;
22
22
  expect(getRegistry().GL_CONTEXT_ID).toBe(7);
23
23
  });
24
24
 
25
- it('does not clobber a registry that already exists', () => {
25
+ it('does not clobber a registry that already exists', (): void => {
26
26
  const existing = getRegistry();
27
27
  existing.stencilBufferLimit = 3;
28
28
  expect(getRegistry()).toBe(existing);
@@ -5,6 +5,7 @@ import type { Game, GameConfig } from './game.js';
5
5
  import { DOM } from './dom.js';
6
6
  import { Signal } from './signal.js';
7
7
  import type { AppliedCallback, Callback } from './callback.js';
8
+ import type { Input } from './input.js';
8
9
 
9
10
  /** The gap the canvas leaves around itself inside its parent. */
10
11
  export type ScaleMargin = { left: number; top: number; right: number; bottom: number; x: number; y: number };
@@ -159,7 +160,7 @@ export class ScaleManager {
159
160
  this._lastReportedCanvasSize = new Rectangle();
160
161
  this._lastReportedGameSize = new Rectangle();
161
162
  this._booted = false;
162
- if (game.config) {
163
+ if (game.config as GameConfig | undefined) {
163
164
  this.parseConfig(game.config);
164
165
  }
165
166
  this.setupScale(width, height);
@@ -249,7 +250,7 @@ export class ScaleManager {
249
250
  if (typeof this.game.parent === 'string') {
250
251
  // hopefully an element ID
251
252
  target = document.querySelector<HTMLElement>(`#${CSS.escape(this.game.parent)}`);
252
- } else if (this.game.parent && this.game.parent.nodeType === 1) {
253
+ } else if (typeof this.game.parent === 'object' && this.game.parent.nodeType === 1) {
253
254
  // quick test for a HTMLelement
254
255
  target = this.game.parent;
255
256
  }
@@ -447,12 +448,12 @@ export class ScaleManager {
447
448
  this.scaleFactorInversed.y = this.height / this.game.height;
448
449
  this.aspectRatio = this.width / this.height;
449
450
  // This can be invoked in boot pre-canvas
450
- if (this.game.canvas) {
451
+ if (this.game.canvas as HTMLCanvasElement | undefined) {
451
452
  this.dom.getOffset(this.game.canvas, this.offset);
452
453
  }
453
454
  this.bounds.setTo(this.offset.x, this.offset.y, this.width, this.height);
454
455
  // Can be invoked in boot pre-input
455
- if (this.game.input && this.game.input.scale) {
456
+ if (this.game.input as Input | undefined) {
456
457
  this.game.input.scale.setTo(this.scaleFactor.x, this.scaleFactor.y);
457
458
  }
458
459
  }
@@ -579,7 +580,7 @@ export class ScaleManager {
579
580
  * @returns {Rectangle} TBD.
580
581
  */
581
582
  public getParentBounds(target: Rectangle): Rectangle {
582
- const bounds = target || new Rectangle();
583
+ const bounds = target ?? new Rectangle();
583
584
  const parentNode = this.boundingParent;
584
585
  const { visualBounds } = this.dom;
585
586
  const { layoutBounds } = this.dom;
@@ -757,10 +758,10 @@ export class ScaleManager {
757
758
  // Max/min not honored fullscreen
758
759
  return;
759
760
  }
760
- if (this.maxWidth) {
761
+ if (this.maxWidth !== null) {
761
762
  this.width = Math.min(this.width, this.maxWidth);
762
763
  }
763
- if (this.maxHeight) {
764
+ if (this.maxHeight !== null) {
764
765
  this.height = Math.min(this.height, this.maxHeight);
765
766
  }
766
767
  }
@@ -796,7 +797,7 @@ export class ScaleManager {
796
797
  }
797
798
  if (this.compatibility.clickTrampoline === 'when-not-mouse') {
798
799
  const { input } = this.game;
799
- if (input.activePointer && input.activePointer !== input.mousePointer && allowTrampoline) {
800
+ if (input.activePointer !== null && input.activePointer !== input.mousePointer && allowTrampoline) {
800
801
  input.activePointer.addClickTrampoline('startFullScreen', this.startFullScreen, this, [antialias, false]);
801
802
  return false;
802
803
  }
@@ -953,7 +954,7 @@ export class ScaleManager {
953
954
  if (this.parentIsWindow || (this.isFullScreen && this.hasPhaserSetFullScreen && !this._createdFullScreenTarget)) {
954
955
  return null;
955
956
  }
956
- const parentNode = this.game.canvas ? (this.game.canvas.parentNode as HTMLElement | null) : null;
957
+ const parentNode = (this.game.canvas.parentNode as HTMLElement | null) ?? null;
957
958
  return parentNode ?? null;
958
959
  }
959
960
 
@@ -968,7 +969,7 @@ export class ScaleManager {
968
969
  /**
969
970
  * TBD.
970
971
  */
971
- public set scaleMode(value) {
972
+ public set scaleMode(value: number) {
972
973
  if (value !== this._scaleMode) {
973
974
  if (!this.isFullScreen) {
974
975
  this.updateDimensions(this._gameSize.width, this._gameSize.height, true);
@@ -990,7 +991,7 @@ export class ScaleManager {
990
991
  /**
991
992
  * TBD.
992
993
  */
993
- public set fullScreenScaleMode(value) {
994
+ public set fullScreenScaleMode(value: number) {
994
995
  if (value !== this._fullScreenScaleMode) {
995
996
  // If in fullscreen then need a wee bit more work
996
997
  if (this.isFullScreen) {