@vpmedia/phaser 1.122.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 (207) hide show
  1. package/dist/index.js +341 -325
  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 +31 -24
  158. package/src/phaser/display/canvas/util.ts +2 -2
  159. package/src/phaser/display/display_object.ts +3 -1
  160. package/src/phaser/display/graphics.test.ts +70 -20
  161. package/src/phaser/display/graphics.ts +38 -32
  162. package/src/phaser/display/group.ts +4 -4
  163. package/src/phaser/display/image.ts +28 -25
  164. package/src/phaser/display/sprite_util.ts +3 -2
  165. package/src/phaser/display/text.test.ts +28 -25
  166. package/src/phaser/display/text.ts +21 -18
  167. package/src/phaser/display/webgl/abstract_filter.ts +20 -10
  168. package/src/phaser/display/webgl/blend_manager.ts +4 -5
  169. package/src/phaser/display/webgl/earcut.test.ts +20 -20
  170. package/src/phaser/display/webgl/fast_sprite_batch.ts +21 -16
  171. package/src/phaser/display/webgl/filter_manager.ts +7 -4
  172. package/src/phaser/display/webgl/filter_texture.ts +5 -5
  173. package/src/phaser/display/webgl/graphics.ts +2 -2
  174. package/src/phaser/display/webgl/mask_manager.ts +9 -14
  175. package/src/phaser/display/webgl/render_texture.ts +15 -14
  176. package/src/phaser/display/webgl/renderer.ts +7 -6
  177. package/src/phaser/display/webgl/shader/normal.ts +41 -31
  178. package/src/phaser/display/webgl/shader/shader.test.ts +24 -24
  179. package/src/phaser/display/webgl/shader_manager.test.ts +18 -18
  180. package/src/phaser/display/webgl/sprite_batch.ts +8 -8
  181. package/src/phaser/display/webgl/stencil_manager.ts +4 -4
  182. package/src/phaser/display/webgl/texture_util.ts +2 -2
  183. package/src/phaser/display/webgl/util.ts +1 -1
  184. package/src/phaser/geom/circle.test.ts +38 -38
  185. package/src/phaser/geom/circle.ts +7 -7
  186. package/src/phaser/geom/ellipse.test.ts +12 -12
  187. package/src/phaser/geom/line.test.ts +15 -15
  188. package/src/phaser/geom/line.ts +5 -2
  189. package/src/phaser/geom/matrix.test.ts +31 -31
  190. package/src/phaser/geom/point.test.ts +31 -31
  191. package/src/phaser/geom/polygon.test.ts +27 -27
  192. package/src/phaser/geom/rectangle.test.ts +87 -87
  193. package/src/phaser/geom/rectangle.ts +11 -11
  194. package/src/phaser/geom/rounded_rectangle.test.ts +9 -9
  195. package/src/phaser/geom/util/circle.test.ts +5 -5
  196. package/src/phaser/geom/util/circle.ts +2 -1
  197. package/src/phaser/geom/util/ellipse.test.ts +2 -2
  198. package/src/phaser/geom/util/line.test.ts +2 -2
  199. package/src/phaser/geom/util/matrix.test.ts +4 -4
  200. package/src/phaser/geom/util/point.test.ts +2 -2
  201. package/src/phaser/geom/util/point.ts +1 -1
  202. package/src/phaser/geom/util/polygon.test.ts +2 -2
  203. package/src/phaser/geom/util/rectangle.test.ts +2 -2
  204. package/src/phaser/geom/util/rectangle.ts +1 -1
  205. package/src/phaser/geom/util/rounded_rectangle.test.ts +2 -2
  206. package/src/phaser/util/math.test.ts +41 -41
  207. package/src/phaser/util/math.ts +5 -2
@@ -1,12 +1,14 @@
1
- export class ArraySet {
1
+ import type { AppliedCallback } from './callback.js';
2
+
3
+ export class ArraySet<T> {
2
4
  public position = 0;
3
- public list: any[];
5
+ public list: T[];
4
6
 
5
7
  /**
6
8
  * TBD.
7
9
  * @param {object[]} list - TBD.
8
10
  */
9
- public constructor(list: any[] = []) {
11
+ public constructor(list: T[] = []) {
10
12
  this.list = list;
11
13
  }
12
14
 
@@ -15,7 +17,7 @@ export class ArraySet {
15
17
  * @param {object} item - TBD.
16
18
  * @returns {object} TBD.
17
19
  */
18
- public add(item: any) {
20
+ public add(item: T): T {
19
21
  if (!this.exists(item)) {
20
22
  this.list.push(item);
21
23
  }
@@ -27,7 +29,7 @@ export class ArraySet {
27
29
  * @param {object} item - TBD.
28
30
  * @returns {number} TBD.
29
31
  */
30
- public getIndex(item: any): number {
32
+ public getIndex(item: T): number {
31
33
  return this.list.indexOf(item);
32
34
  }
33
35
 
@@ -37,12 +39,11 @@ export class ArraySet {
37
39
  * @param {object} value - TBD.
38
40
  * @returns {object} TBD.
39
41
  */
40
- public getByKey(property: string, value: any) {
41
- let i = this.list.length;
42
- while (i) {
43
- i -= 1;
44
- if (this.list[i][property] === value) {
45
- return this.list[i];
42
+ public getByKey(property: string, value: unknown): T | null {
43
+ for (let i = this.list.length - 1; i >= 0; i -= 1) {
44
+ const item = this.list[i] as Record<string, unknown> | undefined;
45
+ if (item?.[property] === value) {
46
+ return this.list[i]!;
46
47
  }
47
48
  }
48
49
  return null;
@@ -53,7 +54,7 @@ export class ArraySet {
53
54
  * @param {object} item - TBD.
54
55
  * @returns {boolean} TBD.
55
56
  */
56
- public exists(item: any): boolean {
57
+ public exists(item: T): boolean {
57
58
  return this.list.includes(item);
58
59
  }
59
60
 
@@ -69,7 +70,7 @@ export class ArraySet {
69
70
  * @param {object} item - TBD.
70
71
  * @returns {object} TBD.
71
72
  */
72
- public remove(item: any) {
73
+ public remove(item: T): T | null {
73
74
  const idx = this.list.indexOf(item);
74
75
  if (idx !== -1) {
75
76
  this.list.splice(idx, 1);
@@ -83,10 +84,10 @@ export class ArraySet {
83
84
  * @param {string} key - TBD.
84
85
  * @param {object} value - TBD.
85
86
  */
86
- public setAll(key: string, value: any): void {
87
+ public setAll(key: string, value: unknown): void {
87
88
  for (const item of this.list) {
88
89
  if (item) {
89
- item[key] = value;
90
+ (item as Record<string, unknown>)[key] = value;
90
91
  }
91
92
  }
92
93
  }
@@ -99,8 +100,8 @@ export class ArraySet {
99
100
  public callAll(key: string, ...args: unknown[]): void {
100
101
  // walked backwards so a callback that removes its own entry does not skip the next one
101
102
  for (let i = this.list.length - 1; i >= 0; i -= 1) {
102
- const item = this.list[i];
103
- if (item && item[key]) {
103
+ const item = this.list[i] as Record<string, AppliedCallback> | undefined;
104
+ if (item?.[key]) {
104
105
  item[key](...args);
105
106
  }
106
107
  }
@@ -111,13 +112,12 @@ export class ArraySet {
111
112
  * @param {boolean} destroy - TBD.
112
113
  */
113
114
  public removeAll(destroy = false): void {
114
- let i = this.list.length;
115
- while (i) {
116
- i -= 1;
117
- if (this.list[i]) {
118
- const item = this.remove(this.list[i]);
115
+ for (let i = this.list.length - 1; i >= 0; i -= 1) {
116
+ const entry = this.list[i];
117
+ if (entry) {
118
+ const item = this.remove(entry) as { destroy?: () => void } | null;
119
119
  if (destroy) {
120
- item.destroy();
120
+ item?.destroy?.();
121
121
  }
122
122
  }
123
123
  }
@@ -137,10 +137,10 @@ export class ArraySet {
137
137
  * TBD.
138
138
  * @returns {object} TBD.
139
139
  */
140
- public get first() {
140
+ public get first(): T | null {
141
141
  this.position = 0;
142
142
  if (this.list.length > 0) {
143
- return this.list[0];
143
+ return this.list[0]!;
144
144
  }
145
145
  return null;
146
146
  }
@@ -149,10 +149,10 @@ export class ArraySet {
149
149
  * TBD.
150
150
  * @returns {object} TBD.
151
151
  */
152
- public get next() {
152
+ public get next(): T | null {
153
153
  if (this.position < this.list.length) {
154
154
  this.position += 1;
155
- return this.list[this.position];
155
+ return this.list[this.position] ?? null;
156
156
  }
157
157
  return null;
158
158
  }
@@ -27,36 +27,36 @@ const FONT_XML = `<?xml version="1.0"?>
27
27
  </chars>
28
28
  </font>`;
29
29
 
30
- describe('Cache', () => {
30
+ describe('Cache', (): void => {
31
31
  let cache: Cache;
32
32
 
33
- beforeEach(() => {
33
+ beforeEach((): void => {
34
34
  getRegistry().TEXTURE_SCALE_MODE = SCALE_LINEAR;
35
35
  cache = new Cache(createGame());
36
36
  });
37
37
 
38
- describe('images', () => {
39
- it('seeds the default and missing images', () => {
38
+ describe('images', (): void => {
39
+ it('seeds the default and missing images', (): void => {
40
40
  expect(cache.checkImageKey('__default')).toBe(true);
41
41
  expect(cache.checkImageKey('__missing')).toBe(true);
42
42
  });
43
43
 
44
- it('keeps the default image out of the reported keys', () => {
44
+ it('keeps the default image out of the reported keys', (): void => {
45
45
  expect(cache.getKeys(IMAGE)).toStrictEqual([]);
46
46
  });
47
47
 
48
- it('returns the source bitmap by default and the whole entry when asked', () => {
48
+ it('returns the source bitmap by default and the whole entry when asked', (): void => {
49
49
  const source = createImage();
50
50
  cache.addImage('logo', 'logo.png', source);
51
51
  expect(cache.getImage('logo')).toBe(source);
52
52
  expect(cache.getImage('logo', true).key).toBe('logo');
53
53
  });
54
54
 
55
- it('falls back to the missing image for an unknown key', () => {
55
+ it('falls back to the missing image for an unknown key', (): void => {
56
56
  expect(cache.getImage('nope', true).key).toBe('__missing');
57
57
  });
58
58
 
59
- it('gives an image one frame covering the whole bitmap', () => {
59
+ it('gives an image one frame covering the whole bitmap', (): void => {
60
60
  cache.addImage('logo', 'logo.png', createImage(64, 32));
61
61
  const frame = cache.getFrameByIndex('logo', 0);
62
62
  expect(frame?.width).toBe(64);
@@ -64,26 +64,26 @@ describe('Cache', () => {
64
64
  expect(cache.getFrameCount('logo')).toBe(1);
65
65
  });
66
66
 
67
- it('reports no frames for a key it does not hold', () => {
67
+ it('reports no frames for a key it does not hold', (): void => {
68
68
  expect(cache.getFrameData('nope')).toBeNull();
69
69
  expect(cache.getFrameCount('nope')).toBe(0);
70
70
  expect(cache.hasFrameData('nope')).toBe(false);
71
71
  });
72
72
 
73
- it('drops an image when it is removed', () => {
73
+ it('drops an image when it is removed', (): void => {
74
74
  cache.addImage('logo', 'logo.png', createImage());
75
75
  cache.removeImage('logo');
76
76
  expect(cache.checkImageKey('logo')).toBe(false);
77
77
  });
78
78
 
79
- it('replaces an image registered twice under the same key', () => {
79
+ it('replaces an image registered twice under the same key', (): void => {
80
80
  cache.addImage('logo', 'a.png', createImage(4, 4));
81
81
  const second = createImage(8, 8);
82
82
  cache.addImage('logo', 'b.png', second);
83
83
  expect(cache.getImage('logo')).toBe(second);
84
84
  });
85
85
 
86
- it('clears the GL textures of every cached image', () => {
86
+ it('clears the GL textures of every cached image', (): void => {
87
87
  cache.addImage('logo', 'logo.png', createImage());
88
88
  const entry = cache.getImage('logo', true);
89
89
  entry.base._glTextures = [null];
@@ -92,25 +92,25 @@ describe('Cache', () => {
92
92
  });
93
93
  });
94
94
 
95
- describe('sounds', () => {
96
- it('stores a sound as undecoded', () => {
95
+ describe('sounds', (): void => {
96
+ it('stores a sound as undecoded', (): void => {
97
97
  cache.addSound('shot', 'shot.ogg', new ArrayBuffer(8));
98
98
  expect(cache.isSoundDecoded('shot')).toBe(false);
99
99
  expect(cache.isSoundReady('shot')).toBe(false);
100
100
  });
101
101
 
102
- it('reports an unknown sound as neither decoded nor ready', () => {
102
+ it('reports an unknown sound as neither decoded nor ready', (): void => {
103
103
  expect(cache.isSoundDecoded('nope')).toBeNull();
104
104
  expect(cache.isSoundReady('nope')).toBe(false);
105
105
  });
106
106
 
107
- it('updates a single property of a cached sound', () => {
107
+ it('updates a single property of a cached sound', (): void => {
108
108
  cache.addSound('shot', 'shot.ogg', new ArrayBuffer(8));
109
109
  cache.updateSound('shot', 'isDecoding', true);
110
110
  expect(cache.getSound('shot')?.isDecoding).toBe(true);
111
111
  });
112
112
 
113
- it('swaps in the decoded buffer and marks the sound ready', () => {
113
+ it('swaps in the decoded buffer and marks the sound ready', (): void => {
114
114
  cache.addSound('shot', 'shot.ogg', new ArrayBuffer(8));
115
115
  const buffer = { duration: 1.5 } as AudioBuffer;
116
116
  cache.decodedSound('shot', buffer);
@@ -119,33 +119,33 @@ describe('Cache', () => {
119
119
  expect(cache.isSoundReady('shot')).toBe(true);
120
120
  });
121
121
 
122
- it('ignores a decode result for a sound it never held', () => {
123
- expect(() => {
122
+ it('ignores a decode result for a sound it never held', (): void => {
123
+ expect((): void => {
124
124
  cache.decodedSound('nope', {} as AudioBuffer);
125
125
  }).not.toThrow();
126
126
  });
127
127
 
128
- it('drops a sound when it is removed', () => {
128
+ it('drops a sound when it is removed', (): void => {
129
129
  cache.addSound('shot', 'shot.ogg', new ArrayBuffer(8));
130
130
  cache.removeSound('shot');
131
131
  expect(cache.getSound('shot')).toBeNull();
132
132
  });
133
133
  });
134
134
 
135
- describe('data', () => {
136
- it('round-trips text', () => {
135
+ describe('data', (): void => {
136
+ it('round-trips text', (): void => {
137
137
  cache.addText('note', 'note.txt', 'hello');
138
138
  expect(cache.getText('note')).toBe('hello');
139
139
  cache.removeText('note');
140
140
  expect(cache.getText('note')).toBeNull();
141
141
  });
142
142
 
143
- it('round-trips JSON', () => {
143
+ it('round-trips JSON', (): void => {
144
144
  cache.addJSON('config', 'config.json', { a: 1 });
145
145
  expect(cache.getJSON('config')).toStrictEqual({ a: 1 });
146
146
  });
147
147
 
148
- it('hands back a detached copy when a clone is asked for', () => {
148
+ it('hands back a detached copy when a clone is asked for', (): void => {
149
149
  const data = { a: 1 };
150
150
  cache.addJSON('config', 'config.json', data);
151
151
  const clone = cache.getJSON<{ a: number }>('config', true);
@@ -153,15 +153,15 @@ describe('Cache', () => {
153
153
  expect(clone).not.toBe(data);
154
154
  });
155
155
 
156
- it('round-trips XML', () => {
156
+ it('round-trips XML', (): void => {
157
157
  const xml = new DOMParser().parseFromString('<root/>', 'text/xml');
158
158
  cache.addXML('doc', 'doc.xml', xml);
159
159
  expect(cache.getXML('doc')).toBe(xml);
160
160
  });
161
161
  });
162
162
 
163
- describe('bitmap fonts', () => {
164
- it('parses the descriptor and keeps it beside the atlas', () => {
163
+ describe('bitmap fonts', (): void => {
164
+ it('parses the descriptor and keeps it beside the atlas', (): void => {
165
165
  const xml = new DOMParser().parseFromString(FONT_XML, 'text/xml');
166
166
  cache.addBitmapFont('arial', 'arial.png', createImage(256, 256), xml, 'xml');
167
167
  const entry = cache.getBitmapFont('arial');
@@ -170,26 +170,26 @@ describe('Cache', () => {
170
170
  expect(entry?.base).toBeDefined();
171
171
  });
172
172
 
173
- it('reports a font it does not hold as absent', () => {
173
+ it('reports a font it does not hold as absent', (): void => {
174
174
  expect(cache.checkBitmapFontKey('nope')).toBe(false);
175
175
  expect(cache.getBitmapFont('nope')).toBeNull();
176
176
  });
177
177
  });
178
178
 
179
- describe('getItem', () => {
180
- it('returns the whole entry when no property is named', () => {
179
+ describe('getItem', (): void => {
180
+ it('returns the whole entry when no property is named', (): void => {
181
181
  cache.addText('note', 'note.txt', 'hello');
182
182
  expect(cache.getItem('note', 4, 'test')).toStrictEqual({ url: 'note.txt', data: 'hello' });
183
183
  });
184
184
 
185
- it('returns null for a key the bucket does not hold', () => {
185
+ it('returns null for a key the bucket does not hold', (): void => {
186
186
  expect(cache.getItem('nope', SOUND, 'test')).toBeNull();
187
187
  expect(cache.getItem('nope', BITMAPFONT, 'test', 'font')).toBeNull();
188
188
  });
189
189
  });
190
190
 
191
- describe('destroy', () => {
192
- it('empties every bucket but the built-in images', () => {
191
+ describe('destroy', (): void => {
192
+ it('empties every bucket but the built-in images', (): void => {
193
193
  cache.addText('note', 'note.txt', 'hello');
194
194
  cache.addSound('shot', 'shot.ogg', new ArrayBuffer(8));
195
195
  cache.destroy();
@@ -6,7 +6,7 @@ import { Frame } from './frame.js';
6
6
  import { FrameData } from './frame_data.js';
7
7
  import { jsonBitmapFont, xmlBitmapFont } from './loader_parser.js';
8
8
  import { Signal } from './signal.js';
9
- import type { BitmapFontData } from './loader_parser.js';
9
+ import type { BitmapFontData, JsonBitmapFontDescriptor } from './loader_parser.js';
10
10
  import type { Game } from './game.js';
11
11
 
12
12
  export const CANVAS = 0;
@@ -272,7 +272,7 @@ export class Cache {
272
272
  const base = new BaseTexture(data);
273
273
  const font =
274
274
  atlasType === 'json'
275
- ? jsonBitmapFont(atlasData, base, xSpacing, ySpacing)
275
+ ? jsonBitmapFont(atlasData as JsonBitmapFontDescriptor, base, xSpacing, ySpacing)
276
276
  : xmlBitmapFont(atlasData as XMLDocument, base, xSpacing, ySpacing);
277
277
  const obj: BitmapFontCacheEntry = { url, data, font, base };
278
278
  this._cache.bitmapFont[key] = obj;
@@ -703,7 +703,7 @@ export class Cache {
703
703
  * @param {string} url - The original URL to resolve.
704
704
  * @returns {string} The resolved URL or null if not found.
705
705
  */
706
- public getURL(url: string) {
706
+ public getURL(url: string): object | null {
707
707
  const resolvedURL = this._resolveURL(url);
708
708
  if (resolvedURL) {
709
709
  return this._urlMap?.[resolvedURL] ?? null;
@@ -31,4 +31,5 @@ export type InterpolationFunction = (v: number[], k: number) => number;
31
31
  * and consumers narrow it by declaring their own display-object subtype — which only holds while
32
32
  * the property stays assignable in both directions, so this one bag has no shape.
33
33
  */
34
+ // eslint-disable-next-line typescript/no-explicit-any -- the whole point of this bag is that it has no shape
34
35
  export type UserData = any;
@@ -15,9 +15,9 @@ class Consumer {
15
15
  }
16
16
  }
17
17
 
18
- describe('callback contexts', () => {
19
- describe('Signal', () => {
20
- it('accepts an arbitrary receiver on add', () => {
18
+ describe('callback contexts', (): void => {
19
+ describe('Signal', (): void => {
20
+ it('accepts an arbitrary receiver on add', (): void => {
21
21
  const signal = new Signal();
22
22
  const consumer = new Consumer();
23
23
  signal.add(consumer.handler, consumer);
@@ -25,7 +25,7 @@ describe('callback contexts', () => {
25
25
  expect(consumer.seen).toBe('payload');
26
26
  });
27
27
 
28
- it('accepts an arbitrary receiver on addOnce', () => {
28
+ it('accepts an arbitrary receiver on addOnce', (): void => {
29
29
  const signal = new Signal();
30
30
  const consumer = new Consumer();
31
31
  signal.addOnce(consumer.handler, consumer);
@@ -33,7 +33,7 @@ describe('callback contexts', () => {
33
33
  expect(consumer.seen).toBe('once');
34
34
  });
35
35
 
36
- it('matches the receiver on remove', () => {
36
+ it('matches the receiver on remove', (): void => {
37
37
  const signal = new Signal();
38
38
  const consumer = new Consumer();
39
39
  signal.add(consumer.handler, consumer);
@@ -41,7 +41,7 @@ describe('callback contexts', () => {
41
41
  expect(signal.getNumListeners()).toBe(0);
42
42
  });
43
43
 
44
- it('matches the receiver on removeAll', () => {
44
+ it('matches the receiver on removeAll', (): void => {
45
45
  const signal = new Signal();
46
46
  const consumer = new Consumer();
47
47
  signal.add(consumer.handler, consumer);
@@ -50,7 +50,7 @@ describe('callback contexts', () => {
50
50
  expect(signal.getNumListeners()).toBe(1);
51
51
  });
52
52
 
53
- it('reports whether a listener is bound to a receiver', () => {
53
+ it('reports whether a listener is bound to a receiver', (): void => {
54
54
  const signal = new Signal();
55
55
  const consumer = new Consumer();
56
56
  signal.add(consumer.handler, consumer);
@@ -58,7 +58,7 @@ describe('callback contexts', () => {
58
58
  expect(signal.has(consumer.handler, new Consumer())).toBe(false);
59
59
  });
60
60
 
61
- it('keeps separate bindings per receiver', () => {
61
+ it('keeps separate bindings per receiver', (): void => {
62
62
  const signal = new Signal();
63
63
  const first = new Consumer();
64
64
  const second = new Consumer();
@@ -1,4 +1,14 @@
1
1
  import { Point } from '../geom/point.js';
2
+
3
+ /** An element rectangle after the cushion has been applied to every edge. */
4
+ export type CalibratedBounds = {
5
+ width: number;
6
+ height: number;
7
+ left: number;
8
+ right: number;
9
+ top: number;
10
+ bottom: number;
11
+ };
2
12
  import type { Device } from './device.js';
3
13
 
4
14
  class VisualBoundsDesktopRectangle {
@@ -170,9 +180,9 @@ class DocumentBoundsRectangle {
170
180
 
171
181
  export class DOM {
172
182
  public treatAsDesktop: boolean;
173
- public visualBounds: any;
174
- public layoutBounds: any;
175
- public documentBounds: any;
183
+ public visualBounds: VisualBoundsDesktopRectangle | VisualBoundsRectangle;
184
+ public layoutBounds: LayoutBoundsDesktopRectangle | LayoutBoundsRectangle;
185
+ public documentBounds: DocumentBoundsRectangle;
176
186
  public scrollXProvider: () => number;
177
187
  public scrollYProvider: () => number;
178
188
 
@@ -222,7 +232,7 @@ export class DOM {
222
232
  * @param {number} cushion - Optional padding to add around the element.
223
233
  * @returns {boolean} True if bounds were successfully retrieved, false otherwise.
224
234
  */
225
- public getBounds(element: HTMLCanvasElement, cushion = 0) {
235
+ public getBounds(element: HTMLCanvasElement, cushion = 0): CalibratedBounds | false {
226
236
  element = element && !element.nodeType ? (element as unknown as HTMLCanvasElement[])[0]! : element;
227
237
  if (!element || element.nodeType !== 1) {
228
238
  return false;
@@ -236,7 +246,7 @@ export class DOM {
236
246
  * @param {number} cushion - Optional padding to add around the rectangle.
237
247
  * @returns {{width: number, height: number, left: number, right: number, top: number, bottom: number}} The calibrated rectangle.
238
248
  */
239
- public calibrate(coords: DOMRect, cushion = 0) {
249
+ public calibrate(coords: DOMRect, cushion = 0): CalibratedBounds {
240
250
  const output = {
241
251
  width: 0,
242
252
  height: 0,
@@ -6,6 +6,7 @@ import { Image } from '../display/image.js';
6
6
  import { Text } from '../display/text.js';
7
7
  import type { Game } from './game.js';
8
8
  import type { SignalListener } from './signal.js';
9
+ import type { TextStyle } from '../display/text.js';
9
10
 
10
11
  export class GameObjectFactory {
11
12
  public game!: Game;
@@ -26,7 +27,13 @@ export class GameObjectFactory {
26
27
  * @param {Group} group - The parent group for the image.
27
28
  * @returns {Image} The created Image object.
28
29
  */
29
- public image(x: number, y: number, key: string, frame: any, group: Group | null = null): Image {
30
+ public image(
31
+ x: number,
32
+ y: number,
33
+ key: string,
34
+ frame: string | number | null = null,
35
+ group: Group | null = null
36
+ ): Image {
30
37
  const target = group ?? this.game.world;
31
38
  return target.add(new Image(this.game, x, y, key, frame));
32
39
  }
@@ -51,7 +58,7 @@ export class GameObjectFactory {
51
58
  * @param {Group | null} group - The parent group for the text.
52
59
  * @returns {Text} The created Text object.
53
60
  */
54
- public text(x: number, y: number, text: any, style: any, group: Group | null = null): Text {
61
+ public text(x: number, y: number, text: string | number, style: TextStyle, group: Group | null = null): Text {
55
62
  const parent = group ?? this.game.world;
56
63
  return parent.add(new Text(this.game, x, y, text, style));
57
64
  }
@@ -10,89 +10,89 @@ const seed = (names: string[]): FrameData => {
10
10
  return data;
11
11
  };
12
12
 
13
- describe('FrameData', () => {
14
- describe('addFrame', () => {
15
- it('assigns a sequential index and registers the name', () => {
13
+ describe('FrameData', (): void => {
14
+ describe('addFrame', (): void => {
15
+ it('assigns a sequential index and registers the name', (): void => {
16
16
  const data = seed(['a', 'b']);
17
- expect(data._frames.map((frame) => frame.index)).toStrictEqual([0, 1]);
17
+ expect(data._frames.map((frame): number => frame.index)).toStrictEqual([0, 1]);
18
18
  expect(data._frameNames).toStrictEqual({ a: 0, b: 1 });
19
19
  });
20
20
 
21
- it('does not register an empty name', () => {
21
+ it('does not register an empty name', (): void => {
22
22
  const data = new FrameData();
23
23
  data.addFrame(new Frame(0, 0, 0, 10, 10, ''));
24
24
  expect(data._frameNames).toStrictEqual({});
25
25
  });
26
26
  });
27
27
 
28
- describe('getFrame', () => {
29
- it('returns the frame at the index', () => {
28
+ describe('getFrame', (): void => {
29
+ it('returns the frame at the index', (): void => {
30
30
  const data = seed(['a', 'b', 'c']);
31
31
  expect(data.getFrame(1).name).toBe('b');
32
32
  });
33
33
 
34
- it('falls back to the first frame when the index is out of range', () => {
34
+ it('falls back to the first frame when the index is out of range', (): void => {
35
35
  const data = seed(['a', 'b']);
36
36
  expect(data.getFrame(9).name).toBe('a');
37
37
  });
38
38
  });
39
39
 
40
- describe('getFrameByName', () => {
41
- it('finds a registered frame', () => {
40
+ describe('getFrameByName', (): void => {
41
+ it('finds a registered frame', (): void => {
42
42
  const data = seed(['a', 'b']);
43
43
  expect(data.getFrameByName('b')?.index).toBe(1);
44
44
  });
45
45
 
46
- it('returns null for an unknown name', () => {
46
+ it('returns null for an unknown name', (): void => {
47
47
  const data = seed(['a']);
48
48
  expect(data.getFrameByName('missing')).toBeNull();
49
49
  });
50
50
 
51
- it('returns null when the name maps to a frame that is gone', () => {
51
+ it('returns null when the name maps to a frame that is gone', (): void => {
52
52
  const data = seed(['a']);
53
53
  data._frames.length = 0;
54
54
  expect(data.getFrameByName('a')).toBeNull();
55
55
  });
56
56
  });
57
57
 
58
- describe('checkFrameName', () => {
59
- it('distinguishes known from unknown names', () => {
58
+ describe('checkFrameName', (): void => {
59
+ it('distinguishes known from unknown names', (): void => {
60
60
  const data = seed(['a']);
61
61
  expect(data.checkFrameName('a')).toBe(true);
62
62
  expect(data.checkFrameName('b')).toBe(false);
63
63
  });
64
64
  });
65
65
 
66
- describe('getFrameRange', () => {
67
- it('collects the inclusive range', () => {
66
+ describe('getFrameRange', (): void => {
67
+ it('collects the inclusive range', (): void => {
68
68
  const data = seed(['a', 'b', 'c', 'd']);
69
- expect(data.getFrameRange(1, 2).map((frame) => frame.name)).toStrictEqual(['b', 'c']);
69
+ expect(data.getFrameRange(1, 2).map((frame): string => frame.name)).toStrictEqual(['b', 'c']);
70
70
  });
71
71
 
72
- it('appends into a supplied output array', () => {
72
+ it('appends into a supplied output array', (): void => {
73
73
  const data = seed(['a', 'b']);
74
74
  const output = [data.getFrame(0)];
75
75
  expect(data.getFrameRange(1, 1, output)).toHaveLength(2);
76
76
  });
77
77
  });
78
78
 
79
- describe('getFrameIndexes', () => {
80
- it('maps numeric indexes through', () => {
79
+ describe('getFrameIndexes', (): void => {
80
+ it('maps numeric indexes through', (): void => {
81
81
  const data = seed(['a', 'b', 'c']);
82
82
  expect(data.getFrameIndexes([0, 2])).toStrictEqual([0, 2]);
83
83
  });
84
84
 
85
- it('maps names when numeric indexing is off', () => {
85
+ it('maps names when numeric indexing is off', (): void => {
86
86
  const data = seed(['a', 'b', 'c']);
87
87
  expect(data.getFrameIndexes(['c', 'a'], false)).toStrictEqual([2, 0]);
88
88
  });
89
89
 
90
- it('skips names that do not resolve', () => {
90
+ it('skips names that do not resolve', (): void => {
91
91
  const data = seed(['a']);
92
92
  expect(data.getFrameIndexes(['a', 'missing'], false)).toStrictEqual([0]);
93
93
  });
94
94
 
95
- it('returns every index when given no frames', () => {
95
+ it('returns every index when given no frames', (): void => {
96
96
  const data = seed(['a', 'b', 'c']);
97
97
  expect(data.getFrameIndexes([])).toStrictEqual([0, 1, 2]);
98
98
  });