@vpmedia/phaser 1.117.0 → 1.118.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 (37) hide show
  1. package/dist/index.js +140 -134
  2. package/dist/index.js.map +1 -1
  3. package/dist/phaser/core/animation_manager.d.ts +1 -1
  4. package/dist/phaser/core/animation_manager.d.ts.map +1 -1
  5. package/dist/phaser/core/cache.d.ts +70 -42
  6. package/dist/phaser/core/cache.d.ts.map +1 -1
  7. package/dist/phaser/core/input.d.ts +1 -1
  8. package/dist/phaser/core/input.d.ts.map +1 -1
  9. package/dist/phaser/core/input_mspointer.d.ts +8 -7
  10. package/dist/phaser/core/input_mspointer.d.ts.map +1 -1
  11. package/dist/phaser/core/loader.d.ts +30 -1
  12. package/dist/phaser/core/loader.d.ts.map +1 -1
  13. package/dist/phaser/core/loader_parser.d.ts +24 -4
  14. package/dist/phaser/core/loader_parser.d.ts.map +1 -1
  15. package/dist/phaser/core/sound.d.ts +13 -3
  16. package/dist/phaser/core/sound.d.ts.map +1 -1
  17. package/dist/phaser/core/tween.d.ts +3 -3
  18. package/dist/phaser/core/tween.d.ts.map +1 -1
  19. package/dist/phaser/core/tween_manager.d.ts +8 -6
  20. package/dist/phaser/core/tween_manager.d.ts.map +1 -1
  21. package/dist/phaser/display/bitmap_text.d.ts +13 -8
  22. package/dist/phaser/display/bitmap_text.d.ts.map +1 -1
  23. package/package.json +1 -1
  24. package/src/phaser/core/animation_manager.ts +1 -1
  25. package/src/phaser/core/cache.test.ts +201 -0
  26. package/src/phaser/core/cache.ts +126 -86
  27. package/src/phaser/core/input.ts +1 -1
  28. package/src/phaser/core/input_mspointer.ts +10 -13
  29. package/src/phaser/core/loader.ts +82 -42
  30. package/src/phaser/core/loader_parser.test.ts +115 -0
  31. package/src/phaser/core/loader_parser.ts +64 -36
  32. package/src/phaser/core/sound.ts +29 -17
  33. package/src/phaser/core/sound_manager.ts +1 -1
  34. package/src/phaser/core/tween.ts +6 -6
  35. package/src/phaser/core/tween_manager.ts +42 -35
  36. package/src/phaser/display/bitmap_text.test.ts +212 -0
  37. package/src/phaser/display/bitmap_text.ts +39 -24
@@ -1,10 +1,12 @@
1
1
  import type { Game } from './game.js';
2
2
  import { Tween } from './tween.js';
3
+ /** What a tween can be attached to: any object, or a list of them. */
4
+ export type TweenTarget = object | object[];
3
5
  export declare class TweenManager {
4
6
  game: Game;
5
- _tweens: any;
6
- _add: any;
7
- easeMap: any;
7
+ _tweens: Tween[];
8
+ _add: Tween[];
9
+ easeMap: Record<string, (k: number) => number>;
8
10
  /**
9
11
  * Creates a new TweenManager instance.
10
12
  * @param {Game} game - The game instance this manager belongs to.
@@ -14,7 +16,7 @@ export declare class TweenManager {
14
16
  * Get all tweens managed by this manager.
15
17
  * @returns {Tween[]} An array of all active tweens.
16
18
  */
17
- getAll(): any;
19
+ getAll(): Tween[];
18
20
  /**
19
21
  * Remove all tweens from the manager.
20
22
  * This method removes all active and pending tweens.
@@ -25,7 +27,7 @@ export declare class TweenManager {
25
27
  * @param {object} obj - The object to remove tweens from.
26
28
  * @param {object[]} children - Optional array of child objects to remove tweens from.
27
29
  */
28
- removeFrom(obj: any, children?: any[] | null): void;
30
+ removeFrom(obj: TweenTarget, children?: object[] | null): void;
29
31
  /**
30
32
  * Add a tween to the manager.
31
33
  * @param {Tween} tween - The tween to add.
@@ -36,7 +38,7 @@ export declare class TweenManager {
36
38
  * @param {object} object - The object to create a tween for.
37
39
  * @returns {Tween} The created Tween object.
38
40
  */
39
- create(object: any): Tween;
41
+ create(object: TweenTarget): Tween;
40
42
  /**
41
43
  * Remove a tween from the manager.
42
44
  * @param {Tween | null | undefined} tween - The tween to remove.
@@ -1 +1 @@
1
- {"version":3,"file":"tween_manager.d.ts","sourceRoot":"","sources":["../../../src/phaser/core/tween_manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAmCnC,qBAAa,YAAY;IAChB,IAAI,EAAG,IAAI,CAAC;IACZ,OAAO,EAAG,GAAG,CAAC;IACd,IAAI,EAAG,GAAG,CAAC;IACX,OAAO,EAAG,GAAG,CAAC;IACrB;;;OAGG;IACH,YAAmB,IAAI,EAAE,IAAI,EAqD5B;IAED;;;OAGG;IACI,MAAM,QAEZ;IAED;;;OAGG;IACI,SAAS,IAAI,IAAI,CAKvB;IAED;;;;OAIG;IACI,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,GAAE,GAAG,EAAE,GAAG,IAAW,GAAG,IAAI,CAuB/D;IAED;;;OAGG;IACI,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAG7B;IAED;;;;OAIG;IACI,MAAM,CAAC,MAAM,EAAE,GAAG,GAAG,KAAK,CAEhC;IAED;;;OAGG;IACI,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAUnD;IAED;;;OAGG;IACI,MAAM,IAAI,OAAO,CAqBvB;IAED;;;;OAIG;IACI,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAE1C;IAED;;;OAGG;IACI,SAAS,IAAI,IAAI,CAIvB;IAED;;;OAGG;IACI,UAAU,IAAI,IAAI,CAIxB;IAED;;;OAGG;IACI,QAAQ,IAAI,IAAI,CAItB;IAED;;;OAGG;IACI,SAAS,IAAI,IAAI,CAIvB;CACF"}
1
+ {"version":3,"file":"tween_manager.d.ts","sourceRoot":"","sources":["../../../src/phaser/core/tween_manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAmCnC,sEAAsE;AACtE,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAE5C,qBAAa,YAAY;IAChB,IAAI,EAAG,IAAI,CAAC;IACZ,OAAO,EAAG,KAAK,EAAE,CAAC;IAClB,IAAI,EAAG,KAAK,EAAE,CAAC;IACf,OAAO,EAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IACvD;;;OAGG;IACH,YAAmB,IAAI,EAAE,IAAI,EAqD5B;IAED;;;OAGG;IACI,MAAM,YAEZ;IAED;;;OAGG;IACI,SAAS,IAAI,IAAI,CAKvB;IAED;;;;OAIG;IACI,UAAU,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,GAAE,MAAM,EAAE,GAAG,IAAW,GAAG,IAAI,CAwB1E;IAED;;;OAGG;IACI,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAG7B;IAED;;;;OAIG;IACI,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,CAExC;IAED;;;OAGG;IACI,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAanD;IAED;;;OAGG;IACI,MAAM,IAAI,OAAO,CAqBvB;IAED;;;;OAIG;IACI,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAE1C;IAED;;;OAGG;IACI,SAAS,IAAI,IAAI,CAIvB;IAED;;;OAGG;IACI,UAAU,IAAI,IAAI,CAIxB;IAED;;;OAGG;IACI,QAAQ,IAAI,IAAI,CAItB;IAED;;;OAGG;IACI,SAAS,IAAI,IAAI,CAIvB;CACF"}
@@ -1,7 +1,17 @@
1
1
  import { Point } from '../geom/point.js';
2
2
  import { DisplayObject } from './display_object.js';
3
3
  import { Image } from './image.js';
4
+ import type { BitmapFontCacheEntry } from '../core/cache.js';
4
5
  import type { Game } from '../core/game.js';
6
+ import type { BitmapFontData } from '../core/loader_parser.js';
7
+ /** One measured line of bitmap text: its width, its content and where each glyph starts. */
8
+ export type BitmapTextLine = {
9
+ width: number;
10
+ text: string;
11
+ end: boolean;
12
+ chars: number[];
13
+ y: number;
14
+ };
5
15
  export declare class BitmapText extends DisplayObject {
6
16
  type: number;
7
17
  pendingDestroy: boolean;
@@ -12,7 +22,7 @@ export declare class BitmapText extends DisplayObject {
12
22
  _glyphs: Image[];
13
23
  _maxWidth: number;
14
24
  _text: string;
15
- _data: any;
25
+ _data: BitmapFontCacheEntry | null;
16
26
  _font: string;
17
27
  _fontSize: number;
18
28
  _align: string;
@@ -49,12 +59,7 @@ export declare class BitmapText extends DisplayObject {
49
59
  * @param {string} text - The text to scan.
50
60
  * @returns {{width: number, text: string, end: boolean, chars: number[]}} An object containing the width, processed text, end status, and character positions.
51
61
  */
52
- scanLine(data: any, scale: number, text: string): {
53
- width: number;
54
- text: string;
55
- end: boolean;
56
- chars: number[];
57
- };
62
+ scanLine(data: BitmapFontData, scale: number, text: string): Omit<BitmapTextLine, 'y'>;
58
63
  /**
59
64
  * Cleans the provided text by removing invalid characters and replacing them with a specified character.
60
65
  * @param {string} text - The text to clean.
@@ -131,7 +136,7 @@ export declare class BitmapText extends DisplayObject {
131
136
  * Sets the font size of this bitmap text.
132
137
  * @param {number} value - The new font size to use.
133
138
  */
134
- set fontSize(value: any);
139
+ set fontSize(value: number | string);
135
140
  /**
136
141
  * Gets the text content of this bitmap text.
137
142
  * @returns {string} The current text content.
@@ -1 +1 @@
1
- {"version":3,"file":"bitmap_text.d.ts","sourceRoot":"","sources":["../../../src/phaser/display/bitmap_text.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bitmap_text.d.ts","sourceRoot":"","sources":["../../../src/phaser/display/bitmap_text.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpmedia/phaser",
3
- "version": "1.117.0",
3
+ "version": "1.118.0",
4
4
  "description": "@vpmedia/phaser is the modern ECMAScript port of the popular Phaser game engine v2.6.2",
5
5
  "author": "Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)",
6
6
  "license": "MIT",
@@ -53,7 +53,7 @@ export class AnimationManager {
53
53
  * @param {string|number} frame - The frame index or name to set as current.
54
54
  * @returns {boolean} True if the frame data was loaded successfully, false otherwise.
55
55
  */
56
- public loadFrameData(frameData: FrameData, frame: string | number): boolean {
56
+ public loadFrameData(frameData: FrameData | null, frame: string | number): boolean {
57
57
  if (!frameData) {
58
58
  return false;
59
59
  }
@@ -0,0 +1,201 @@
1
+ import { beforeEach, describe, expect, it } from 'vitest';
2
+ import { SCALE_LINEAR } from './const.js';
3
+ import { BITMAPFONT, Cache, IMAGE, SOUND } from './cache.js';
4
+ import { getRegistry } from './registry.js';
5
+ import type { Game } from './game.js';
6
+
7
+ const createGame = (): Game =>
8
+ ({
9
+ logger: { warn: (): void => undefined },
10
+ load: { baseURL: '' },
11
+ sound: { isLocked: false },
12
+ }) as unknown as Game;
13
+
14
+ const createImage = (width = 4, height = 4): HTMLImageElement => {
15
+ const img = new Image();
16
+ Object.defineProperty(img, 'width', { value: width });
17
+ Object.defineProperty(img, 'height', { value: height });
18
+ return img;
19
+ };
20
+
21
+ const FONT_XML = `<?xml version="1.0"?>
22
+ <font>
23
+ <info face="Arial" size="32" />
24
+ <common lineHeight="40" />
25
+ <chars>
26
+ <char id="65" x="0" y="0" width="20" height="30" xoffset="1" yoffset="2" xadvance="21" />
27
+ </chars>
28
+ </font>`;
29
+
30
+ describe('Cache', () => {
31
+ let cache: Cache;
32
+
33
+ beforeEach(() => {
34
+ getRegistry().TEXTURE_SCALE_MODE = SCALE_LINEAR;
35
+ cache = new Cache(createGame());
36
+ });
37
+
38
+ describe('images', () => {
39
+ it('seeds the default and missing images', () => {
40
+ expect(cache.checkImageKey('__default')).toBe(true);
41
+ expect(cache.checkImageKey('__missing')).toBe(true);
42
+ });
43
+
44
+ it('keeps the default image out of the reported keys', () => {
45
+ expect(cache.getKeys(IMAGE)).toStrictEqual([]);
46
+ });
47
+
48
+ it('returns the source bitmap by default and the whole entry when asked', () => {
49
+ const source = createImage();
50
+ cache.addImage('logo', 'logo.png', source);
51
+ expect(cache.getImage('logo')).toBe(source);
52
+ expect(cache.getImage('logo', true).key).toBe('logo');
53
+ });
54
+
55
+ it('falls back to the missing image for an unknown key', () => {
56
+ expect(cache.getImage('nope', true).key).toBe('__missing');
57
+ });
58
+
59
+ it('gives an image one frame covering the whole bitmap', () => {
60
+ cache.addImage('logo', 'logo.png', createImage(64, 32));
61
+ const frame = cache.getFrameByIndex('logo', 0);
62
+ expect(frame?.width).toBe(64);
63
+ expect(frame?.height).toBe(32);
64
+ expect(cache.getFrameCount('logo')).toBe(1);
65
+ });
66
+
67
+ it('reports no frames for a key it does not hold', () => {
68
+ expect(cache.getFrameData('nope')).toBeNull();
69
+ expect(cache.getFrameCount('nope')).toBe(0);
70
+ expect(cache.hasFrameData('nope')).toBe(false);
71
+ });
72
+
73
+ it('drops an image when it is removed', () => {
74
+ cache.addImage('logo', 'logo.png', createImage());
75
+ cache.removeImage('logo');
76
+ expect(cache.checkImageKey('logo')).toBe(false);
77
+ });
78
+
79
+ it('replaces an image registered twice under the same key', () => {
80
+ cache.addImage('logo', 'a.png', createImage(4, 4));
81
+ const second = createImage(8, 8);
82
+ cache.addImage('logo', 'b.png', second);
83
+ expect(cache.getImage('logo')).toBe(second);
84
+ });
85
+
86
+ it('clears the GL textures of every cached image', () => {
87
+ cache.addImage('logo', 'logo.png', createImage());
88
+ const entry = cache.getImage('logo', true);
89
+ entry.base._glTextures = [null];
90
+ cache.clearGLTextures();
91
+ expect(entry.base._glTextures).toStrictEqual([]);
92
+ });
93
+ });
94
+
95
+ describe('sounds', () => {
96
+ it('stores a sound as undecoded', () => {
97
+ cache.addSound('shot', 'shot.ogg', new ArrayBuffer(8));
98
+ expect(cache.isSoundDecoded('shot')).toBe(false);
99
+ expect(cache.isSoundReady('shot')).toBe(false);
100
+ });
101
+
102
+ it('reports an unknown sound as neither decoded nor ready', () => {
103
+ expect(cache.isSoundDecoded('nope')).toBeNull();
104
+ expect(cache.isSoundReady('nope')).toBe(false);
105
+ });
106
+
107
+ it('updates a single property of a cached sound', () => {
108
+ cache.addSound('shot', 'shot.ogg', new ArrayBuffer(8));
109
+ cache.updateSound('shot', 'isDecoding', true);
110
+ expect(cache.getSound('shot')?.isDecoding).toBe(true);
111
+ });
112
+
113
+ it('swaps in the decoded buffer and marks the sound ready', () => {
114
+ cache.addSound('shot', 'shot.ogg', new ArrayBuffer(8));
115
+ const buffer = { duration: 1.5 } as AudioBuffer;
116
+ cache.decodedSound('shot', buffer);
117
+ expect(cache.getSoundData('shot')).toBe(buffer);
118
+ expect(cache.isSoundDecoded('shot')).toBe(true);
119
+ expect(cache.isSoundReady('shot')).toBe(true);
120
+ });
121
+
122
+ it('ignores a decode result for a sound it never held', () => {
123
+ expect(() => {
124
+ cache.decodedSound('nope', {} as AudioBuffer);
125
+ }).not.toThrow();
126
+ });
127
+
128
+ it('drops a sound when it is removed', () => {
129
+ cache.addSound('shot', 'shot.ogg', new ArrayBuffer(8));
130
+ cache.removeSound('shot');
131
+ expect(cache.getSound('shot')).toBeNull();
132
+ });
133
+ });
134
+
135
+ describe('data', () => {
136
+ it('round-trips text', () => {
137
+ cache.addText('note', 'note.txt', 'hello');
138
+ expect(cache.getText('note')).toBe('hello');
139
+ cache.removeText('note');
140
+ expect(cache.getText('note')).toBeNull();
141
+ });
142
+
143
+ it('round-trips JSON', () => {
144
+ cache.addJSON('config', 'config.json', { a: 1 });
145
+ expect(cache.getJSON('config')).toStrictEqual({ a: 1 });
146
+ });
147
+
148
+ it('hands back a detached copy when a clone is asked for', () => {
149
+ const data = { a: 1 };
150
+ cache.addJSON('config', 'config.json', data);
151
+ const clone = cache.getJSON<{ a: number }>('config', true);
152
+ expect(clone).toStrictEqual(data);
153
+ expect(clone).not.toBe(data);
154
+ });
155
+
156
+ it('round-trips XML', () => {
157
+ const xml = new DOMParser().parseFromString('<root/>', 'text/xml');
158
+ cache.addXML('doc', 'doc.xml', xml);
159
+ expect(cache.getXML('doc')).toBe(xml);
160
+ });
161
+ });
162
+
163
+ describe('bitmap fonts', () => {
164
+ it('parses the descriptor and keeps it beside the atlas', () => {
165
+ const xml = new DOMParser().parseFromString(FONT_XML, 'text/xml');
166
+ cache.addBitmapFont('arial', 'arial.png', createImage(256, 256), xml, 'xml');
167
+ const entry = cache.getBitmapFont('arial');
168
+ expect(entry?.font.font).toBe('Arial');
169
+ expect(entry?.font.chars[65]?.xAdvance).toBe(21);
170
+ expect(entry?.base).toBeDefined();
171
+ });
172
+
173
+ it('reports a font it does not hold as absent', () => {
174
+ expect(cache.checkBitmapFontKey('nope')).toBe(false);
175
+ expect(cache.getBitmapFont('nope')).toBeNull();
176
+ });
177
+ });
178
+
179
+ describe('getItem', () => {
180
+ it('returns the whole entry when no property is named', () => {
181
+ cache.addText('note', 'note.txt', 'hello');
182
+ expect(cache.getItem('note', 4, 'test')).toStrictEqual({ url: 'note.txt', data: 'hello' });
183
+ });
184
+
185
+ it('returns null for a key the bucket does not hold', () => {
186
+ expect(cache.getItem('nope', SOUND, 'test')).toBeNull();
187
+ expect(cache.getItem('nope', BITMAPFONT, 'test', 'font')).toBeNull();
188
+ });
189
+ });
190
+
191
+ describe('destroy', () => {
192
+ it('empties every bucket but the built-in images', () => {
193
+ cache.addText('note', 'note.txt', 'hello');
194
+ cache.addSound('shot', 'shot.ogg', new ArrayBuffer(8));
195
+ cache.destroy();
196
+ expect(cache.getText('note')).toBeNull();
197
+ expect(cache.getSound('shot')).toBeNull();
198
+ expect(cache.checkImageKey('__default')).toBe(true);
199
+ });
200
+ });
201
+ });