@vpmedia/phaser 1.123.0 → 1.124.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 (206) hide show
  1. package/dist/index.js +339 -323
  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/input.d.ts +3 -2
  17. package/dist/phaser/core/input.d.ts.map +1 -1
  18. package/dist/phaser/core/input_handler.d.ts.map +1 -1
  19. package/dist/phaser/core/input_mouse.d.ts +5 -1
  20. package/dist/phaser/core/input_mouse.d.ts.map +1 -1
  21. package/dist/phaser/core/input_pointer.d.ts +3 -3
  22. package/dist/phaser/core/input_pointer.d.ts.map +1 -1
  23. package/dist/phaser/core/input_touch.d.ts +8 -8
  24. package/dist/phaser/core/input_touch.d.ts.map +1 -1
  25. package/dist/phaser/core/loader.d.ts +11 -2
  26. package/dist/phaser/core/loader.d.ts.map +1 -1
  27. package/dist/phaser/core/loader_parser.d.ts +14 -1
  28. package/dist/phaser/core/loader_parser.d.ts.map +1 -1
  29. package/dist/phaser/core/raf.d.ts +1 -1
  30. package/dist/phaser/core/raf.d.ts.map +1 -1
  31. package/dist/phaser/core/scale_manager.d.ts.map +1 -1
  32. package/dist/phaser/core/scene_manager.d.ts.map +1 -1
  33. package/dist/phaser/core/signal.d.ts.map +1 -1
  34. package/dist/phaser/core/sound.d.ts.map +1 -1
  35. package/dist/phaser/core/sound_manager.d.ts +1 -1
  36. package/dist/phaser/core/sound_manager.d.ts.map +1 -1
  37. package/dist/phaser/core/stage.d.ts +16 -6
  38. package/dist/phaser/core/stage.d.ts.map +1 -1
  39. package/dist/phaser/core/time.d.ts.map +1 -1
  40. package/dist/phaser/core/timer.d.ts +1 -1
  41. package/dist/phaser/core/timer.d.ts.map +1 -1
  42. package/dist/phaser/core/tween.d.ts +13 -5
  43. package/dist/phaser/core/tween.d.ts.map +1 -1
  44. package/dist/phaser/core/tween_data.d.ts +9 -7
  45. package/dist/phaser/core/tween_data.d.ts.map +1 -1
  46. package/dist/phaser/core/tween_manager.d.ts.map +1 -1
  47. package/dist/phaser/display/button.d.ts +6 -5
  48. package/dist/phaser/display/button.d.ts.map +1 -1
  49. package/dist/phaser/display/canvas/buffer.d.ts +1 -1
  50. package/dist/phaser/display/canvas/buffer.d.ts.map +1 -1
  51. package/dist/phaser/display/canvas/masker.d.ts +1 -1
  52. package/dist/phaser/display/canvas/masker.d.ts.map +1 -1
  53. package/dist/phaser/display/canvas/pool.d.ts +2 -2
  54. package/dist/phaser/display/canvas/pool.d.ts.map +1 -1
  55. package/dist/phaser/display/canvas/renderer.d.ts +9 -8
  56. package/dist/phaser/display/canvas/renderer.d.ts.map +1 -1
  57. package/dist/phaser/display/display_object.d.ts +3 -1
  58. package/dist/phaser/display/display_object.d.ts.map +1 -1
  59. package/dist/phaser/display/graphics.d.ts +1 -1
  60. package/dist/phaser/display/graphics.d.ts.map +1 -1
  61. package/dist/phaser/display/group.d.ts +1 -1
  62. package/dist/phaser/display/group.d.ts.map +1 -1
  63. package/dist/phaser/display/image.d.ts +6 -5
  64. package/dist/phaser/display/image.d.ts.map +1 -1
  65. package/dist/phaser/display/sprite_util.d.ts +3 -2
  66. package/dist/phaser/display/sprite_util.d.ts.map +1 -1
  67. package/dist/phaser/display/text.d.ts +2 -16
  68. package/dist/phaser/display/text.d.ts.map +1 -1
  69. package/dist/phaser/display/webgl/abstract_filter.d.ts +14 -8
  70. package/dist/phaser/display/webgl/abstract_filter.d.ts.map +1 -1
  71. package/dist/phaser/display/webgl/blend_manager.d.ts +2 -3
  72. package/dist/phaser/display/webgl/blend_manager.d.ts.map +1 -1
  73. package/dist/phaser/display/webgl/fast_sprite_batch.d.ts +11 -5
  74. package/dist/phaser/display/webgl/fast_sprite_batch.d.ts.map +1 -1
  75. package/dist/phaser/display/webgl/filter_manager.d.ts +6 -4
  76. package/dist/phaser/display/webgl/filter_manager.d.ts.map +1 -1
  77. package/dist/phaser/display/webgl/filter_texture.d.ts +4 -4
  78. package/dist/phaser/display/webgl/filter_texture.d.ts.map +1 -1
  79. package/dist/phaser/display/webgl/graphics.d.ts +2 -2
  80. package/dist/phaser/display/webgl/graphics.d.ts.map +1 -1
  81. package/dist/phaser/display/webgl/mask_manager.d.ts +3 -2
  82. package/dist/phaser/display/webgl/mask_manager.d.ts.map +1 -1
  83. package/dist/phaser/display/webgl/render_texture.d.ts +11 -8
  84. package/dist/phaser/display/webgl/render_texture.d.ts.map +1 -1
  85. package/dist/phaser/display/webgl/renderer.d.ts +8 -4
  86. package/dist/phaser/display/webgl/renderer.d.ts.map +1 -1
  87. package/dist/phaser/display/webgl/shader/normal.d.ts +28 -3
  88. package/dist/phaser/display/webgl/shader/normal.d.ts.map +1 -1
  89. package/dist/phaser/display/webgl/sprite_batch.d.ts +6 -5
  90. package/dist/phaser/display/webgl/sprite_batch.d.ts.map +1 -1
  91. package/dist/phaser/display/webgl/stencil_manager.d.ts +3 -3
  92. package/dist/phaser/display/webgl/stencil_manager.d.ts.map +1 -1
  93. package/dist/phaser/display/webgl/texture_util.d.ts +2 -2
  94. package/dist/phaser/display/webgl/texture_util.d.ts.map +1 -1
  95. package/dist/phaser/display/webgl/util.d.ts +1 -1
  96. package/dist/phaser/display/webgl/util.d.ts.map +1 -1
  97. package/dist/phaser/geom/circle.d.ts.map +1 -1
  98. package/dist/phaser/geom/line.d.ts +10 -1
  99. package/dist/phaser/geom/line.d.ts.map +1 -1
  100. package/dist/phaser/geom/rectangle.d.ts.map +1 -1
  101. package/dist/phaser/geom/util/circle.d.ts +2 -1
  102. package/dist/phaser/geom/util/circle.d.ts.map +1 -1
  103. package/dist/phaser/geom/util/point.d.ts +1 -1
  104. package/dist/phaser/geom/util/point.d.ts.map +1 -1
  105. package/dist/phaser/geom/util/rectangle.d.ts +1 -1
  106. package/dist/phaser/geom/util/rectangle.d.ts.map +1 -1
  107. package/dist/phaser/util/math.d.ts.map +1 -1
  108. package/package.json +1 -1
  109. package/src/phaser/core/animation.ts +4 -4
  110. package/src/phaser/core/animation_manager.ts +10 -10
  111. package/src/phaser/core/animation_parser.ts +30 -24
  112. package/src/phaser/core/array_set.ts +27 -27
  113. package/src/phaser/core/cache.test.ts +33 -33
  114. package/src/phaser/core/cache.ts +3 -3
  115. package/src/phaser/core/callback.ts +1 -0
  116. package/src/phaser/core/callback_context.test.ts +8 -8
  117. package/src/phaser/core/dom.ts +15 -5
  118. package/src/phaser/core/factory.ts +9 -2
  119. package/src/phaser/core/frame_data.test.ts +23 -23
  120. package/src/phaser/core/input.ts +9 -8
  121. package/src/phaser/core/input_handler.test.ts +18 -18
  122. package/src/phaser/core/input_handler.ts +1 -1
  123. package/src/phaser/core/input_mouse.ts +9 -8
  124. package/src/phaser/core/input_pointer.test.ts +26 -26
  125. package/src/phaser/core/input_pointer.ts +3 -3
  126. package/src/phaser/core/input_touch.ts +8 -8
  127. package/src/phaser/core/loader.test.ts +26 -26
  128. package/src/phaser/core/loader.ts +25 -25
  129. package/src/phaser/core/loader_parser.test.ts +16 -16
  130. package/src/phaser/core/loader_parser.ts +16 -6
  131. package/src/phaser/core/raf.ts +1 -1
  132. package/src/phaser/core/registry.test.ts +6 -6
  133. package/src/phaser/core/scale_manager.ts +2 -2
  134. package/src/phaser/core/scene_manager.test.ts +30 -30
  135. package/src/phaser/core/scene_manager.ts +1 -1
  136. package/src/phaser/core/signal.test.ts +8 -8
  137. package/src/phaser/core/signal.ts +1 -1
  138. package/src/phaser/core/signal_dispatch.test.ts +30 -30
  139. package/src/phaser/core/sound.ts +20 -8
  140. package/src/phaser/core/sound_manager.ts +6 -6
  141. package/src/phaser/core/stage.ts +19 -9
  142. package/src/phaser/core/time.ts +1 -1
  143. package/src/phaser/core/timer.test.ts +47 -47
  144. package/src/phaser/core/timer.ts +1 -1
  145. package/src/phaser/core/tween.ts +28 -25
  146. package/src/phaser/core/tween_data.test.ts +119 -0
  147. package/src/phaser/core/tween_data.ts +54 -39
  148. package/src/phaser/core/tween_easing.test.ts +5 -5
  149. package/src/phaser/core/tween_manager.ts +2 -2
  150. package/src/phaser/display/bitmap_text.test.ts +30 -30
  151. package/src/phaser/display/button.ts +8 -6
  152. package/src/phaser/display/canvas/buffer.ts +2 -2
  153. package/src/phaser/display/canvas/masker.ts +1 -1
  154. package/src/phaser/display/canvas/pool.test.ts +20 -20
  155. package/src/phaser/display/canvas/pool.ts +3 -3
  156. package/src/phaser/display/canvas/renderer.ts +12 -11
  157. package/src/phaser/display/canvas/util.test.ts +25 -25
  158. package/src/phaser/display/display_object.ts +3 -1
  159. package/src/phaser/display/graphics.test.ts +70 -20
  160. package/src/phaser/display/graphics.ts +38 -32
  161. package/src/phaser/display/group.ts +4 -4
  162. package/src/phaser/display/image.ts +28 -25
  163. package/src/phaser/display/sprite_util.ts +3 -2
  164. package/src/phaser/display/text.test.ts +28 -25
  165. package/src/phaser/display/text.ts +21 -18
  166. package/src/phaser/display/webgl/abstract_filter.ts +20 -10
  167. package/src/phaser/display/webgl/blend_manager.ts +4 -5
  168. package/src/phaser/display/webgl/earcut.test.ts +20 -20
  169. package/src/phaser/display/webgl/fast_sprite_batch.ts +21 -16
  170. package/src/phaser/display/webgl/filter_manager.ts +7 -4
  171. package/src/phaser/display/webgl/filter_texture.ts +5 -5
  172. package/src/phaser/display/webgl/graphics.ts +2 -2
  173. package/src/phaser/display/webgl/mask_manager.ts +9 -14
  174. package/src/phaser/display/webgl/render_texture.ts +15 -14
  175. package/src/phaser/display/webgl/renderer.ts +7 -6
  176. package/src/phaser/display/webgl/shader/normal.ts +41 -31
  177. package/src/phaser/display/webgl/shader/shader.test.ts +24 -24
  178. package/src/phaser/display/webgl/shader_manager.test.ts +18 -18
  179. package/src/phaser/display/webgl/sprite_batch.ts +8 -8
  180. package/src/phaser/display/webgl/stencil_manager.ts +4 -4
  181. package/src/phaser/display/webgl/texture_util.ts +2 -2
  182. package/src/phaser/display/webgl/util.ts +1 -1
  183. package/src/phaser/geom/circle.test.ts +38 -38
  184. package/src/phaser/geom/circle.ts +7 -7
  185. package/src/phaser/geom/ellipse.test.ts +12 -12
  186. package/src/phaser/geom/line.test.ts +15 -15
  187. package/src/phaser/geom/line.ts +5 -2
  188. package/src/phaser/geom/matrix.test.ts +31 -31
  189. package/src/phaser/geom/point.test.ts +31 -31
  190. package/src/phaser/geom/polygon.test.ts +27 -27
  191. package/src/phaser/geom/rectangle.test.ts +87 -87
  192. package/src/phaser/geom/rectangle.ts +11 -11
  193. package/src/phaser/geom/rounded_rectangle.test.ts +9 -9
  194. package/src/phaser/geom/util/circle.test.ts +5 -5
  195. package/src/phaser/geom/util/circle.ts +2 -1
  196. package/src/phaser/geom/util/ellipse.test.ts +2 -2
  197. package/src/phaser/geom/util/line.test.ts +2 -2
  198. package/src/phaser/geom/util/matrix.test.ts +4 -4
  199. package/src/phaser/geom/util/point.test.ts +2 -2
  200. package/src/phaser/geom/util/point.ts +1 -1
  201. package/src/phaser/geom/util/polygon.test.ts +2 -2
  202. package/src/phaser/geom/util/rectangle.test.ts +2 -2
  203. package/src/phaser/geom/util/rectangle.ts +1 -1
  204. package/src/phaser/geom/util/rounded_rectangle.test.ts +2 -2
  205. package/src/phaser/util/math.test.ts +41 -41
  206. package/src/phaser/util/math.ts +5 -2
@@ -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]! };
@@ -525,10 +532,10 @@ export class Loader {
525
532
  this.addToFileList('bitmapfont', key, textureURL, { atlasURL, xSpacing, ySpacing });
526
533
  } else if (typeof atlasData === 'string') {
527
534
  // A stringified xml/json atlas has been given
528
- let json = null;
529
- let xml = null;
535
+ let json: unknown = null;
536
+ let xml: XMLDocument | null = null;
530
537
  try {
531
- json = JSON.parse(atlasData);
538
+ json = JSON.parse(atlasData) as unknown;
532
539
  } catch {
533
540
  xml = this.parseXml(atlasData);
534
541
  }
@@ -1115,7 +1122,7 @@ export class Loader {
1115
1122
  switch (file.type) {
1116
1123
  case 'packfile': {
1117
1124
  // Pack data must never be false-ish after it is fetched without error
1118
- file.data = JSON.parse(response.responseText) ?? {};
1125
+ file.data = (JSON.parse(response.responseText) ?? {}) as LoaderFileData;
1119
1126
  break;
1120
1127
  }
1121
1128
  case 'image': {
@@ -1167,10 +1174,10 @@ export class Loader {
1167
1174
  this.transformUrl(file.atlasURL, file),
1168
1175
  'text',
1169
1176
  (bitmapFontFile: LoaderFile, bitmapFontXhr: XMLHttpRequest): void => {
1170
- let json;
1177
+ let json: unknown;
1171
1178
  try {
1172
1179
  // Try to parse as JSON, if it fails, then it's hopefully XML
1173
- json = JSON.parse(bitmapFontXhr.responseText);
1180
+ json = JSON.parse(bitmapFontXhr.responseText) as unknown;
1174
1181
  } catch {
1175
1182
  // pass
1176
1183
  }
@@ -1217,7 +1224,7 @@ export class Loader {
1217
1224
  * @param {XMLHttpRequest} xhr - The XMLHttpRequest object containing the file data.
1218
1225
  */
1219
1226
  public jsonLoadComplete(file: LoaderFile, xhr: XMLHttpRequest): void {
1220
- const data = JSON.parse(xhr.responseText);
1227
+ const data = JSON.parse(xhr.responseText) as unknown;
1221
1228
  const url = typeof file.url === 'string' ? file.url : '';
1222
1229
  if (file.type === 'bitmapfont') {
1223
1230
  this.cache.addBitmapFont(
@@ -1254,7 +1261,8 @@ export class Loader {
1254
1261
  const data = xhr.responseText;
1255
1262
  const xml = this.parseXml(data);
1256
1263
  if (!xml) {
1257
- const responseType = xhr.responseType || (xhr as any).contentType; // contentType for MS-XDomainRequest
1264
+ // contentType is the MS-XDomainRequest name for the same thing
1265
+ const responseType = xhr.responseType || (xhr as unknown as { contentType?: string }).contentType;
1258
1266
  this.game.logger.warn(`${file.key}: invalid XML (${responseType})`);
1259
1267
  this.asyncComplete(file, 'invalid XML');
1260
1268
  return;
@@ -1283,22 +1291,14 @@ export class Loader {
1283
1291
  * @param {object} data - The XML string data to parse.
1284
1292
  * @returns {Document} The parsed DOM Document, or null if parsing failed.
1285
1293
  */
1286
- public parseXml(data: string) {
1287
- let xml = null;
1294
+ public parseXml(data: string): XMLDocument | null {
1295
+ let xml: XMLDocument | null = null;
1288
1296
  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
- }
1297
+ xml = new DOMParser().parseFromString(data, 'text/xml');
1298
1298
  } catch {
1299
1299
  xml = null;
1300
1300
  }
1301
- if (!xml || !xml.documentElement || xml.querySelectorAll('parsererror').length > 0) {
1301
+ if (!xml?.documentElement || xml.querySelectorAll('parsererror').length > 0) {
1302
1302
  return null;
1303
1303
  }
1304
1304
  return xml;
@@ -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);
@@ -968,7 +968,7 @@ export class ScaleManager {
968
968
  /**
969
969
  * TBD.
970
970
  */
971
- public set scaleMode(value) {
971
+ public set scaleMode(value: number) {
972
972
  if (value !== this._scaleMode) {
973
973
  if (!this.isFullScreen) {
974
974
  this.updateDimensions(this._gameSize.width, this._gameSize.height, true);
@@ -990,7 +990,7 @@ export class ScaleManager {
990
990
  /**
991
991
  * TBD.
992
992
  */
993
- public set fullScreenScaleMode(value) {
993
+ public set fullScreenScaleMode(value: number) {
994
994
  if (value !== this._fullScreenScaleMode) {
995
995
  // If in fullscreen then need a wee bit more work
996
996
  if (this.isFullScreen) {
@@ -20,74 +20,74 @@ const createGame = (isBooted = true): Game =>
20
20
  const createManager = (pendingState: ConstructorParameters<typeof SceneManager>[1] = null): SceneManager =>
21
21
  new SceneManager(createGame(), pendingState);
22
22
 
23
- describe('SceneManager', () => {
24
- describe('add', () => {
25
- it('takes a plain hook object and links the game onto it', () => {
23
+ describe('SceneManager', (): void => {
24
+ describe('add', (): void => {
25
+ it('takes a plain hook object and links the game onto it', (): void => {
26
26
  const manager = createManager();
27
27
  const state: SceneState = { create: vi.fn<() => void>() };
28
28
  expect(manager.add('menu', state)).toBe(state);
29
29
  expect(state.game).toBeDefined();
30
30
  });
31
31
 
32
- it('builds a state from a constructor', () => {
32
+ it('builds a state from a constructor', (): void => {
33
33
  const manager = createManager();
34
34
  class Menu extends Scene {}
35
35
  expect(manager.add('menu', Menu)).toBeInstanceOf(Menu);
36
36
  });
37
37
 
38
- it('takes a scene instance as-is', () => {
38
+ it('takes a scene instance as-is', (): void => {
39
39
  const manager = createManager();
40
40
  const scene = new Scene();
41
41
  expect(manager.add('menu', scene)).toBe(scene);
42
42
  });
43
43
 
44
- it('queues the state when the game has not booted', () => {
44
+ it('queues the state when the game has not booted', (): void => {
45
45
  const manager = new SceneManager(createGame(false), null);
46
46
  manager.add('menu', { create: vi.fn<() => void>() }, true);
47
47
  expect(manager._pendingState).toBe('menu');
48
48
  });
49
49
 
50
- it('starts the state right away once the game has booted', () => {
50
+ it('starts the state right away once the game has booted', (): void => {
51
51
  const manager = createManager();
52
52
  manager.add('menu', { create: vi.fn<() => void>() }, true);
53
53
  expect(manager._pendingState).toBe('menu');
54
54
  });
55
55
  });
56
56
 
57
- describe('boot', () => {
58
- it('registers a state given as an object under the default key', () => {
57
+ describe('boot', (): void => {
58
+ it('registers a state given as an object under the default key', (): void => {
59
59
  const manager = createManager({ create: vi.fn<() => void>() });
60
60
  manager.boot();
61
61
  expect(manager.states['default']).toBeDefined();
62
62
  });
63
63
 
64
- it('leaves a state given by key alone', () => {
64
+ it('leaves a state given by key alone', (): void => {
65
65
  const manager = createManager('menu');
66
66
  manager.boot();
67
67
  expect(manager.states['default']).toBeUndefined();
68
68
  });
69
69
  });
70
70
 
71
- describe('checkState', () => {
72
- it('accepts a state carrying any of the lifecycle hooks', () => {
71
+ describe('checkState', (): void => {
72
+ it('accepts a state carrying any of the lifecycle hooks', (): void => {
73
73
  const manager = createManager();
74
74
  manager.add('menu', { update: vi.fn<() => void>() });
75
75
  expect(manager.checkState('menu')).toBe(true);
76
76
  });
77
77
 
78
- it('rejects a state with no hooks at all', () => {
78
+ it('rejects a state with no hooks at all', (): void => {
79
79
  const manager = createManager();
80
80
  manager.add('menu', {});
81
81
  expect(manager.checkState('menu')).toBe(false);
82
82
  });
83
83
 
84
- it('rejects a key it does not hold', () => {
84
+ it('rejects a key it does not hold', (): void => {
85
85
  expect(createManager().checkState('nope')).toBe(false);
86
86
  });
87
87
  });
88
88
 
89
- describe('setCurrentState', () => {
90
- it('binds the hooks the state provides and leaves the rest null', () => {
89
+ describe('setCurrentState', (): void => {
90
+ it('binds the hooks the state provides and leaves the rest null', (): void => {
91
91
  const manager = createManager();
92
92
  const create = vi.fn<() => void>();
93
93
  manager.add('menu', { create });
@@ -98,7 +98,7 @@ describe('SceneManager', () => {
98
98
  expect(manager.onPreloadCallback).toBeNull();
99
99
  });
100
100
 
101
- it('falls back to a no-op for init and shutdown', () => {
101
+ it('falls back to a no-op for init and shutdown', (): void => {
102
102
  const manager = createManager();
103
103
  manager.add('menu', {});
104
104
  manager.setCurrentState('menu');
@@ -106,7 +106,7 @@ describe('SceneManager', () => {
106
106
  expect(manager.onShutDownCallback).toBe(manager.dummy);
107
107
  });
108
108
 
109
- it('calls init with the arguments start was given', () => {
109
+ it('calls init with the arguments start was given', (): void => {
110
110
  const manager = createManager();
111
111
  const init = vi.fn<() => void>();
112
112
  manager.add('menu', { init, update: vi.fn<() => void>() });
@@ -115,7 +115,7 @@ describe('SceneManager', () => {
115
115
  expect(init).toHaveBeenCalledWith('a', 1);
116
116
  });
117
117
 
118
- it('stamps the key onto the state', () => {
118
+ it('stamps the key onto the state', (): void => {
119
119
  const manager = createManager();
120
120
  const state: SceneState = { create: vi.fn<() => void>() };
121
121
  manager.add('menu', state);
@@ -124,8 +124,8 @@ describe('SceneManager', () => {
124
124
  });
125
125
  });
126
126
 
127
- describe('start', () => {
128
- it('ignores a key with no lifecycle hooks', () => {
127
+ describe('start', (): void => {
128
+ it('ignores a key with no lifecycle hooks', (): void => {
129
129
  const manager = createManager();
130
130
  manager.add('menu', {});
131
131
  manager.start('menu');
@@ -133,8 +133,8 @@ describe('SceneManager', () => {
133
133
  });
134
134
  });
135
135
 
136
- describe('update', () => {
137
- it('runs the update hook only once the scene has been created', () => {
136
+ describe('update', (): void => {
137
+ it('runs the update hook only once the scene has been created', (): void => {
138
138
  const manager = createManager();
139
139
  const update = vi.fn<() => void>();
140
140
  manager.add('menu', { update });
@@ -146,7 +146,7 @@ describe('SceneManager', () => {
146
146
  expect(update).toHaveBeenCalledTimes(1);
147
147
  });
148
148
 
149
- it('runs the create hook exactly once', () => {
149
+ it('runs the create hook exactly once', (): void => {
150
150
  const manager = createManager();
151
151
  const create = vi.fn<() => void>();
152
152
  manager.add('menu', { create });
@@ -157,8 +157,8 @@ describe('SceneManager', () => {
157
157
  });
158
158
  });
159
159
 
160
- describe('resize', () => {
161
- it('passes the new size to the scene', () => {
160
+ describe('resize', (): void => {
161
+ it('passes the new size to the scene', (): void => {
162
162
  const manager = createManager();
163
163
  const resize = vi.fn<(width: number, height: number) => void>();
164
164
  manager.add('menu', { resize });
@@ -168,8 +168,8 @@ describe('SceneManager', () => {
168
168
  });
169
169
  });
170
170
 
171
- describe('remove', () => {
172
- it('drops the state and unbinds its hooks when it is current', () => {
171
+ describe('remove', (): void => {
172
+ it('drops the state and unbinds its hooks when it is current', (): void => {
173
173
  const manager = createManager();
174
174
  manager.add('menu', { create: vi.fn<() => void>() });
175
175
  manager.setCurrentState('menu');
@@ -179,8 +179,8 @@ describe('SceneManager', () => {
179
179
  });
180
180
  });
181
181
 
182
- describe('destroy', () => {
183
- it('empties the manager', () => {
182
+ describe('destroy', (): void => {
183
+ it('empties the manager', (): void => {
184
184
  const manager = createManager();
185
185
  manager.add('menu', { create: vi.fn<() => void>(), shutdown: vi.fn<() => void>() });
186
186
  manager.setCurrentState('menu');
@@ -359,7 +359,7 @@ export class SceneManager {
359
359
  * Get whether the scene has been created.
360
360
  * @returns {boolean} True if the scene has been created, false otherwise.
361
361
  */
362
- public get created() {
362
+ public get created(): boolean {
363
363
  return this._created;
364
364
  }
365
365
  }
@@ -1,14 +1,14 @@
1
1
  import { expect, describe, it } from 'vitest';
2
2
  import { Signal } from './signal.js';
3
3
 
4
- describe('Signal', () => {
5
- describe('core', () => {
6
- it('adds, dispatches to and removes listeners', () => {
4
+ describe('Signal', (): void => {
5
+ describe('core', (): void => {
6
+ it('adds, dispatches to and removes listeners', (): void => {
7
7
  const signal = new Signal();
8
- const listener = (arg: number) => {
8
+ const listener = (arg: number): void => {
9
9
  expect(arg).toBe(1);
10
10
  };
11
- const listenerOnce = (arg: number) => {
11
+ const listenerOnce = (arg: number): void => {
12
12
  expect(arg).toBe(1);
13
13
  };
14
14
  signal.add(listener);
@@ -20,14 +20,14 @@ describe('Signal', () => {
20
20
  signal.remove(listener);
21
21
  expect(signal.has(listener)).toBe(false);
22
22
  expect(signal.getNumListeners()).toBe(0);
23
- expect(signal.has(() => null)).toBe(false);
23
+ expect(signal.has((): null => null)).toBe(false);
24
24
  });
25
25
 
26
- it('async', async () => {
26
+ it('async', async (): Promise<void> => {
27
27
  const signal = new Signal();
28
28
  const promise = signal.toPromise();
29
29
  expect(signal.getNumListeners()).toBe(1);
30
- setTimeout(() => {
30
+ setTimeout((): void => {
31
31
  signal.dispatch(1);
32
32
  }, 10);
33
33
  const result = await promise;
@@ -275,7 +275,7 @@ export class Signal {
275
275
  * Get a bound version of the dispatch function.
276
276
  * @returns {Function} A function that will dispatch the signal with the correct context.
277
277
  */
278
- public get boundDispatch() {
278
+ public get boundDispatch(): (...args: unknown[]) => void {
279
279
  this._boundDispatch ??= (...rest: unknown[]): void => {
280
280
  this.dispatch(...rest);
281
281
  };