@vpmedia/phaser 1.117.0 → 1.119.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +163 -158
- package/dist/index.js.map +1 -1
- package/dist/phaser/core/animation_manager.d.ts +1 -1
- package/dist/phaser/core/animation_manager.d.ts.map +1 -1
- package/dist/phaser/core/cache.d.ts +70 -42
- package/dist/phaser/core/cache.d.ts.map +1 -1
- package/dist/phaser/core/game.d.ts +34 -8
- package/dist/phaser/core/game.d.ts.map +1 -1
- package/dist/phaser/core/input.d.ts +1 -1
- package/dist/phaser/core/input.d.ts.map +1 -1
- package/dist/phaser/core/input_mspointer.d.ts +8 -7
- package/dist/phaser/core/input_mspointer.d.ts.map +1 -1
- package/dist/phaser/core/loader.d.ts +30 -1
- package/dist/phaser/core/loader.d.ts.map +1 -1
- package/dist/phaser/core/loader_parser.d.ts +24 -4
- package/dist/phaser/core/loader_parser.d.ts.map +1 -1
- package/dist/phaser/core/scene.d.ts +3 -2
- package/dist/phaser/core/scene.d.ts.map +1 -1
- package/dist/phaser/core/scene_manager.d.ts +28 -17
- package/dist/phaser/core/scene_manager.d.ts.map +1 -1
- package/dist/phaser/core/sound.d.ts +13 -3
- package/dist/phaser/core/sound.d.ts.map +1 -1
- package/dist/phaser/core/tween.d.ts +3 -3
- package/dist/phaser/core/tween.d.ts.map +1 -1
- package/dist/phaser/core/tween_manager.d.ts +8 -6
- package/dist/phaser/core/tween_manager.d.ts.map +1 -1
- package/dist/phaser/display/bitmap_text.d.ts +13 -8
- package/dist/phaser/display/bitmap_text.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/phaser/core/animation_manager.ts +1 -1
- package/src/phaser/core/cache.test.ts +201 -0
- package/src/phaser/core/cache.ts +126 -86
- package/src/phaser/core/game.ts +45 -22
- package/src/phaser/core/input.ts +1 -1
- package/src/phaser/core/input_mspointer.ts +10 -13
- package/src/phaser/core/loader.ts +82 -42
- package/src/phaser/core/loader_parser.test.ts +115 -0
- package/src/phaser/core/loader_parser.ts +64 -36
- package/src/phaser/core/scene.ts +4 -2
- package/src/phaser/core/scene_manager.test.ts +193 -0
- package/src/phaser/core/scene_manager.ts +51 -36
- package/src/phaser/core/sound.ts +29 -17
- package/src/phaser/core/sound_manager.ts +1 -1
- package/src/phaser/core/tween.ts +6 -6
- package/src/phaser/core/tween_manager.ts +42 -35
- package/src/phaser/display/bitmap_text.test.ts +212 -0
- package/src/phaser/display/bitmap_text.ts +39 -24
- package/src/phaser/display/webgl/renderer.ts +1 -1
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { Scene } from './scene.js';
|
|
3
|
+
import { SceneManager } from './scene_manager.js';
|
|
4
|
+
import type { Game } from './game.js';
|
|
5
|
+
import type { SceneState } from './scene_manager.js';
|
|
6
|
+
|
|
7
|
+
const createGame = (isBooted = true): Game =>
|
|
8
|
+
({
|
|
9
|
+
isBooted,
|
|
10
|
+
isKickStart: false,
|
|
11
|
+
world: { x: 0, y: 0, destroy: vi.fn() },
|
|
12
|
+
tweens: { removeAll: vi.fn() },
|
|
13
|
+
input: { reset: vi.fn() },
|
|
14
|
+
time: { removeAll: vi.fn() },
|
|
15
|
+
scale: { reset: vi.fn() },
|
|
16
|
+
cache: { destroy: vi.fn() },
|
|
17
|
+
load: { reset: vi.fn(), start: vi.fn(), totalQueuedFiles: (): number => 0, totalQueuedPacks: (): number => 0 },
|
|
18
|
+
}) as unknown as Game;
|
|
19
|
+
|
|
20
|
+
const createManager = (pendingState: ConstructorParameters<typeof SceneManager>[1] = null): SceneManager =>
|
|
21
|
+
new SceneManager(createGame(), pendingState);
|
|
22
|
+
|
|
23
|
+
describe('SceneManager', () => {
|
|
24
|
+
describe('add', () => {
|
|
25
|
+
it('takes a plain hook object and links the game onto it', () => {
|
|
26
|
+
const manager = createManager();
|
|
27
|
+
const state: SceneState = { create: vi.fn<() => void>() };
|
|
28
|
+
expect(manager.add('menu', state)).toBe(state);
|
|
29
|
+
expect(state.game).toBeDefined();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('builds a state from a constructor', () => {
|
|
33
|
+
const manager = createManager();
|
|
34
|
+
class Menu extends Scene {}
|
|
35
|
+
expect(manager.add('menu', Menu)).toBeInstanceOf(Menu);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('takes a scene instance as-is', () => {
|
|
39
|
+
const manager = createManager();
|
|
40
|
+
const scene = new Scene();
|
|
41
|
+
expect(manager.add('menu', scene)).toBe(scene);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('queues the state when the game has not booted', () => {
|
|
45
|
+
const manager = new SceneManager(createGame(false), null);
|
|
46
|
+
manager.add('menu', { create: vi.fn<() => void>() }, true);
|
|
47
|
+
expect(manager._pendingState).toBe('menu');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('starts the state right away once the game has booted', () => {
|
|
51
|
+
const manager = createManager();
|
|
52
|
+
manager.add('menu', { create: vi.fn<() => void>() }, true);
|
|
53
|
+
expect(manager._pendingState).toBe('menu');
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('boot', () => {
|
|
58
|
+
it('registers a state given as an object under the default key', () => {
|
|
59
|
+
const manager = createManager({ create: vi.fn<() => void>() });
|
|
60
|
+
manager.boot();
|
|
61
|
+
expect(manager.states['default']).toBeDefined();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('leaves a state given by key alone', () => {
|
|
65
|
+
const manager = createManager('menu');
|
|
66
|
+
manager.boot();
|
|
67
|
+
expect(manager.states['default']).toBeUndefined();
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe('checkState', () => {
|
|
72
|
+
it('accepts a state carrying any of the lifecycle hooks', () => {
|
|
73
|
+
const manager = createManager();
|
|
74
|
+
manager.add('menu', { update: vi.fn<() => void>() });
|
|
75
|
+
expect(manager.checkState('menu')).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('rejects a state with no hooks at all', () => {
|
|
79
|
+
const manager = createManager();
|
|
80
|
+
manager.add('menu', {});
|
|
81
|
+
expect(manager.checkState('menu')).toBe(false);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('rejects a key it does not hold', () => {
|
|
85
|
+
expect(createManager().checkState('nope')).toBe(false);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
describe('setCurrentState', () => {
|
|
90
|
+
it('binds the hooks the state provides and leaves the rest null', () => {
|
|
91
|
+
const manager = createManager();
|
|
92
|
+
const create = vi.fn<() => void>();
|
|
93
|
+
manager.add('menu', { create });
|
|
94
|
+
manager.setCurrentState('menu');
|
|
95
|
+
expect(manager.current).toBe('menu');
|
|
96
|
+
expect(manager.onCreateCallback).toBe(create);
|
|
97
|
+
expect(manager.onUpdateCallback).toBeNull();
|
|
98
|
+
expect(manager.onPreloadCallback).toBeNull();
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('falls back to a no-op for init and shutdown', () => {
|
|
102
|
+
const manager = createManager();
|
|
103
|
+
manager.add('menu', {});
|
|
104
|
+
manager.setCurrentState('menu');
|
|
105
|
+
expect(manager.onInitCallback).toBe(manager.dummy);
|
|
106
|
+
expect(manager.onShutDownCallback).toBe(manager.dummy);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('calls init with the arguments start was given', () => {
|
|
110
|
+
const manager = createManager();
|
|
111
|
+
const init = vi.fn<() => void>();
|
|
112
|
+
manager.add('menu', { init, update: vi.fn<() => void>() });
|
|
113
|
+
manager.start('menu', true, false, 'a', 1);
|
|
114
|
+
manager.setCurrentState('menu');
|
|
115
|
+
expect(init).toHaveBeenCalledWith('a', 1);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('stamps the key onto the state', () => {
|
|
119
|
+
const manager = createManager();
|
|
120
|
+
const state: SceneState = { create: vi.fn<() => void>() };
|
|
121
|
+
manager.add('menu', state);
|
|
122
|
+
manager.setCurrentState('menu');
|
|
123
|
+
expect(state.key).toBe('menu');
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe('start', () => {
|
|
128
|
+
it('ignores a key with no lifecycle hooks', () => {
|
|
129
|
+
const manager = createManager();
|
|
130
|
+
manager.add('menu', {});
|
|
131
|
+
manager.start('menu');
|
|
132
|
+
expect(manager._pendingState).toBeNull();
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe('update', () => {
|
|
137
|
+
it('runs the update hook only once the scene has been created', () => {
|
|
138
|
+
const manager = createManager();
|
|
139
|
+
const update = vi.fn<() => void>();
|
|
140
|
+
manager.add('menu', { update });
|
|
141
|
+
manager.setCurrentState('menu');
|
|
142
|
+
manager.update();
|
|
143
|
+
expect(update).not.toHaveBeenCalled();
|
|
144
|
+
manager.loadComplete();
|
|
145
|
+
manager.update();
|
|
146
|
+
expect(update).toHaveBeenCalledTimes(1);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('runs the create hook exactly once', () => {
|
|
150
|
+
const manager = createManager();
|
|
151
|
+
const create = vi.fn<() => void>();
|
|
152
|
+
manager.add('menu', { create });
|
|
153
|
+
manager.setCurrentState('menu');
|
|
154
|
+
manager.loadComplete();
|
|
155
|
+
manager.loadComplete();
|
|
156
|
+
expect(create).toHaveBeenCalledTimes(1);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe('resize', () => {
|
|
161
|
+
it('passes the new size to the scene', () => {
|
|
162
|
+
const manager = createManager();
|
|
163
|
+
const resize = vi.fn<(width: number, height: number) => void>();
|
|
164
|
+
manager.add('menu', { resize });
|
|
165
|
+
manager.setCurrentState('menu');
|
|
166
|
+
manager.resize(320, 240);
|
|
167
|
+
expect(resize).toHaveBeenCalledWith(320, 240);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
describe('remove', () => {
|
|
172
|
+
it('drops the state and unbinds its hooks when it is current', () => {
|
|
173
|
+
const manager = createManager();
|
|
174
|
+
manager.add('menu', { create: vi.fn<() => void>() });
|
|
175
|
+
manager.setCurrentState('menu');
|
|
176
|
+
manager.remove('menu');
|
|
177
|
+
expect(manager.states['menu']).toBeUndefined();
|
|
178
|
+
expect(manager.onCreateCallback).toBeNull();
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
describe('destroy', () => {
|
|
183
|
+
it('empties the manager', () => {
|
|
184
|
+
const manager = createManager();
|
|
185
|
+
manager.add('menu', { create: vi.fn<() => void>(), shutdown: vi.fn<() => void>() });
|
|
186
|
+
manager.setCurrentState('menu');
|
|
187
|
+
manager.destroy();
|
|
188
|
+
expect(manager.states).toStrictEqual({});
|
|
189
|
+
expect(manager.current).toBe('');
|
|
190
|
+
expect(manager._pendingState).toBeNull();
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
});
|
|
@@ -7,34 +7,47 @@ export type SceneHooks = {
|
|
|
7
7
|
preload?: () => void;
|
|
8
8
|
create?: () => void;
|
|
9
9
|
update?: () => void;
|
|
10
|
+
render?: () => void;
|
|
10
11
|
resize?: (width: number, height: number) => void;
|
|
11
12
|
pauseUpdate?: () => void;
|
|
12
13
|
shutdown?: () => void;
|
|
13
14
|
};
|
|
14
15
|
|
|
16
|
+
/** A scene once the manager holds it: its hooks plus the wiring the manager adds. */
|
|
17
|
+
export type SceneState = SceneHooks & {
|
|
18
|
+
game?: Game | null;
|
|
19
|
+
key?: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/** What the manager accepts as a scene: an instance, a plain hook object, or a class to build one. */
|
|
23
|
+
export type SceneDefinition = SceneState | (new (game: Game) => SceneState);
|
|
24
|
+
|
|
25
|
+
/** A hook invoked with the scene as its receiver and the game as its argument. */
|
|
26
|
+
type SceneCallback = (game: Game) => void;
|
|
27
|
+
|
|
15
28
|
export class SceneManager {
|
|
16
29
|
public game!: Game;
|
|
17
|
-
public states!:
|
|
18
|
-
public _pendingState!:
|
|
19
|
-
public _clearWorld!:
|
|
20
|
-
public _clearCache!:
|
|
21
|
-
public _created!:
|
|
22
|
-
public _args!:
|
|
30
|
+
public states!: Record<string, SceneState>;
|
|
31
|
+
public _pendingState!: SceneDefinition | string | null;
|
|
32
|
+
public _clearWorld!: boolean;
|
|
33
|
+
public _clearCache!: boolean;
|
|
34
|
+
public _created!: boolean;
|
|
35
|
+
public _args!: unknown[];
|
|
23
36
|
public current!: string;
|
|
24
|
-
public onInitCallback!:
|
|
25
|
-
public onPreloadCallback!:
|
|
26
|
-
public onCreateCallback!:
|
|
27
|
-
public onUpdateCallback!:
|
|
28
|
-
public onResizeCallback!:
|
|
29
|
-
public onPauseUpdateCallback!:
|
|
30
|
-
public onShutDownCallback!:
|
|
31
|
-
public callbackContext!:
|
|
37
|
+
public onInitCallback!: ((...args: unknown[]) => void) | null;
|
|
38
|
+
public onPreloadCallback!: SceneCallback | null;
|
|
39
|
+
public onCreateCallback!: SceneCallback | null;
|
|
40
|
+
public onUpdateCallback!: SceneCallback | null;
|
|
41
|
+
public onResizeCallback!: ((width: number, height: number) => void) | null;
|
|
42
|
+
public onPauseUpdateCallback!: SceneCallback | null;
|
|
43
|
+
public onShutDownCallback!: SceneCallback | null;
|
|
44
|
+
public callbackContext!: SceneState;
|
|
32
45
|
/**
|
|
33
46
|
* Creates a new SceneManager instance.
|
|
34
47
|
* @param {Game} game - The game instance this manager belongs to.
|
|
35
48
|
* @param {string} pendingState - The state to load when the game boots.
|
|
36
49
|
*/
|
|
37
|
-
public constructor(game: Game, pendingState: string) {
|
|
50
|
+
public constructor(game: Game, pendingState: SceneDefinition | string | null) {
|
|
38
51
|
this.game = game;
|
|
39
52
|
this.states = {};
|
|
40
53
|
this._pendingState = null;
|
|
@@ -72,15 +85,15 @@ export class SceneManager {
|
|
|
72
85
|
* @param {boolean} autoStart - Whether to start this state immediately.
|
|
73
86
|
* @returns {Scene|object} The created scene or state object.
|
|
74
87
|
*/
|
|
75
|
-
public add(key: string, state:
|
|
76
|
-
let newState
|
|
77
|
-
if (state
|
|
78
|
-
newState = state;
|
|
79
|
-
} else if (typeof state === 'object') {
|
|
80
|
-
newState = state;
|
|
81
|
-
newState.game = this.game;
|
|
82
|
-
} else if (typeof state === 'function') {
|
|
88
|
+
public add(key: string, state: SceneDefinition, autoStart = false): SceneState {
|
|
89
|
+
let newState: SceneState;
|
|
90
|
+
if (typeof state === 'function') {
|
|
83
91
|
newState = new state(this.game);
|
|
92
|
+
} else {
|
|
93
|
+
newState = state;
|
|
94
|
+
if (!(state instanceof Scene)) {
|
|
95
|
+
newState.game = this.game;
|
|
96
|
+
}
|
|
84
97
|
}
|
|
85
98
|
this.states[key] = newState;
|
|
86
99
|
if (autoStart) {
|
|
@@ -149,7 +162,7 @@ export class SceneManager {
|
|
|
149
162
|
* This method is called before the game loop updates.
|
|
150
163
|
*/
|
|
151
164
|
public preUpdate(): void {
|
|
152
|
-
if (this._pendingState && this.game.isBooted) {
|
|
165
|
+
if (typeof this._pendingState === 'string' && this._pendingState && this.game.isBooted) {
|
|
153
166
|
// var previousStateKey = this.current;
|
|
154
167
|
// Already got a state running?
|
|
155
168
|
this.clearCurrentState();
|
|
@@ -207,11 +220,9 @@ export class SceneManager {
|
|
|
207
220
|
* @returns {boolean} True if the scene exists, false otherwise.
|
|
208
221
|
*/
|
|
209
222
|
public checkState(key: string): boolean {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
return false;
|
|
223
|
+
const state = this.states[key];
|
|
224
|
+
if (state) {
|
|
225
|
+
return Boolean(state.preload ?? state.create ?? state.update ?? state.render);
|
|
215
226
|
}
|
|
216
227
|
return false;
|
|
217
228
|
}
|
|
@@ -221,8 +232,11 @@ export class SceneManager {
|
|
|
221
232
|
* @param {string} key - The unique key for the state to link.
|
|
222
233
|
*/
|
|
223
234
|
public link(key: string): void {
|
|
224
|
-
this.states[key]
|
|
225
|
-
|
|
235
|
+
const state = this.states[key];
|
|
236
|
+
if (state) {
|
|
237
|
+
state.game = this.game;
|
|
238
|
+
state.key = key;
|
|
239
|
+
}
|
|
226
240
|
}
|
|
227
241
|
|
|
228
242
|
/**
|
|
@@ -230,8 +244,9 @@ export class SceneManager {
|
|
|
230
244
|
* @param {string} key - The unique key for the state to unlink.
|
|
231
245
|
*/
|
|
232
246
|
public unlink(key: string): void {
|
|
233
|
-
|
|
234
|
-
|
|
247
|
+
const state = this.states[key];
|
|
248
|
+
if (state) {
|
|
249
|
+
state.game = null;
|
|
235
250
|
}
|
|
236
251
|
}
|
|
237
252
|
|
|
@@ -240,7 +255,7 @@ export class SceneManager {
|
|
|
240
255
|
* @param {string} key - The unique key for the state to set as current.
|
|
241
256
|
*/
|
|
242
257
|
public setCurrentState(key: string): void {
|
|
243
|
-
this.callbackContext = this.states[key]
|
|
258
|
+
this.callbackContext = this.states[key]!;
|
|
244
259
|
this.link(key);
|
|
245
260
|
// Used when the state is set as being the current active state
|
|
246
261
|
this.onInitCallback = this.callbackContext.init ?? this.dummy;
|
|
@@ -265,7 +280,7 @@ export class SceneManager {
|
|
|
265
280
|
* @returns {T} The current scene state.
|
|
266
281
|
*/
|
|
267
282
|
public getCurrentState<T = Partial<Scene>>(): T {
|
|
268
|
-
return this.states[this.current];
|
|
283
|
+
return this.states[this.current] as T;
|
|
269
284
|
}
|
|
270
285
|
|
|
271
286
|
/**
|
|
@@ -273,7 +288,7 @@ export class SceneManager {
|
|
|
273
288
|
* This method is called when scene loading is complete.
|
|
274
289
|
*/
|
|
275
290
|
public loadComplete(): void {
|
|
276
|
-
if (this._created
|
|
291
|
+
if (!this._created && this.onCreateCallback) {
|
|
277
292
|
this._created = true;
|
|
278
293
|
this.onCreateCallback.call(this.callbackContext, this.game);
|
|
279
294
|
} else {
|
package/src/phaser/core/sound.ts
CHANGED
|
@@ -2,13 +2,24 @@ import { Signal } from './signal.js';
|
|
|
2
2
|
import type { Game } from './game.js';
|
|
3
3
|
import type { Tween } from './tween.js';
|
|
4
4
|
|
|
5
|
+
/** A named span within a sound file. */
|
|
6
|
+
export type SoundMarker = {
|
|
7
|
+
name: string;
|
|
8
|
+
start: number;
|
|
9
|
+
stop: number;
|
|
10
|
+
volume: number;
|
|
11
|
+
duration: number;
|
|
12
|
+
durationMS: number;
|
|
13
|
+
loop: boolean;
|
|
14
|
+
};
|
|
15
|
+
|
|
5
16
|
export class Sound {
|
|
6
|
-
public _paused!:
|
|
17
|
+
public _paused!: boolean;
|
|
7
18
|
public game!: Game;
|
|
8
19
|
public name!: string;
|
|
9
20
|
public key!: string;
|
|
10
21
|
public loop!: boolean;
|
|
11
|
-
public markers!:
|
|
22
|
+
public markers!: Record<string, SoundMarker>;
|
|
12
23
|
public context!: AudioContext | null;
|
|
13
24
|
public autoplay!: boolean;
|
|
14
25
|
public totalDuration!: number;
|
|
@@ -124,8 +135,10 @@ export class Sound {
|
|
|
124
135
|
*/
|
|
125
136
|
public soundHasUnlocked(key: string): void {
|
|
126
137
|
if (key === this.key) {
|
|
127
|
-
|
|
128
|
-
|
|
138
|
+
// Unlocking parks the decoded buffer in _sound; play() replaces it with a real source node.
|
|
139
|
+
const buffer = this.game.cache.getSoundData(this.key) as AudioBuffer;
|
|
140
|
+
this._sound = buffer as unknown as AudioBufferSourceNode;
|
|
141
|
+
this.totalDuration = buffer.duration;
|
|
129
142
|
}
|
|
130
143
|
}
|
|
131
144
|
|
|
@@ -246,7 +259,7 @@ export class Sound {
|
|
|
246
259
|
* @param {boolean} forceRestart - Whether to force restarting the sound even if it's already playing.
|
|
247
260
|
* @returns {Sound} This Sound instance for chaining.
|
|
248
261
|
*/
|
|
249
|
-
public play(marker:
|
|
262
|
+
public play(marker: string | false | null = '', position = 0, volume = 1, loop = false, forceRestart = true): this {
|
|
250
263
|
if (marker === undefined || marker === false || marker === null) {
|
|
251
264
|
marker = '';
|
|
252
265
|
}
|
|
@@ -274,15 +287,16 @@ export class Sound {
|
|
|
274
287
|
// We should never play the entire thing
|
|
275
288
|
return this;
|
|
276
289
|
}
|
|
290
|
+
const markerData = marker === '' ? undefined : this.markers[marker];
|
|
277
291
|
if (marker !== '') {
|
|
278
|
-
if (
|
|
292
|
+
if (markerData) {
|
|
279
293
|
this.currentMarker = marker;
|
|
280
294
|
// Playing a marker? Then we default to the marker values
|
|
281
|
-
this.position =
|
|
282
|
-
this.volume =
|
|
283
|
-
this.loop =
|
|
284
|
-
this.duration =
|
|
285
|
-
this.durationMS =
|
|
295
|
+
this.position = markerData.start;
|
|
296
|
+
this.volume = markerData.volume;
|
|
297
|
+
this.loop = markerData.loop;
|
|
298
|
+
this.duration = markerData.duration;
|
|
299
|
+
this.durationMS = markerData.durationMS;
|
|
286
300
|
if (volume !== undefined) {
|
|
287
301
|
this.volume = volume;
|
|
288
302
|
}
|
|
@@ -298,10 +312,8 @@ export class Sound {
|
|
|
298
312
|
return this;
|
|
299
313
|
}
|
|
300
314
|
} else {
|
|
301
|
-
position
|
|
302
|
-
|
|
303
|
-
volume = this._volume;
|
|
304
|
-
}
|
|
315
|
+
position ??= 0;
|
|
316
|
+
volume ??= this._volume;
|
|
305
317
|
if (loop === undefined) {
|
|
306
318
|
({ loop } = this);
|
|
307
319
|
}
|
|
@@ -323,7 +335,7 @@ export class Sound {
|
|
|
323
335
|
} else {
|
|
324
336
|
this._sound.connect(this.gainNode);
|
|
325
337
|
}
|
|
326
|
-
this._buffer = this.game.cache.getSoundData(this.key);
|
|
338
|
+
this._buffer = this.game.cache.getSoundData(this.key) as AudioBuffer | null;
|
|
327
339
|
this._sound.buffer = this._buffer;
|
|
328
340
|
if (this.loop && marker === '') {
|
|
329
341
|
this._sound.loop = true;
|
|
@@ -351,7 +363,7 @@ export class Sound {
|
|
|
351
363
|
this.onPlay.dispatch(this);
|
|
352
364
|
} else {
|
|
353
365
|
this.pendingPlayback = true;
|
|
354
|
-
if (this.game.cache.getSound(this.key)
|
|
366
|
+
if (this.game.cache.getSound(this.key)?.isDecoding === false) {
|
|
355
367
|
this.game.sound.decode(this.key);
|
|
356
368
|
}
|
|
357
369
|
}
|
|
@@ -272,7 +272,7 @@ export class SoundManager {
|
|
|
272
272
|
*/
|
|
273
273
|
public decode(key: string): void {
|
|
274
274
|
const soundData = this.game.cache.getSoundData(key);
|
|
275
|
-
if (!soundData) {
|
|
275
|
+
if (!(soundData instanceof ArrayBuffer)) {
|
|
276
276
|
return;
|
|
277
277
|
}
|
|
278
278
|
if (this.game.cache.isSoundDecoded(key) === true) {
|
package/src/phaser/core/tween.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
+
import type { TweenTarget } from './tween_manager.js';
|
|
1
2
|
import * as MathUtils from '../util/math.js';
|
|
2
3
|
import { TWEEN_COMPLETE, TWEEN_LOOPED, TWEEN_PENDING, TWEEN_RUNNING } from './const.js';
|
|
3
4
|
import { Signal } from './signal.js';
|
|
4
5
|
import { TweenData } from './tween_data.js';
|
|
5
6
|
import type { Game } from './game.js';
|
|
6
|
-
import type { DisplayObject } from '../display/display_object.js';
|
|
7
7
|
import type { TweenManager } from './tween_manager.js';
|
|
8
8
|
|
|
9
9
|
export class Tween {
|
|
10
10
|
public game!: Game;
|
|
11
|
-
public target!:
|
|
11
|
+
public target!: TweenTarget;
|
|
12
12
|
public manager!: TweenManager;
|
|
13
13
|
public timeline!: TweenData[];
|
|
14
14
|
public reverse!: boolean;
|
|
@@ -36,7 +36,7 @@ export class Tween {
|
|
|
36
36
|
* @param {Game} game - Reference to the Phaser Game instance.
|
|
37
37
|
* @param {TweenManager} manager - Reference to the Tween Manager.
|
|
38
38
|
*/
|
|
39
|
-
public constructor(target:
|
|
39
|
+
public constructor(target: TweenTarget, game: Game, manager: TweenManager) {
|
|
40
40
|
this.game = game;
|
|
41
41
|
this.target = target;
|
|
42
42
|
/** @type {TweenManager} */
|
|
@@ -100,7 +100,7 @@ export class Tween {
|
|
|
100
100
|
yoyo = false
|
|
101
101
|
): this {
|
|
102
102
|
if (typeof ease === 'string' && this.manager.easeMap[ease]) {
|
|
103
|
-
ease = this.manager.easeMap[ease]
|
|
103
|
+
ease = this.manager.easeMap[ease]!;
|
|
104
104
|
}
|
|
105
105
|
if (this.isRunning) {
|
|
106
106
|
return this;
|
|
@@ -133,7 +133,7 @@ export class Tween {
|
|
|
133
133
|
yoyo = false
|
|
134
134
|
): this {
|
|
135
135
|
if (typeof ease === 'string' && this.manager.easeMap[ease]) {
|
|
136
|
-
ease = this.manager.easeMap[ease]
|
|
136
|
+
ease = this.manager.easeMap[ease]!;
|
|
137
137
|
}
|
|
138
138
|
if (this.isRunning) {
|
|
139
139
|
this.game.logger.warn('Tween.from cannot be called after Tween.start');
|
|
@@ -284,7 +284,7 @@ export class Tween {
|
|
|
284
284
|
*/
|
|
285
285
|
public easing(ease: string | Function, index: number): this {
|
|
286
286
|
if (typeof ease === 'string' && this.manager.easeMap[ease]) {
|
|
287
|
-
ease = this.manager.easeMap[ease]
|
|
287
|
+
ease = this.manager.easeMap[ease]!;
|
|
288
288
|
}
|
|
289
289
|
return this.updateTweenData('easingFunction', ease, index);
|
|
290
290
|
}
|
|
@@ -35,11 +35,14 @@ import {
|
|
|
35
35
|
SinusoidalOut,
|
|
36
36
|
} from './tween_easing.js';
|
|
37
37
|
|
|
38
|
+
/** What a tween can be attached to: any object, or a list of them. */
|
|
39
|
+
export type TweenTarget = object | object[];
|
|
40
|
+
|
|
38
41
|
export class TweenManager {
|
|
39
42
|
public game!: Game;
|
|
40
|
-
public _tweens!:
|
|
41
|
-
public _add!:
|
|
42
|
-
public easeMap!:
|
|
43
|
+
public _tweens!: Tween[];
|
|
44
|
+
public _add!: Tween[];
|
|
45
|
+
public easeMap!: Record<string, (k: number) => number>;
|
|
43
46
|
/**
|
|
44
47
|
* Creates a new TweenManager instance.
|
|
45
48
|
* @param {Game} game - The game instance this manager belongs to.
|
|
@@ -112,8 +115,8 @@ export class TweenManager {
|
|
|
112
115
|
* This method removes all active and pending tweens.
|
|
113
116
|
*/
|
|
114
117
|
public removeAll(): void {
|
|
115
|
-
for (
|
|
116
|
-
|
|
118
|
+
for (const tween of this._tweens) {
|
|
119
|
+
tween.pendingDelete = true;
|
|
117
120
|
}
|
|
118
121
|
this._add = [];
|
|
119
122
|
}
|
|
@@ -123,27 +126,28 @@ export class TweenManager {
|
|
|
123
126
|
* @param {object} obj - The object to remove tweens from.
|
|
124
127
|
* @param {object[]} children - Optional array of child objects to remove tweens from.
|
|
125
128
|
*/
|
|
126
|
-
public removeFrom(obj:
|
|
127
|
-
let i;
|
|
128
|
-
let len;
|
|
129
|
+
public removeFrom(obj: TweenTarget, children: object[] | null = null): void {
|
|
129
130
|
if (Array.isArray(obj)) {
|
|
130
|
-
for (
|
|
131
|
-
this.removeFrom(
|
|
131
|
+
for (const entry of obj) {
|
|
132
|
+
this.removeFrom(entry);
|
|
132
133
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const group = obj as { type?: number; children?: TweenTarget[] };
|
|
137
|
+
if (group.type === GROUP && children && group.children) {
|
|
138
|
+
for (const child of group.children) {
|
|
139
|
+
this.removeFrom(child);
|
|
136
140
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
for (const tween of this._tweens.slice()) {
|
|
144
|
+
if (obj === tween.target) {
|
|
145
|
+
this.remove(tween);
|
|
142
146
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
+
}
|
|
148
|
+
for (const tween of this._add.slice()) {
|
|
149
|
+
if (obj === tween.target) {
|
|
150
|
+
this.remove(tween);
|
|
147
151
|
}
|
|
148
152
|
}
|
|
149
153
|
}
|
|
@@ -162,7 +166,7 @@ export class TweenManager {
|
|
|
162
166
|
* @param {object} object - The object to create a tween for.
|
|
163
167
|
* @returns {Tween} The created Tween object.
|
|
164
168
|
*/
|
|
165
|
-
public create(object:
|
|
169
|
+
public create(object: TweenTarget): Tween {
|
|
166
170
|
return new Tween(object, this.game, this);
|
|
167
171
|
}
|
|
168
172
|
|
|
@@ -171,13 +175,16 @@ export class TweenManager {
|
|
|
171
175
|
* @param {Tween | null | undefined} tween - The tween to remove.
|
|
172
176
|
*/
|
|
173
177
|
public remove(tween: Tween | null | undefined): void {
|
|
178
|
+
if (!tween) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
174
181
|
let i = this._tweens.indexOf(tween);
|
|
175
182
|
if (i !== -1) {
|
|
176
|
-
this._tweens[i]
|
|
183
|
+
this._tweens[i]!.pendingDelete = true;
|
|
177
184
|
} else {
|
|
178
185
|
i = this._add.indexOf(tween);
|
|
179
186
|
if (i !== -1) {
|
|
180
|
-
this._add[i]
|
|
187
|
+
this._add[i]!.pendingDelete = true;
|
|
181
188
|
}
|
|
182
189
|
}
|
|
183
190
|
}
|
|
@@ -194,7 +201,7 @@ export class TweenManager {
|
|
|
194
201
|
}
|
|
195
202
|
let i = 0;
|
|
196
203
|
while (i < numTweens) {
|
|
197
|
-
if (this._tweens[i]
|
|
204
|
+
if (this._tweens[i]!.update(this.game.time.time)) {
|
|
198
205
|
i += 1;
|
|
199
206
|
} else {
|
|
200
207
|
this._tweens.splice(i, 1);
|
|
@@ -215,7 +222,7 @@ export class TweenManager {
|
|
|
215
222
|
* @returns {boolean} True if the object is being tweened, false otherwise.
|
|
216
223
|
*/
|
|
217
224
|
public isTweening(object: unknown): boolean {
|
|
218
|
-
return
|
|
225
|
+
return this._tweens.some((tween: Tween): boolean => tween.target === object);
|
|
219
226
|
}
|
|
220
227
|
|
|
221
228
|
/**
|
|
@@ -223,8 +230,8 @@ export class TweenManager {
|
|
|
223
230
|
* This method pauses all active tweens.
|
|
224
231
|
*/
|
|
225
232
|
public _pauseAll(): void {
|
|
226
|
-
for (
|
|
227
|
-
|
|
233
|
+
for (const tween of this._tweens) {
|
|
234
|
+
tween._pause();
|
|
228
235
|
}
|
|
229
236
|
}
|
|
230
237
|
|
|
@@ -233,8 +240,8 @@ export class TweenManager {
|
|
|
233
240
|
* This method resumes all paused tweens.
|
|
234
241
|
*/
|
|
235
242
|
public _resumeAll(): void {
|
|
236
|
-
for (
|
|
237
|
-
|
|
243
|
+
for (const tween of this._tweens) {
|
|
244
|
+
tween._resume();
|
|
238
245
|
}
|
|
239
246
|
}
|
|
240
247
|
|
|
@@ -243,8 +250,8 @@ export class TweenManager {
|
|
|
243
250
|
* This method pauses all active tweens.
|
|
244
251
|
*/
|
|
245
252
|
public pauseAll(): void {
|
|
246
|
-
for (
|
|
247
|
-
|
|
253
|
+
for (const tween of this._tweens) {
|
|
254
|
+
tween.pause();
|
|
248
255
|
}
|
|
249
256
|
}
|
|
250
257
|
|
|
@@ -253,8 +260,8 @@ export class TweenManager {
|
|
|
253
260
|
* This method resumes all paused tweens.
|
|
254
261
|
*/
|
|
255
262
|
public resumeAll(): void {
|
|
256
|
-
for (
|
|
257
|
-
|
|
263
|
+
for (const tween of this._tweens) {
|
|
264
|
+
tween.resume();
|
|
258
265
|
}
|
|
259
266
|
}
|
|
260
267
|
}
|