minimojs 1.0.0-alpha.4 → 1.0.0-alpha.41
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/README.md +58 -20
- package/dist/internal/AnimationSystem.js +345 -0
- package/dist/internal/AssetSystem.d.ts +6 -0
- package/dist/internal/AssetSystem.js +281 -0
- package/dist/internal/BackgroundSystem.d.ts +1 -0
- package/dist/internal/BackgroundSystem.js +26 -0
- package/dist/internal/CanvasSystem.d.ts +1 -0
- package/dist/internal/CanvasSystem.js +51 -0
- package/dist/internal/DesignNamingCheck.d.ts +1 -0
- package/dist/internal/DesignNamingCheck.js +7 -0
- package/dist/internal/ExplosionSystem.d.ts +1 -0
- package/dist/internal/ExplosionSystem.js +540 -0
- package/dist/internal/InputSystem.d.ts +1 -0
- package/dist/internal/InputSystem.js +292 -0
- package/dist/internal/LoopSystem.d.ts +1 -0
- package/dist/internal/LoopSystem.js +61 -0
- package/dist/internal/PhysicsSystem.d.ts +1 -0
- package/dist/internal/PhysicsSystem.js +174 -0
- package/dist/internal/RenderSystem.d.ts +1 -0
- package/dist/internal/RenderSystem.js +1021 -0
- package/dist/internal/SoundSystem.d.ts +39 -0
- package/dist/internal/SoundSystem.js +292 -0
- package/dist/internal/SpriteSystem.d.ts +1 -0
- package/dist/internal/SpriteSystem.js +32 -0
- package/dist/internal/TextSystem.d.ts +1 -0
- package/dist/internal/TextSystem.js +16 -0
- package/dist/internal/TimerSystem.d.ts +1 -0
- package/dist/internal/TimerSystem.js +43 -0
- package/dist/internal/TrailSystem.d.ts +1 -0
- package/dist/internal/TrailSystem.js +116 -0
- package/dist/internal/TransitionSystem.d.ts +1 -0
- package/dist/internal/TransitionSystem.js +74 -0
- package/dist/internal/arcade-racer/ArcadeRacerCollisionSystem.d.ts +1 -0
- package/dist/internal/arcade-racer/ArcadeRacerCollisionSystem.js +198 -0
- package/dist/internal/arcade-racer/ArcadeRacerLaneSystem.d.ts +1 -0
- package/dist/internal/arcade-racer/ArcadeRacerLaneSystem.js +120 -0
- package/dist/internal/arcade-racer/ArcadeRacerRenderSystem.d.ts +1 -0
- package/dist/internal/arcade-racer/ArcadeRacerRenderSystem.js +599 -0
- package/dist/internal/arcade-racer/ArcadeRacerRoadSprite.d.ts +1 -0
- package/dist/internal/arcade-racer/ArcadeRacerRoadSprite.js +13 -0
- package/dist/internal/arcade-racer/ArcadeRacerTrackSystem.d.ts +1 -0
- package/dist/internal/arcade-racer/ArcadeRacerTrackSystem.js +447 -0
- package/dist/minimo-ambient.d.ts +299 -0
- package/dist/minimo-ambient.js +1445 -0
- package/dist/minimo-arcaderacer.d.ts +1431 -0
- package/dist/minimo-arcaderacer.js +2060 -0
- package/dist/minimo-cards.d.ts +359 -0
- package/dist/minimo-cards.js +819 -0
- package/dist/minimo-dice.d.ts +206 -0
- package/dist/minimo-dice.js +719 -0
- package/dist/minimo-fire.d.ts +282 -0
- package/dist/minimo-fire.js +930 -0
- package/dist/minimo-format.d.ts +632 -0
- package/dist/minimo-format.js +669 -0
- package/dist/minimo-leaderboard.d.ts +199 -0
- package/dist/minimo-leaderboard.js +566 -0
- package/dist/minimo-multiplayer.d.ts +387 -0
- package/dist/minimo-multiplayer.js +1323 -0
- package/dist/minimo.d.ts +1690 -233
- package/dist/minimo.js +2587 -892
- package/package.json +10 -3
- package/dist/animations.js +0 -30
- package/dist/audio.js +0 -17
- package/dist/game.js +0 -1105
- package/dist/input.js +0 -185
- package/dist/internal-types.js +0 -4
- package/dist/physics.js +0 -10
- package/dist/render.js +0 -75
- package/dist/sprite.js +0 -149
- package/dist/timers.js +0 -23
- /package/dist/{pointer-info.js → internal/AnimationSystem.d.ts} +0 -0
package/dist/minimo.d.ts
CHANGED
|
@@ -7,48 +7,253 @@
|
|
|
7
7
|
* ALL ROTATIONS ARE IN DEGREES.
|
|
8
8
|
* THE ENGINE LOOP USES requestAnimationFrame ONLY.
|
|
9
9
|
*/
|
|
10
|
+
import { SoundPlayback } from "./internal/SoundSystem.js";
|
|
11
|
+
import type { PlaySoundOptions } from "./internal/SoundSystem.js";
|
|
12
|
+
import type { DesignObject } from "./minimo-format.js";
|
|
13
|
+
export { Design, parseAssetFile } from "./minimo-format.js";
|
|
14
|
+
export { SoundPlayback } from "./internal/SoundSystem.js";
|
|
15
|
+
export type { PlaySoundOptions, SoundPlaybackState } from "./internal/SoundSystem.js";
|
|
16
|
+
export type { AssetFile, DesignBackground, DesignEmoji, DesignFile, DesignFileV1, DesignFileV2, DesignFileV3, DesignImage, DesignModule, DesignObject, DesignObjectBase, DesignObjectType, DesignPage, DesignSpriteBase, DesignText, ImageAsset, SoundAsset, UnknownAsset, } from "./minimo-format.js";
|
|
10
17
|
/**
|
|
11
|
-
*
|
|
18
|
+
* Optional tuning values for {@link Game.animateExplode}.
|
|
12
19
|
*
|
|
13
|
-
*
|
|
14
|
-
|
|
20
|
+
* All fields are optional. Omitted fields use the engine defaults.
|
|
21
|
+
*/
|
|
22
|
+
export interface ExplodeOptions {
|
|
23
|
+
/** Number of vertical slices used to break the sprite apart. */
|
|
24
|
+
rows?: number;
|
|
25
|
+
/** Number of horizontal slices used to break the sprite apart. */
|
|
26
|
+
cols?: number;
|
|
27
|
+
/** Total effect duration in **milliseconds**. */
|
|
28
|
+
durationMs?: number;
|
|
29
|
+
/** Initial outward velocity magnitude in pixels per second. */
|
|
30
|
+
speed?: number;
|
|
31
|
+
/** Downward acceleration applied to pieces in pixels per second squared. */
|
|
32
|
+
gravityY?: number;
|
|
33
|
+
/** Maximum angular speed applied to pieces, in degrees per second. */
|
|
34
|
+
spin?: number;
|
|
35
|
+
/** Whether pieces fade out as the effect approaches completion. */
|
|
36
|
+
fade?: boolean;
|
|
37
|
+
/** Whether the original sprite is destroyed instead of restored after the effect. */
|
|
38
|
+
destroySprite?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Cardinal flow direction used by directional visual effects.
|
|
42
|
+
*/
|
|
43
|
+
export type FlowDirection = "left-to-right" | "right-to-left" | "top-to-bottom" | "bottom-to-top";
|
|
44
|
+
/**
|
|
45
|
+
* Direction used by piece-based local integration and disintegration effects.
|
|
15
46
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
47
|
+
* - Cardinal values apply a directional sweep across the sprite.
|
|
48
|
+
* - `"in-place"` keeps pieces in their final positions and only randomizes
|
|
49
|
+
* when each piece appears or disappears.
|
|
50
|
+
*/
|
|
51
|
+
export type PieceFlowDirection = FlowDirection | "in-place";
|
|
52
|
+
/**
|
|
53
|
+
* Optional tuning values for {@link Game.animateAssemble}.
|
|
18
54
|
*
|
|
19
|
-
*
|
|
20
|
-
|
|
55
|
+
* All fields are optional. Omitted fields use the engine defaults.
|
|
56
|
+
*/
|
|
57
|
+
export interface AssembleOptions {
|
|
58
|
+
/** Number of vertical slices used to reconstruct the sprite. */
|
|
59
|
+
rows?: number;
|
|
60
|
+
/** Number of horizontal slices used to reconstruct the sprite. */
|
|
61
|
+
cols?: number;
|
|
62
|
+
/** Total effect duration in **milliseconds**. */
|
|
63
|
+
durationMs?: number;
|
|
64
|
+
/** Initial outward distance magnitude in pixels per second equivalent. */
|
|
65
|
+
speed?: number;
|
|
66
|
+
/** Downward pull applied while pieces converge, in pixels per second squared. */
|
|
67
|
+
gravityY?: number;
|
|
68
|
+
/** Maximum angular speed applied to pieces, in degrees per second. */
|
|
69
|
+
spin?: number;
|
|
70
|
+
/** Whether pieces fade in while assembling. */
|
|
71
|
+
fade?: boolean;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Optional tuning values for {@link Game.animateDisintegrate}.
|
|
21
75
|
*
|
|
22
|
-
*
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
76
|
+
* All fields are optional. Omitted fields use the engine defaults.
|
|
77
|
+
*/
|
|
78
|
+
export interface DisintegrateOptions {
|
|
79
|
+
/** Number of vertical slices used to dissolve the sprite. */
|
|
80
|
+
rows?: number;
|
|
81
|
+
/** Number of horizontal slices used to dissolve the sprite. */
|
|
82
|
+
cols?: number;
|
|
83
|
+
/** Total effect duration in **milliseconds**. */
|
|
84
|
+
durationMs?: number;
|
|
85
|
+
/** Primary sweep direction across the sprite. */
|
|
86
|
+
direction?: PieceFlowDirection;
|
|
87
|
+
/** Maximum local travel distance in pixels for each piece. */
|
|
88
|
+
distance?: number;
|
|
89
|
+
/** Maximum angular speed applied to pieces, in degrees per second. */
|
|
90
|
+
spin?: number;
|
|
91
|
+
/** Whether pieces fade out as they disintegrate. */
|
|
92
|
+
fade?: boolean;
|
|
93
|
+
/** Whether the original sprite is destroyed instead of left hidden after the effect. */
|
|
94
|
+
destroySprite?: boolean;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Optional tuning values for {@link Game.animateIntegrate}.
|
|
28
98
|
*
|
|
29
|
-
*
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
99
|
+
* All fields are optional. Omitted fields use the engine defaults.
|
|
100
|
+
*/
|
|
101
|
+
export interface IntegrateOptions {
|
|
102
|
+
/** Number of vertical slices used to reconstruct the sprite. */
|
|
103
|
+
rows?: number;
|
|
104
|
+
/** Number of horizontal slices used to reconstruct the sprite. */
|
|
105
|
+
cols?: number;
|
|
106
|
+
/** Total effect duration in **milliseconds**. */
|
|
107
|
+
durationMs?: number;
|
|
108
|
+
/** Primary sweep direction across the sprite. */
|
|
109
|
+
direction?: PieceFlowDirection;
|
|
110
|
+
/** Maximum local travel distance in pixels for each piece. */
|
|
111
|
+
distance?: number;
|
|
112
|
+
/** Maximum angular speed applied to pieces, in degrees per second. */
|
|
113
|
+
spin?: number;
|
|
114
|
+
/** Whether pieces fade in while integrating. */
|
|
115
|
+
fade?: boolean;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Wipe mode used by {@link Game.animateWipe}.
|
|
119
|
+
*/
|
|
120
|
+
export type WipeMode = "reveal" | "cover";
|
|
121
|
+
/**
|
|
122
|
+
* Full-screen transition type used by {@link Game.transitionTo}.
|
|
123
|
+
*/
|
|
124
|
+
export type ScreenTransitionType = "fade" | "wipe" | "slide" | "iris" | "pixelate" | "flash";
|
|
125
|
+
/**
|
|
126
|
+
* Optional tuning values for {@link Game.animateWipe}.
|
|
34
127
|
*
|
|
35
|
-
*
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
128
|
+
* All fields are optional. Omitted fields use the engine defaults.
|
|
129
|
+
*/
|
|
130
|
+
export interface WipeOptions {
|
|
131
|
+
/** Whether the wipe reveals the sprite or covers it away. */
|
|
132
|
+
mode?: WipeMode;
|
|
133
|
+
/** Primary wipe direction. */
|
|
134
|
+
direction?: FlowDirection;
|
|
135
|
+
/** Total effect duration in **milliseconds**. */
|
|
136
|
+
durationMs?: number;
|
|
137
|
+
/** Whether the original sprite is destroyed for `mode: "cover"`. */
|
|
138
|
+
destroySprite?: boolean;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Optional tuning values for {@link Game.transitionTo}.
|
|
40
142
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
143
|
+
* MinimoJS scene transitions operate on frozen snapshots of the outgoing and
|
|
144
|
+
* incoming scenes. The target scene is created immediately, then both
|
|
145
|
+
* snapshots are composited for the duration of the effect.
|
|
44
146
|
*/
|
|
45
|
-
export
|
|
147
|
+
export interface SceneTransitionOptions {
|
|
148
|
+
/** Required transition style. */
|
|
149
|
+
type: ScreenTransitionType;
|
|
150
|
+
/** Total transition duration in **milliseconds**. */
|
|
151
|
+
durationMs?: number;
|
|
152
|
+
/** Optional color used by `fade` and `flash`. */
|
|
153
|
+
color?: string;
|
|
154
|
+
/** Direction used by `wipe` and `slide`. */
|
|
155
|
+
direction?: FlowDirection;
|
|
156
|
+
/** Optional iris center X position in canvas pixels. */
|
|
157
|
+
centerX?: number;
|
|
158
|
+
/** Optional iris center Y position in canvas pixels. */
|
|
159
|
+
centerY?: number;
|
|
160
|
+
/** Maximum pixel block size used by `pixelate`. */
|
|
161
|
+
pixelSize?: number;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Optional tuning values for {@link Game.animateTrail}.
|
|
165
|
+
*
|
|
166
|
+
* All fields are optional. Omitted fields use the engine defaults.
|
|
167
|
+
*/
|
|
168
|
+
export interface TrailOptions {
|
|
169
|
+
/** How long the emitter spawns afterimages, in **milliseconds**. */
|
|
170
|
+
durationMs?: number;
|
|
171
|
+
/** Time between emitted afterimages, in **milliseconds**. */
|
|
172
|
+
spacingMs?: number;
|
|
173
|
+
/** Lifetime of each afterimage before it disappears, in **milliseconds**. */
|
|
174
|
+
fadeMs?: number;
|
|
175
|
+
/** Starting opacity multiplier for each emitted afterimage, in range `[0, 1]`. */
|
|
176
|
+
alpha?: number;
|
|
177
|
+
/** Final scale multiplier reached by each afterimage before it vanishes. */
|
|
178
|
+
scaleTo?: number;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* How a {@link BackgroundLayer} image is fit inside its destination rectangle.
|
|
182
|
+
*
|
|
183
|
+
* - `"none"`: draws the image at its original size with no scaling.
|
|
184
|
+
* - `"stretch"`: fills the destination exactly, ignoring aspect ratio.
|
|
185
|
+
* - `"contain"`: preserves aspect ratio and keeps the entire image visible.
|
|
186
|
+
* - `"cover"`: preserves aspect ratio and fully covers the destination, cropping if needed.
|
|
187
|
+
*/
|
|
188
|
+
export type BackgroundFit = "none" | "stretch" | "contain" | "cover";
|
|
189
|
+
/**
|
|
190
|
+
* Minimal scene contract understood by {@link Game.start} and {@link Game.reset}.
|
|
191
|
+
*
|
|
192
|
+
* Scene methods are invoked directly on the scene instance, so class-based
|
|
193
|
+
* scenes keep their expected `this` value.
|
|
194
|
+
*/
|
|
195
|
+
export interface IScene {
|
|
46
196
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
197
|
+
* Registers images this scene needs that the rest of the game does not.
|
|
198
|
+
*
|
|
199
|
+
* **Only for games with many scenes that each carry many assets of their
|
|
200
|
+
* own**, such as a game with many levels, where a player does not reach
|
|
201
|
+
* every scene in a session and loading all of them at boot would make the
|
|
202
|
+
* first wait needlessly long. Every other game should load its images in
|
|
203
|
+
* {@link Game.onPreload}, once, at boot.
|
|
204
|
+
*
|
|
205
|
+
* Called whenever the scene is entered — by {@link Game.start},
|
|
206
|
+
* {@link Game.reset}, or {@link Game.transitionTo} — before
|
|
207
|
+
* {@link IScene.onCreate}. Call {@link Game.loadAssets},
|
|
208
|
+
* {@link Game.loadImage}, or {@link Game.loadSound} inside it, as inside `game.onPreload`. Images that
|
|
209
|
+
* are already loaded are skipped, so replaying a scene loads nothing.
|
|
210
|
+
*
|
|
211
|
+
* When images are pending, the scene being left freezes, dimmed, under a
|
|
212
|
+
* progress ring until they load, and only then is this scene created.
|
|
213
|
+
* Because of that, `reset()` and `transitionTo()` may return before this
|
|
214
|
+
* scene exists: continue in `onCreate()`, not in the code after the call.
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```ts
|
|
218
|
+
* class Level {
|
|
219
|
+
* constructor(n) { this.n = n; }
|
|
220
|
+
* onPreload() {
|
|
221
|
+
* game.loadImage(`level-${this.n}-bg`, `assets/level-${this.n}-bg.png`);
|
|
222
|
+
* }
|
|
223
|
+
* onCreate() {
|
|
224
|
+
* game.addBackground(new BackgroundLayer(`level-${this.n}-bg`));
|
|
225
|
+
* }
|
|
226
|
+
* }
|
|
227
|
+
* ```
|
|
50
228
|
*/
|
|
51
|
-
|
|
229
|
+
onPreload?(): void;
|
|
230
|
+
/**
|
|
231
|
+
* Called when the scene is created, before the first frame and again after
|
|
232
|
+
* each {@link Game.reset} that targets this scene. When the scene has an
|
|
233
|
+
* {@link IScene.onPreload} with images still loading, it is called once they
|
|
234
|
+
* have loaded.
|
|
235
|
+
*/
|
|
236
|
+
onCreate?(): void;
|
|
237
|
+
/**
|
|
238
|
+
* Called once per frame after timers, animation, and physics updates.
|
|
239
|
+
*
|
|
240
|
+
* @param dt - Delta time in seconds since the previous frame.
|
|
241
|
+
*/
|
|
242
|
+
onUpdate?(dt: number): void;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Base class for all renderable MinimoJS actors.
|
|
246
|
+
*
|
|
247
|
+
* Concrete subclasses provide their own visual content while inheriting the
|
|
248
|
+
* shared transform, visibility, physics, and animation state required by the
|
|
249
|
+
* engine.
|
|
250
|
+
*/
|
|
251
|
+
export declare abstract class Sprite {
|
|
252
|
+
protected constructor(game?: Game | null);
|
|
253
|
+
/**
|
|
254
|
+
* Game instance associated with this sprite, if any.
|
|
255
|
+
*/
|
|
256
|
+
get game(): Game | null;
|
|
52
257
|
/**
|
|
53
258
|
* X position in world space (horizontal center of the sprite), in pixels.
|
|
54
259
|
* Positive X points right. Updated each frame by: `x += vx * dt`.
|
|
@@ -62,26 +267,80 @@ export declare class Sprite {
|
|
|
62
267
|
*/
|
|
63
268
|
y: number;
|
|
64
269
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* This value is read-only after construction and defines the glyph-cache
|
|
68
|
-
* render size. The visible and collision size during gameplay is exposed by
|
|
69
|
-
* {@link Sprite.displaySize}.
|
|
270
|
+
* Resolved center X used internally by rendering, hit testing, and collisions.
|
|
70
271
|
*/
|
|
71
|
-
get
|
|
272
|
+
get renderX(): number;
|
|
273
|
+
/**
|
|
274
|
+
* Resolved center Y used internally by rendering, hit testing, and collisions.
|
|
275
|
+
*/
|
|
276
|
+
get renderY(): number;
|
|
72
277
|
/**
|
|
73
|
-
* Visual scale multiplier applied to
|
|
278
|
+
* Visual scale multiplier applied to this sprite's logical width/height.
|
|
74
279
|
* Default: `1`.
|
|
75
|
-
*
|
|
76
|
-
* Set this at runtime to resize a sprite without changing its base cached
|
|
77
|
-
* glyph size.
|
|
78
280
|
*/
|
|
79
281
|
scale: number;
|
|
80
282
|
/**
|
|
81
|
-
*
|
|
82
|
-
* Computed as `size * scale` with non-negative clamping.
|
|
283
|
+
* Base logical width in pixels before applying {@link Sprite.scale}.
|
|
83
284
|
*/
|
|
84
|
-
get
|
|
285
|
+
abstract get width(): number;
|
|
286
|
+
/**
|
|
287
|
+
* Base logical height in pixels before applying {@link Sprite.scale}.
|
|
288
|
+
*/
|
|
289
|
+
abstract get height(): number;
|
|
290
|
+
/**
|
|
291
|
+
* Effective rendered/collision width in pixels.
|
|
292
|
+
*/
|
|
293
|
+
get displayWidth(): number;
|
|
294
|
+
/**
|
|
295
|
+
* Effective rendered/collision height in pixels.
|
|
296
|
+
*/
|
|
297
|
+
get displayHeight(): number;
|
|
298
|
+
/**
|
|
299
|
+
* Optional logical body width used by physics helpers and collision checks.
|
|
300
|
+
*
|
|
301
|
+
* When `null` (default), MinimoJS uses the sprite's visual {@link Sprite.width}.
|
|
302
|
+
* When set, this value is scaled by {@link Sprite.scale} the same way as the
|
|
303
|
+
* visual sprite size.
|
|
304
|
+
*/
|
|
305
|
+
bodyWidth: number | null;
|
|
306
|
+
/**
|
|
307
|
+
* Optional logical body height used by physics helpers and collision checks.
|
|
308
|
+
*
|
|
309
|
+
* When `null` (default), MinimoJS uses the sprite's visual {@link Sprite.height}.
|
|
310
|
+
* When set, this value is scaled by {@link Sprite.scale} the same way as the
|
|
311
|
+
* visual sprite size.
|
|
312
|
+
*/
|
|
313
|
+
bodyHeight: number | null;
|
|
314
|
+
/**
|
|
315
|
+
* Horizontal body offset, in local sprite pixels before scale is applied.
|
|
316
|
+
*
|
|
317
|
+
* Positive values move the collision body to the right of the sprite's rendered center.
|
|
318
|
+
* Negative values move it to the left.
|
|
319
|
+
*/
|
|
320
|
+
bodyOffsetX: number;
|
|
321
|
+
/**
|
|
322
|
+
* Vertical body offset, in local sprite pixels before scale is applied.
|
|
323
|
+
*
|
|
324
|
+
* Positive values move the collision body downward relative to the sprite's
|
|
325
|
+
* rendered center. Negative values move it upward.
|
|
326
|
+
*/
|
|
327
|
+
bodyOffsetY: number;
|
|
328
|
+
/**
|
|
329
|
+
* Effective collision-body width in pixels after applying {@link Sprite.scale}.
|
|
330
|
+
*/
|
|
331
|
+
get bodyDisplayWidth(): number;
|
|
332
|
+
/**
|
|
333
|
+
* Effective collision-body height in pixels after applying {@link Sprite.scale}.
|
|
334
|
+
*/
|
|
335
|
+
get bodyDisplayHeight(): number;
|
|
336
|
+
/**
|
|
337
|
+
* Resolved body center X used internally by physics helpers and collision checks.
|
|
338
|
+
*/
|
|
339
|
+
get bodyCenterX(): number;
|
|
340
|
+
/**
|
|
341
|
+
* Resolved body center Y used internally by physics helpers and collision checks.
|
|
342
|
+
*/
|
|
343
|
+
get bodyCenterY(): number;
|
|
85
344
|
/**
|
|
86
345
|
* CSS text color used when rendering this sprite.
|
|
87
346
|
*
|
|
@@ -168,11 +427,78 @@ export declare class Sprite {
|
|
|
168
427
|
*/
|
|
169
428
|
gravityScale: number;
|
|
170
429
|
/**
|
|
171
|
-
*
|
|
430
|
+
* Optional name, so code can ask an object what it is. Names may repeat,
|
|
431
|
+
* like a `name` attribute in the DOM. The engine never reads it.
|
|
432
|
+
* A sprite created from a design file takes the object's `name`.
|
|
433
|
+
*
|
|
434
|
+
* @example
|
|
435
|
+
* ```ts
|
|
436
|
+
* if (other.name === "door") openDoor();
|
|
437
|
+
* ```
|
|
438
|
+
*/
|
|
439
|
+
name: string | undefined;
|
|
440
|
+
/**
|
|
441
|
+
* Tags for grouping, like CSS classes in the DOM. Empty by default. The
|
|
442
|
+
* engine never reads them. A sprite created from a design file takes the
|
|
443
|
+
* object's `tags`, which {@link Game.registerBuilderByTag} also matches.
|
|
444
|
+
*
|
|
445
|
+
* @example
|
|
446
|
+
* ```ts
|
|
447
|
+
* if (other.tags.includes("coin")) collect(other);
|
|
448
|
+
* ```
|
|
449
|
+
*/
|
|
450
|
+
tags: string[];
|
|
451
|
+
/**
|
|
452
|
+
* The game's own values for this object, such as a button's action or an
|
|
453
|
+
* enemy's speed. An empty object by default, so `sprite.data.hp = 3` needs
|
|
454
|
+
* no check. The engine never reads it. A sprite created from a design file
|
|
455
|
+
* takes a copy of the object's `data`.
|
|
456
|
+
*/
|
|
457
|
+
data: Record<string, unknown>;
|
|
458
|
+
/**
|
|
459
|
+
* Stable cache key describing the sprite's rendered appearance.
|
|
460
|
+
*
|
|
461
|
+
* The renderer uses this to reuse prerendered canvases across frames.
|
|
462
|
+
*/
|
|
463
|
+
abstract getRenderCacheKey(): string;
|
|
464
|
+
protected getAnchorOffsetX(): number;
|
|
465
|
+
protected getAnchorOffsetY(): number;
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* A 2D game object rendered as an emoji on the canvas.
|
|
469
|
+
*
|
|
470
|
+
* Instantiate directly or extend to create custom sprite types.
|
|
471
|
+
* Register with the engine by passing the instance to {@link Game.add}.
|
|
472
|
+
*
|
|
473
|
+
* **Coordinate system:** center-based world space. `(x, y)` is the center of
|
|
474
|
+
* the sprite. Positive X = right, positive Y = down.
|
|
475
|
+
*
|
|
476
|
+
* **Lifecycle:** A sprite exists until {@link Game.destroySprite} is called or
|
|
477
|
+
* {@link Game.reset} is invoked. After destruction, do not read or write its fields.
|
|
478
|
+
*
|
|
479
|
+
* @example
|
|
480
|
+
* ```ts
|
|
481
|
+
* const coin = new EmojiSprite("🪙", 300, 200, 32);
|
|
482
|
+
* game.add(coin);
|
|
483
|
+
* ```
|
|
484
|
+
*/
|
|
485
|
+
export declare class EmojiSprite extends Sprite {
|
|
486
|
+
/**
|
|
487
|
+
* The emoji character used to render this sprite.
|
|
488
|
+
* Must be a single emoji. Change this at runtime to animate between frames.
|
|
489
|
+
* @example "🔥", "⭐", "🐢"
|
|
490
|
+
*/
|
|
491
|
+
sprite: string;
|
|
492
|
+
get size(): number;
|
|
493
|
+
get width(): number;
|
|
494
|
+
get height(): number;
|
|
495
|
+
get displaySize(): number;
|
|
496
|
+
/**
|
|
497
|
+
* Creates a new EmojiSprite with the given emoji, optional position, and base size.
|
|
172
498
|
* All other properties use their defaults and can be set after construction.
|
|
173
499
|
*
|
|
174
500
|
* @param sprite - The emoji character to render. Must be a single emoji.
|
|
175
|
-
*
|
|
501
|
+
* Use {@link ImageSprite} for preloaded bitmap textures.
|
|
176
502
|
* @example "🔥", "⭐", "🐢", "💣", "👾"
|
|
177
503
|
* @param x - Initial X position in world space (center), in pixels. Default: `0`.
|
|
178
504
|
* @param y - Initial Y position in world space (center), in pixels. Default: `0`.
|
|
@@ -180,12 +506,336 @@ export declare class Sprite {
|
|
|
180
506
|
*
|
|
181
507
|
* @example
|
|
182
508
|
* ```ts
|
|
183
|
-
* const enemy = new
|
|
509
|
+
* const enemy = new EmojiSprite("👾", 200, 100, 40);
|
|
184
510
|
* game.add(enemy);
|
|
185
511
|
* ```
|
|
186
512
|
*/
|
|
187
513
|
constructor(sprite: string, x?: number, y?: number, size?: number);
|
|
514
|
+
getRenderCacheKey(): string;
|
|
188
515
|
}
|
|
516
|
+
/**
|
|
517
|
+
* A renderable sprite backed by a preloaded image asset.
|
|
518
|
+
*
|
|
519
|
+
* Width and height are always resolved from the current texture. To resize the
|
|
520
|
+
* sprite visually, use {@link Sprite.scale}.
|
|
521
|
+
*/
|
|
522
|
+
export declare class ImageSprite extends Sprite {
|
|
523
|
+
get imageKey(): string;
|
|
524
|
+
get width(): number;
|
|
525
|
+
get height(): number;
|
|
526
|
+
/**
|
|
527
|
+
* Creates a new image-backed sprite.
|
|
528
|
+
*
|
|
529
|
+
* @param game - Game instance used to resolve the texture key.
|
|
530
|
+
* @param imageKey - Texture key previously registered with {@link Game.loadImage} or {@link Game.createTexture}.
|
|
531
|
+
* @param x - Initial X position in world space (center), in pixels. Default: `0`.
|
|
532
|
+
* @param y - Initial Y position in world space (center), in pixels. Default: `0`.
|
|
533
|
+
*/
|
|
534
|
+
constructor(game: Game, imageKey: string, x?: number, y?: number);
|
|
535
|
+
/**
|
|
536
|
+
* Replaces the current texture with another preloaded image.
|
|
537
|
+
*
|
|
538
|
+
* @param imageKey - New texture key to render.
|
|
539
|
+
*/
|
|
540
|
+
setTexture(imageKey: string): void;
|
|
541
|
+
getRenderCacheKey(): string;
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* A renderable sprite backed by a per-instance canvas that is repainted on demand.
|
|
545
|
+
*
|
|
546
|
+
* `DrawSprite` is useful for procedural shapes, gauges, charts, minimaps, and
|
|
547
|
+
* HUD widgets whose appearance changes often and is easier to express with
|
|
548
|
+
* Canvas 2D drawing commands than with emoji, text, or image swaps.
|
|
549
|
+
*
|
|
550
|
+
* Treat `DrawSprite` as a specialized tool, not the default sprite type.
|
|
551
|
+
* Because it may execute custom Canvas 2D drawing code repeatedly, overusing it
|
|
552
|
+
* can affect game performance much more than regular {@link EmojiSprite},
|
|
553
|
+
* {@link ImageSprite}, or {@link TextSprite} instances.
|
|
554
|
+
*
|
|
555
|
+
* Prefer the other sprite types whenever they can express the same result more
|
|
556
|
+
* simply. Reach for `DrawSprite` only when you truly need procedural drawing or
|
|
557
|
+
* custom per-sprite canvas rendering that the built-in sprite types cannot
|
|
558
|
+
* provide cleanly.
|
|
559
|
+
*
|
|
560
|
+
* MinimoJS creates and owns an internal canvas for each `DrawSprite` instance.
|
|
561
|
+
* Before every engine render that needs this sprite's surface, the engine:
|
|
562
|
+
*
|
|
563
|
+
* 1. Resolves the sprite's internal canvas size
|
|
564
|
+
* 2. Optionally clears and repaints that internal canvas
|
|
565
|
+
* 3. Draws the resulting canvas like any other sprite surface
|
|
566
|
+
*
|
|
567
|
+
* By default, `DrawSprite` is live-rendered: the engine clears the internal
|
|
568
|
+
* canvas and calls {@link DrawSprite.redraw} every frame.
|
|
569
|
+
*
|
|
570
|
+
* Set {@link DrawSprite.frozen} to `true` if you want to keep and reuse the
|
|
571
|
+
* last rendered canvas contents without repainting on each frame. This is
|
|
572
|
+
* useful for shapes or procedural art that you only want to draw once.
|
|
573
|
+
*
|
|
574
|
+
* While `frozen` is `true`, MinimoJS reuses the existing surface exactly as-is:
|
|
575
|
+
* it does not clear the canvas and does not call {@link DrawSprite.redraw}
|
|
576
|
+
* again, unless the surface does not exist yet or its size had to be rebuilt.
|
|
577
|
+
*
|
|
578
|
+
* This means freezing is a rendering optimization and content-preservation
|
|
579
|
+
* flag, not a separate caching system. You can switch `frozen` on or off at
|
|
580
|
+
* runtime whenever it makes sense for your sprite.
|
|
581
|
+
*
|
|
582
|
+
* The local drawing coordinate system uses the sprite surface itself:
|
|
583
|
+
* - `(0, 0)` is the top-left corner of the internal canvas
|
|
584
|
+
* - `width` / `height` match the sprite's logical size before `scale`
|
|
585
|
+
* - draw centered content yourself if you want the visual origin in the middle
|
|
586
|
+
*
|
|
587
|
+
* Override {@link DrawSprite.redraw} in a subclass, or assign your own method
|
|
588
|
+
* on an instance if you prefer an inline style in JavaScript.
|
|
589
|
+
*/
|
|
590
|
+
export declare class DrawSprite extends Sprite {
|
|
591
|
+
/**
|
|
592
|
+
* When `false` (default), MinimoJS clears this sprite's internal canvas and
|
|
593
|
+
* calls {@link DrawSprite.redraw} on every render pass.
|
|
594
|
+
*
|
|
595
|
+
* When `true`, MinimoJS keeps and reuses the existing canvas contents without
|
|
596
|
+
* clearing or repainting them again, unless the internal surface does not yet
|
|
597
|
+
* exist or had to be resized.
|
|
598
|
+
*
|
|
599
|
+
* Use this when your procedural drawing becomes static after its first paint,
|
|
600
|
+
* or when you want explicit manual control over when the sprite is redrawn by
|
|
601
|
+
* toggling `frozen` at runtime.
|
|
602
|
+
*/
|
|
603
|
+
frozen: boolean;
|
|
604
|
+
get width(): number;
|
|
605
|
+
get height(): number;
|
|
606
|
+
/**
|
|
607
|
+
* Creates a new dynamic canvas-backed sprite.
|
|
608
|
+
*
|
|
609
|
+
* @param width - Internal canvas width in pixels. Minimum `1`.
|
|
610
|
+
* @param height - Internal canvas height in pixels. Minimum `1`.
|
|
611
|
+
* @param x - Initial X position in world space (center), in pixels. Default: `0`.
|
|
612
|
+
* @param y - Initial Y position in world space (center), in pixels. Default: `0`.
|
|
613
|
+
*/
|
|
614
|
+
constructor(width: number, height: number, x?: number, y?: number);
|
|
615
|
+
/**
|
|
616
|
+
* Called by the engine whenever the sprite's internal surface must be repainted.
|
|
617
|
+
*
|
|
618
|
+
* The provided context is already cleared and reset to the default 2D canvas
|
|
619
|
+
* state for the current surface size. MinimoJS repaints each `DrawSprite` at
|
|
620
|
+
* most once per render pass while it is not {@link DrawSprite.frozen}, so
|
|
621
|
+
* repeated snapshot reads during the same frame reuse the already-redrawn
|
|
622
|
+
* surface.
|
|
623
|
+
*
|
|
624
|
+
* @param ctx - The sprite's internal 2D drawing context.
|
|
625
|
+
*/
|
|
626
|
+
redraw(_ctx: CanvasRenderingContext2D): void;
|
|
627
|
+
getRenderCacheKey(): string;
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* A renderable text actor that participates in the same animation/effects
|
|
631
|
+
* pipeline as regular sprites.
|
|
632
|
+
*
|
|
633
|
+
* Use `TextSprite` when the content is primarily text, or when you need text
|
|
634
|
+
* layout features such as wrapping, fixed button sizes, background/border, or
|
|
635
|
+
* text stroke.
|
|
636
|
+
*
|
|
637
|
+
* For controls that are only a single emoji, prefer {@link EmojiSprite}. Emoji-only
|
|
638
|
+
* buttons usually behave better as sprites because they do not need text
|
|
639
|
+
* padding/layout and their bounds match the rendered emoji more directly.
|
|
640
|
+
*/
|
|
641
|
+
export declare class TextSprite extends Sprite {
|
|
642
|
+
anchorX: "left" | "center" | "right";
|
|
643
|
+
anchorY: "top" | "middle" | "bottom";
|
|
644
|
+
text: string;
|
|
645
|
+
/**
|
|
646
|
+
* CSS font family. Default: `monospace`, which needs no download. Name a web
|
|
647
|
+
* font here, and register it with {@link Game.requireFont}, to use one.
|
|
648
|
+
*/
|
|
649
|
+
fontFamily: string;
|
|
650
|
+
fontSize: number;
|
|
651
|
+
fontWeight: string;
|
|
652
|
+
lineHeight: number;
|
|
653
|
+
maxWidth: number;
|
|
654
|
+
fixedWidth: number;
|
|
655
|
+
fixedHeight: number;
|
|
656
|
+
paddingX: number;
|
|
657
|
+
paddingY: number;
|
|
658
|
+
backgroundColor: string | null;
|
|
659
|
+
borderColor: string | null;
|
|
660
|
+
borderWidth: number;
|
|
661
|
+
cornerRadius: number;
|
|
662
|
+
strokeColor: string | null;
|
|
663
|
+
strokeWidth: number;
|
|
664
|
+
textAlign: CanvasTextAlign;
|
|
665
|
+
get width(): number;
|
|
666
|
+
get height(): number;
|
|
667
|
+
constructor(text: string, x?: number, y?: number, fontSizeOrConfig?: number | TextSpriteConfig, config?: TextSpriteConfig);
|
|
668
|
+
getRenderCacheKey(): string;
|
|
669
|
+
get align(): CanvasTextAlign;
|
|
670
|
+
set align(value: CanvasTextAlign);
|
|
671
|
+
protected getAnchorOffsetX(): number;
|
|
672
|
+
protected getAnchorOffsetY(): number;
|
|
673
|
+
}
|
|
674
|
+
export type TextSpriteConfig = {
|
|
675
|
+
anchorX?: "left" | "center" | "right";
|
|
676
|
+
anchorY?: "top" | "middle" | "bottom";
|
|
677
|
+
fontFamily?: string;
|
|
678
|
+
fontSize?: number;
|
|
679
|
+
fontWeight?: string;
|
|
680
|
+
lineHeight?: number;
|
|
681
|
+
maxWidth?: number;
|
|
682
|
+
fixedWidth?: number;
|
|
683
|
+
fixedHeight?: number;
|
|
684
|
+
paddingX?: number;
|
|
685
|
+
paddingY?: number;
|
|
686
|
+
backgroundColor?: string | null;
|
|
687
|
+
borderColor?: string | null;
|
|
688
|
+
borderWidth?: number;
|
|
689
|
+
cornerRadius?: number;
|
|
690
|
+
strokeColor?: string | null;
|
|
691
|
+
strokeWidth?: number;
|
|
692
|
+
textAlign?: CanvasTextAlign;
|
|
693
|
+
align?: CanvasTextAlign;
|
|
694
|
+
};
|
|
695
|
+
export type FontRequirementOptions = {
|
|
696
|
+
weight?: string;
|
|
697
|
+
style?: "normal" | "italic" | "oblique";
|
|
698
|
+
size?: number;
|
|
699
|
+
sampleText?: string;
|
|
700
|
+
};
|
|
701
|
+
/**
|
|
702
|
+
* A static image-based background layer rendered behind all sprites.
|
|
703
|
+
*
|
|
704
|
+
* Background layers are visual-only: they do not participate in physics,
|
|
705
|
+
* collisions, input hit-testing, or sprite queries.
|
|
706
|
+
*
|
|
707
|
+
* `x` / `y` use **top-left screen-space coordinates**, unlike {@link Sprite},
|
|
708
|
+
* which uses center-based world space.
|
|
709
|
+
*
|
|
710
|
+
* The texture referenced by {@link BackgroundLayer.imageKey} must be registered
|
|
711
|
+
* with {@link Game.loadImage} during {@link Game.onPreload}, or created
|
|
712
|
+
* dynamically with {@link Game.createTexture}.
|
|
713
|
+
*
|
|
714
|
+
* @example
|
|
715
|
+
* ```ts
|
|
716
|
+
* game.onPreload = () => {
|
|
717
|
+
* game.loadImage("sky", "assets/sky.png");
|
|
718
|
+
* };
|
|
719
|
+
*
|
|
720
|
+
* game.onCreate = () => {
|
|
721
|
+
* const bg = game.addBackground(new BackgroundLayer("sky"));
|
|
722
|
+
* bg.fit = "cover";
|
|
723
|
+
* };
|
|
724
|
+
* ```
|
|
725
|
+
*/
|
|
726
|
+
export declare class BackgroundLayer {
|
|
727
|
+
/**
|
|
728
|
+
* Key of the preloaded image to render.
|
|
729
|
+
*/
|
|
730
|
+
imageKey: string;
|
|
731
|
+
/**
|
|
732
|
+
* Left edge of the destination rectangle in screen space, in pixels.
|
|
733
|
+
*/
|
|
734
|
+
x: number;
|
|
735
|
+
/**
|
|
736
|
+
* Top edge of the destination rectangle in screen space, in pixels.
|
|
737
|
+
*/
|
|
738
|
+
y: number;
|
|
739
|
+
/**
|
|
740
|
+
* Width of the destination rectangle in pixels.
|
|
741
|
+
* If `0` (default), the canvas width is used.
|
|
742
|
+
*/
|
|
743
|
+
width: number;
|
|
744
|
+
/**
|
|
745
|
+
* Height of the destination rectangle in pixels.
|
|
746
|
+
* If `0` (default), the canvas height is used.
|
|
747
|
+
*/
|
|
748
|
+
height: number;
|
|
749
|
+
/**
|
|
750
|
+
* Opacity of the layer in range `[0, 1]`.
|
|
751
|
+
*/
|
|
752
|
+
alpha: number;
|
|
753
|
+
/**
|
|
754
|
+
* Controls whether the layer is drawn.
|
|
755
|
+
*/
|
|
756
|
+
visible: boolean;
|
|
757
|
+
/**
|
|
758
|
+
* Orders background layers relative to each other.
|
|
759
|
+
* Higher values render on top of lower background layers, but still behind sprites.
|
|
760
|
+
*/
|
|
761
|
+
layer: number;
|
|
762
|
+
/**
|
|
763
|
+
* How the image is fit inside the destination rectangle.
|
|
764
|
+
* Default: `"cover"`.
|
|
765
|
+
*/
|
|
766
|
+
fit: BackgroundFit;
|
|
767
|
+
/**
|
|
768
|
+
* Optional name, so code can ask a layer what it is. Names may repeat. The
|
|
769
|
+
* engine never reads it. See {@link Sprite.name}.
|
|
770
|
+
*/
|
|
771
|
+
name: string | undefined;
|
|
772
|
+
/**
|
|
773
|
+
* Tags for grouping. Empty by default. The engine never reads them. See
|
|
774
|
+
* {@link Sprite.tags}.
|
|
775
|
+
*/
|
|
776
|
+
tags: string[];
|
|
777
|
+
/**
|
|
778
|
+
* The game's own values for this layer. An empty object by default. The
|
|
779
|
+
* engine never reads it. See {@link Sprite.data}.
|
|
780
|
+
*/
|
|
781
|
+
data: Record<string, unknown>;
|
|
782
|
+
/**
|
|
783
|
+
* Creates a new background layer.
|
|
784
|
+
*
|
|
785
|
+
* @param imageKey - Preloaded image key previously registered with {@link Game.loadImage}.
|
|
786
|
+
* @param x - Destination rectangle left edge in screen space. Default: `0`.
|
|
787
|
+
* @param y - Destination rectangle top edge in screen space. Default: `0`.
|
|
788
|
+
* @param width - Destination rectangle width. `0` means canvas width. Default: `0`.
|
|
789
|
+
* @param height - Destination rectangle height. `0` means canvas height. Default: `0`.
|
|
790
|
+
*/
|
|
791
|
+
constructor(imageKey: string, x?: number, y?: number, width?: number, height?: number);
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* The objects {@link Game.createObjectList} created, in the order of their
|
|
795
|
+
* data, and searches on them.
|
|
796
|
+
*
|
|
797
|
+
* An `ObjectList` only holds and finds its objects; it never changes them.
|
|
798
|
+
* Remove them through the game, as any other object:
|
|
799
|
+
*
|
|
800
|
+
* ```ts
|
|
801
|
+
* for (const obj of ui.objects) {
|
|
802
|
+
* if (obj instanceof BackgroundLayer) game.destroyBackgroundLayer(obj);
|
|
803
|
+
* else game.destroySprite(obj);
|
|
804
|
+
* }
|
|
805
|
+
* ```
|
|
806
|
+
*
|
|
807
|
+
* Searches read each object's current {@link Sprite.name} and
|
|
808
|
+
* {@link Sprite.tags}. In TypeScript, name the type you expect:
|
|
809
|
+
* `ui.findByName<ImageSprite>("play")`.
|
|
810
|
+
*/
|
|
811
|
+
export declare class ObjectList {
|
|
812
|
+
/** Every object created, in the order of the data. */
|
|
813
|
+
readonly objects: readonly (Sprite | BackgroundLayer)[];
|
|
814
|
+
/**
|
|
815
|
+
* Returns the first object whose `name` is `name`, in order.
|
|
816
|
+
* Throws an error naming `name` when there is none.
|
|
817
|
+
*
|
|
818
|
+
* @example
|
|
819
|
+
* ```ts
|
|
820
|
+
* const play = ui.findByName("play");
|
|
821
|
+
* ```
|
|
822
|
+
*/
|
|
823
|
+
findByName<T extends Sprite | BackgroundLayer = Sprite | BackgroundLayer>(name: string): T;
|
|
824
|
+
/** Returns every object whose `name` is `name`, in order; an empty list when there is none. */
|
|
825
|
+
findAllByName<T extends Sprite | BackgroundLayer = Sprite | BackgroundLayer>(name: string): T[];
|
|
826
|
+
/**
|
|
827
|
+
* Returns the first object whose `tags` include `tag`, in order.
|
|
828
|
+
* Throws an error naming `tag` when there is none.
|
|
829
|
+
*/
|
|
830
|
+
findByTag<T extends Sprite | BackgroundLayer = Sprite | BackgroundLayer>(tag: string): T;
|
|
831
|
+
/** Returns every object whose `tags` include `tag`, in order; an empty list when there is none. */
|
|
832
|
+
findAllByTag<T extends Sprite | BackgroundLayer = Sprite | BackgroundLayer>(tag: string): T[];
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* Builds the object for a design object whose tags include the tag it was
|
|
836
|
+
* registered for. See {@link Game.registerBuilderByTag}.
|
|
837
|
+
*/
|
|
838
|
+
export type ObjectBuilder = (obj: DesignObject, game: Game) => Sprite | BackgroundLayer;
|
|
189
839
|
/**
|
|
190
840
|
* Snapshot of an active pointer tracked by the engine.
|
|
191
841
|
*
|
|
@@ -257,21 +907,21 @@ export interface CollisionInfo {
|
|
|
257
907
|
* You must import it with standard ESM syntax such as:
|
|
258
908
|
*
|
|
259
909
|
* ```ts
|
|
260
|
-
* import { Game,
|
|
910
|
+
* import { Game, EmojiSprite } from "minimojs";
|
|
261
911
|
* ```
|
|
262
912
|
*
|
|
263
913
|
* In the browser, use it from a module script:
|
|
264
914
|
*
|
|
265
915
|
* ```html
|
|
266
916
|
* <script type="module">
|
|
267
|
-
* import { Game,
|
|
917
|
+
* import { Game, EmojiSprite } from "./dist/minimo.js";
|
|
268
918
|
* </script>
|
|
269
919
|
* ```
|
|
270
920
|
*
|
|
271
921
|
* Or from a CDN:
|
|
272
922
|
*
|
|
273
923
|
* ```ts
|
|
274
|
-
* import { Game,
|
|
924
|
+
* import { Game, EmojiSprite } from "https://cdn.jsdelivr.net/npm/minimojs@<version>/dist/minimo.js";
|
|
275
925
|
* ```
|
|
276
926
|
*
|
|
277
927
|
* Do NOT use a classic `<script>` tag without `type="module"`.
|
|
@@ -280,12 +930,21 @@ export interface CollisionInfo {
|
|
|
280
930
|
*
|
|
281
931
|
* ---
|
|
282
932
|
*
|
|
283
|
-
* ##
|
|
933
|
+
* ## Font Setup
|
|
934
|
+
*
|
|
935
|
+
* `drawText()` and `TextSprite` default to `monospace`, which every device
|
|
936
|
+
* has, so a game that names no font downloads none and waits for none. To use
|
|
937
|
+
* a web font, declare it in your page, register it with {@link Game.requireFont}
|
|
938
|
+
* before calling {@link Game.start}, and name it in {@link TextSprite.fontFamily}.
|
|
939
|
+
*
|
|
940
|
+
* Prefer {@link TextSprite} for persistent UI text, interactive labels,
|
|
941
|
+
* buttons, fixed-size text boxes, and styled text elements. Keep
|
|
942
|
+
* `drawText()` for simple screen-space overlays such as HUD counters, debug
|
|
943
|
+
* text, or other text that is redrawn every frame.
|
|
284
944
|
*
|
|
285
|
-
*
|
|
286
|
-
*
|
|
287
|
-
* the
|
|
288
|
-
* If the font is missing, the browser falls back to `monospace`.
|
|
945
|
+
* You MUST still declare the fonts yourself in your `index.html`. MinimoJS
|
|
946
|
+
* does NOT download, inject, or manage web fonts for you. If a font is missing,
|
|
947
|
+
* the browser falls back to `monospace`.
|
|
289
948
|
*
|
|
290
949
|
* Example `index.html` `<head>` setup:
|
|
291
950
|
*
|
|
@@ -298,17 +957,32 @@ export interface CollisionInfo {
|
|
|
298
957
|
* />
|
|
299
958
|
* ```
|
|
300
959
|
*
|
|
960
|
+
* Example custom font registration:
|
|
961
|
+
*
|
|
962
|
+
* ```ts
|
|
963
|
+
* const game = new Game(720, 1280);
|
|
964
|
+
* game.requireFont('"Bangers"', { weight: "400" });
|
|
965
|
+
* game.start();
|
|
966
|
+
* ```
|
|
967
|
+
*
|
|
301
968
|
* ---
|
|
302
969
|
*
|
|
303
970
|
* ## Quick Start
|
|
304
971
|
*
|
|
305
972
|
* ```ts
|
|
306
|
-
* import { Game,
|
|
973
|
+
* import { Game, ImageSprite } from "https://cdn.jsdelivr.net/npm/minimojs@<version>/dist/minimo.js";
|
|
974
|
+
*
|
|
975
|
+
* const game = new Game(720, 1280);
|
|
307
976
|
*
|
|
308
|
-
*
|
|
977
|
+
* game.onPreload = () => {
|
|
978
|
+
* game.loadImage("player", "assets/player.png");
|
|
979
|
+
* };
|
|
309
980
|
*
|
|
310
|
-
*
|
|
311
|
-
*
|
|
981
|
+
* let player: ImageSprite;
|
|
982
|
+
*
|
|
983
|
+
* game.onCreate = () => {
|
|
984
|
+
* player = game.add(new ImageSprite(game, "player", 400, 500));
|
|
985
|
+
* };
|
|
312
986
|
*
|
|
313
987
|
* game.onUpdate = (dt) => {
|
|
314
988
|
* if (game.isKeyDown("ArrowLeft")) player.vx = -200;
|
|
@@ -321,6 +995,13 @@ export interface CollisionInfo {
|
|
|
321
995
|
* game.start();
|
|
322
996
|
* ```
|
|
323
997
|
*
|
|
998
|
+
* Prototyping, and have no art yet? Swap the texture for an emoji and drop the
|
|
999
|
+
* preload entirely — everything else stays the same:
|
|
1000
|
+
*
|
|
1001
|
+
* ```ts
|
|
1002
|
+
* const player = game.add(new EmojiSprite("🐢", 400, 500, 48));
|
|
1003
|
+
* ```
|
|
1004
|
+
*
|
|
324
1005
|
* ---
|
|
325
1006
|
*
|
|
326
1007
|
* ## Engine Philosophy
|
|
@@ -346,13 +1027,28 @@ export interface CollisionInfo {
|
|
|
346
1027
|
*
|
|
347
1028
|
* ---
|
|
348
1029
|
*
|
|
349
|
-
* ##
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
*
|
|
355
|
-
*
|
|
1030
|
+
* ## Choosing a Visual Source
|
|
1031
|
+
*
|
|
1032
|
+
* A sprite's look comes from one of four concrete types, all of which extend the
|
|
1033
|
+
* shared abstract {@link Sprite} type. Use `Sprite` as the type in your own
|
|
1034
|
+
* signatures; never construct it directly.
|
|
1035
|
+
*
|
|
1036
|
+
* 1. {@link ImageSprite} — the game's own images, and the first option to reach
|
|
1037
|
+
* for. Register a texture with {@link Game.loadImage} inside
|
|
1038
|
+
* {@link Game.onPreload}, or build one at runtime with
|
|
1039
|
+
* {@link Game.createTexture}, then render it with
|
|
1040
|
+
* `new ImageSprite(game, key, x, y)`. An image looks identical on every
|
|
1041
|
+
* device and belongs to the game.
|
|
1042
|
+
* 2. {@link EmojiSprite} — a single Unicode emoji, and the shortest path to a
|
|
1043
|
+
* first prototype: `new EmojiSprite("🐢", x, y, size)`. Note that an
|
|
1044
|
+
* emoji is drawn with the player's own system emoji font, so the same game
|
|
1045
|
+
* looks different across iOS, Android, and Windows, and a glyph the platform
|
|
1046
|
+
* lacks renders as an empty box. Prefer an image whenever the look matters.
|
|
1047
|
+
* 3. {@link TextSprite} — text, labels, and buttons.
|
|
1048
|
+
* 4. {@link DrawSprite} — procedural Canvas 2D drawing, for shapes and gauges
|
|
1049
|
+
* the other three cannot express cleanly.
|
|
1050
|
+
*
|
|
1051
|
+
* Emoji and images mix freely in one game.
|
|
356
1052
|
*
|
|
357
1053
|
* ---
|
|
358
1054
|
*
|
|
@@ -368,7 +1064,7 @@ export interface CollisionInfo {
|
|
|
368
1064
|
*
|
|
369
1065
|
* ALL time parameters to engine methods are in **milliseconds (ms)**.
|
|
370
1066
|
* This includes: {@link Game.addTimer}, {@link Game.animateAlpha},
|
|
371
|
-
* {@link Game.animateRotation}, and {@link Game.sound}.
|
|
1067
|
+
* {@link Game.animateRotation}, {@link Game.animateDeform}, and {@link Game.sound}.
|
|
372
1068
|
*
|
|
373
1069
|
* The `dt` parameter in {@link Game.onUpdate} is an exception — it is in
|
|
374
1070
|
* **seconds** for convenient velocity math (`position += velocity * dt`).
|
|
@@ -420,10 +1116,10 @@ export interface CollisionInfo {
|
|
|
420
1116
|
*
|
|
421
1117
|
* ---
|
|
422
1118
|
*
|
|
423
|
-
* ## Scene Initialization with `
|
|
1119
|
+
* ## Scene Initialization with `IScene`
|
|
424
1120
|
*
|
|
425
|
-
* MinimoJS
|
|
426
|
-
*
|
|
1121
|
+
* MinimoJS supports simple scene objects via {@link IScene}. The engine calls
|
|
1122
|
+
* a scene's `onCreate()`:
|
|
427
1123
|
* - Once before the first frame (when {@link Game.start} is called).
|
|
428
1124
|
* - Again after each {@link Game.reset}.
|
|
429
1125
|
*
|
|
@@ -435,28 +1131,42 @@ export interface CollisionInfo {
|
|
|
435
1131
|
* - Scroll position (scrollX and scrollY reset to 0)
|
|
436
1132
|
* - Per-frame input state (pressed keys/pointer)
|
|
437
1133
|
*
|
|
438
|
-
* After clearing, `reset()` calls `onCreate()` so
|
|
439
|
-
*
|
|
1134
|
+
* After clearing, `reset()` calls the active scene's `onCreate()` so it can
|
|
1135
|
+
* rebuild immediately. Simply re-add sprites and re-register timers.
|
|
440
1136
|
*
|
|
441
1137
|
* ```ts
|
|
442
|
-
*
|
|
443
|
-
*
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
*
|
|
1138
|
+
* class SkullScene implements IScene {
|
|
1139
|
+
* onCreate() {
|
|
1140
|
+
* const skull = new EmojiSprite("💀", 400, 300, 96);
|
|
1141
|
+
* game.add(skull);
|
|
1142
|
+
* }
|
|
447
1143
|
*
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
1144
|
+
* onUpdate(dt: number) {
|
|
1145
|
+
* // normal per-frame update
|
|
1146
|
+
* }
|
|
1147
|
+
* }
|
|
451
1148
|
*
|
|
452
|
-
*
|
|
1149
|
+
* const scene = new SkullScene();
|
|
1150
|
+
* game.start(scene); // calls onCreate() once before first frame
|
|
453
1151
|
* // later:
|
|
454
1152
|
* game.reset(); // clears + calls onCreate() again
|
|
455
1153
|
* ```
|
|
456
1154
|
*
|
|
1155
|
+
* Legacy `game.onCreate` / `game.onUpdate` callbacks still work when no active
|
|
1156
|
+
* {@link IScene} is set.
|
|
1157
|
+
*
|
|
1158
|
+
* ### Loading a Scene's Own Images
|
|
1159
|
+
*
|
|
1160
|
+
* Load images in {@link Game.onPreload}: once, at boot. Only a game with many
|
|
1161
|
+
* scenes that each carry many assets of their own — typically a game with many
|
|
1162
|
+
* levels, whose player does not reach every level in a session — should give
|
|
1163
|
+
* scenes an {@link IScene.onPreload}. Entering such a scene loads its images
|
|
1164
|
+
* first, with the scene being left frozen and dimmed under a progress ring, so `reset()`
|
|
1165
|
+
* and `transitionTo()` may return before the new scene's `onCreate()` runs.
|
|
1166
|
+
*
|
|
457
1167
|
* ---
|
|
458
1168
|
*
|
|
459
|
-
* ##
|
|
1169
|
+
* ## EmojiSprite Lifecycle Ownership
|
|
460
1170
|
*
|
|
461
1171
|
* The `Game` instance owns all sprites.
|
|
462
1172
|
* - Create sprites with {@link Game.add}.
|
|
@@ -470,7 +1180,7 @@ export interface CollisionInfo {
|
|
|
470
1180
|
* ## Forbidden Features
|
|
471
1181
|
*
|
|
472
1182
|
* The following do NOT exist in MinimoJS v1. Do NOT attempt to use them:
|
|
473
|
-
* -
|
|
1183
|
+
* - Full scene manager architecture (scene stacks, transitions, loaders, etc.)
|
|
474
1184
|
* - Entity Component System (ECS)
|
|
475
1185
|
* - Physics engine (no Box2D, Matter.js, etc.)
|
|
476
1186
|
* - Camera zoom or scale
|
|
@@ -479,7 +1189,6 @@ export interface CollisionInfo {
|
|
|
479
1189
|
* - Parallax layers
|
|
480
1190
|
* - Multiple cameras
|
|
481
1191
|
* - Full physics engine (only basic explicit AABB collision helpers are provided)
|
|
482
|
-
* - Image sprites (PNG, SVG, canvas, etc.)
|
|
483
1192
|
* - `setTimeout` or `setInterval`
|
|
484
1193
|
*/
|
|
485
1194
|
export declare class Game {
|
|
@@ -494,7 +1203,8 @@ export declare class Game {
|
|
|
494
1203
|
* game.gravityX = 0; // no horizontal gravity
|
|
495
1204
|
* ```
|
|
496
1205
|
*/
|
|
497
|
-
gravityX: number;
|
|
1206
|
+
get gravityX(): number;
|
|
1207
|
+
set gravityX(value: number);
|
|
498
1208
|
/**
|
|
499
1209
|
* Vertical gravity acceleration in pixels per second².
|
|
500
1210
|
* Applied to every sprite whose {@link Sprite.gravityScale} is non-zero.
|
|
@@ -507,7 +1217,8 @@ export declare class Game {
|
|
|
507
1217
|
* game.gravityY = 980; // standard downward gravity
|
|
508
1218
|
* ```
|
|
509
1219
|
*/
|
|
510
|
-
gravityY: number;
|
|
1220
|
+
get gravityY(): number;
|
|
1221
|
+
set gravityY(value: number);
|
|
511
1222
|
/**
|
|
512
1223
|
* Enables the basic collision-resolution helpers (`collide` / `collideAny`).
|
|
513
1224
|
*
|
|
@@ -521,7 +1232,8 @@ export declare class Game {
|
|
|
521
1232
|
* game.physics = true;
|
|
522
1233
|
* ```
|
|
523
1234
|
*/
|
|
524
|
-
physics: boolean;
|
|
1235
|
+
get physics(): boolean;
|
|
1236
|
+
set physics(value: boolean);
|
|
525
1237
|
/**
|
|
526
1238
|
* Horizontal scroll offset of the world camera, in pixels.
|
|
527
1239
|
* The canvas viewport is shifted left by `scrollX` — sprites with higher `x`
|
|
@@ -569,6 +1281,20 @@ export declare class Game {
|
|
|
569
1281
|
from: string;
|
|
570
1282
|
to: string;
|
|
571
1283
|
} | null;
|
|
1284
|
+
/**
|
|
1285
|
+
* When `true`, MinimoJS draws every sprite's collision body as an overlay.
|
|
1286
|
+
*
|
|
1287
|
+
* This is a runtime debugging aid only. It does not change collisions,
|
|
1288
|
+
* input, rendering order, or physics behavior.
|
|
1289
|
+
*/
|
|
1290
|
+
debugBodies: boolean;
|
|
1291
|
+
/**
|
|
1292
|
+
* When `true`, MinimoJS draws every sprite's input area as an overlay.
|
|
1293
|
+
*
|
|
1294
|
+
* This is a runtime debugging aid only. It does not change input behavior,
|
|
1295
|
+
* physics, or rendering.
|
|
1296
|
+
*/
|
|
1297
|
+
debugInputAreas: boolean;
|
|
572
1298
|
/**
|
|
573
1299
|
* Background color for the full web page (`document.body`).
|
|
574
1300
|
* Set to any valid CSS color string. Default: `null` (engine leaves page background unchanged).
|
|
@@ -582,24 +1308,49 @@ export declare class Game {
|
|
|
582
1308
|
*/
|
|
583
1309
|
pageBackground: string | null;
|
|
584
1310
|
/**
|
|
585
|
-
*
|
|
1311
|
+
* Asset registration callback invoked once before the first scene is created.
|
|
1312
|
+
*
|
|
1313
|
+
* This is the normal place to load a game's images and sounds. Use it to register them
|
|
1314
|
+
* with {@link Game.loadAssets}, {@link Game.loadImage}, or {@link Game.loadSound}. The callback is synchronous: it should only
|
|
1315
|
+
* queue assets, not await network work.
|
|
1316
|
+
*
|
|
1317
|
+
* After `onPreload` returns, MinimoJS loads the queued images and sounds, together with
|
|
1318
|
+
* those of the first scene's {@link IScene.onPreload} if it has one, and
|
|
1319
|
+
* shows a loading line until they are ready. If any file fails, it asks the
|
|
1320
|
+
* player with `window.confirm` whether to retry them; declining leaves the
|
|
1321
|
+
* game on the loading screen and reports the failed files on the console.
|
|
1322
|
+
*
|
|
1323
|
+
* @example
|
|
1324
|
+
* ```ts
|
|
1325
|
+
* game.onPreload = () => {
|
|
1326
|
+
* game.loadImage("sky", "assets/sky.png");
|
|
1327
|
+
* game.loadImage("land", "assets/land.png");
|
|
1328
|
+
* };
|
|
1329
|
+
* ```
|
|
1330
|
+
*/
|
|
1331
|
+
onPreload: (() => void) | null;
|
|
1332
|
+
/**
|
|
1333
|
+
* Legacy scene creation callback.
|
|
586
1334
|
*
|
|
587
1335
|
* Called once before the first frame on {@link Game.start}, and again after
|
|
588
|
-
* each {@link Game.reset}
|
|
1336
|
+
* each {@link Game.reset} when no active {@link IScene} is set.
|
|
589
1337
|
*
|
|
590
1338
|
* @example
|
|
591
1339
|
* ```ts
|
|
592
1340
|
* game.onCreate = () => {
|
|
593
|
-
* const player = new
|
|
1341
|
+
* const player = new EmojiSprite("🐢");
|
|
594
1342
|
* player.x = 200;
|
|
595
1343
|
* player.y = 300;
|
|
596
1344
|
* game.add(player);
|
|
597
1345
|
* };
|
|
598
1346
|
* ```
|
|
599
1347
|
*/
|
|
600
|
-
onCreate: (() => void) | null;
|
|
1348
|
+
get onCreate(): (() => void) | null;
|
|
1349
|
+
set onCreate(callback: (() => void) | null);
|
|
601
1350
|
/**
|
|
602
|
-
*
|
|
1351
|
+
* Legacy per-frame callback invoked after physics and timer updates.
|
|
1352
|
+
*
|
|
1353
|
+
* This is used only when no active {@link IScene} is set.
|
|
603
1354
|
*
|
|
604
1355
|
* @param dt - Delta time in **seconds** since the last frame.
|
|
605
1356
|
* Use this for velocity-based movement: `sprite.x += speed * dt`.
|
|
@@ -607,121 +1358,401 @@ export declare class Game {
|
|
|
607
1358
|
*
|
|
608
1359
|
* @example
|
|
609
1360
|
* ```ts
|
|
610
|
-
* game.onUpdate = (dt) => {
|
|
611
|
-
* if (game.isKeyDown("ArrowRight")) player.vx = 200;
|
|
612
|
-
* else player.vx = 0;
|
|
613
|
-
* };
|
|
1361
|
+
* game.onUpdate = (dt) => {
|
|
1362
|
+
* if (game.isKeyDown("ArrowRight")) player.vx = 200;
|
|
1363
|
+
* else player.vx = 0;
|
|
1364
|
+
* };
|
|
1365
|
+
* ```
|
|
1366
|
+
*/
|
|
1367
|
+
onUpdate: ((dt: number) => void) | null;
|
|
1368
|
+
/**
|
|
1369
|
+
* Currently active scene object, if any.
|
|
1370
|
+
*/
|
|
1371
|
+
get currentScene(): IScene | null;
|
|
1372
|
+
/**
|
|
1373
|
+
* Returns `true` while a full-screen scene transition is playing.
|
|
1374
|
+
*/
|
|
1375
|
+
get isTransitioning(): boolean;
|
|
1376
|
+
/**
|
|
1377
|
+
* Returns `true` while images are loading: at boot, or while a scene with
|
|
1378
|
+
* pending images in its {@link IScene.onPreload} is being entered. While a
|
|
1379
|
+
* scene loads, the scene being left is frozen and `reset()` and
|
|
1380
|
+
* `transitionTo()` are ignored.
|
|
1381
|
+
*/
|
|
1382
|
+
get isLoading(): boolean;
|
|
1383
|
+
/**
|
|
1384
|
+
* Creates a new MinimoJS game instance.
|
|
1385
|
+
*
|
|
1386
|
+
* The engine creates its own `<canvas>`, sets its dimensions, and appends it
|
|
1387
|
+
* to `document.body`. The canvas is automatically centered and responsively
|
|
1388
|
+
* scaled to use the maximum available viewport space while preserving aspect ratio.
|
|
1389
|
+
* For new mobile-first Minimo Games, prefer a portrait canvas such as `720x1280`.
|
|
1390
|
+
*
|
|
1391
|
+
* @param width - Canvas width in pixels. Default: `720`.
|
|
1392
|
+
* @param height - Canvas height in pixels. Default: `1280`.
|
|
1393
|
+
*
|
|
1394
|
+
* @throws Error if a 2D context cannot be obtained.
|
|
1395
|
+
*
|
|
1396
|
+
* @example
|
|
1397
|
+
* ```ts
|
|
1398
|
+
* const game = new Game(720, 1280);
|
|
1399
|
+
* game.physics = true;
|
|
1400
|
+
* ```
|
|
1401
|
+
*/
|
|
1402
|
+
constructor(width?: number, height?: number);
|
|
1403
|
+
/**
|
|
1404
|
+
* The width of the canvas in pixels. Read-only — set via constructor.
|
|
1405
|
+
*/
|
|
1406
|
+
get width(): number;
|
|
1407
|
+
/**
|
|
1408
|
+
* The height of the canvas in pixels. Read-only — set via constructor.
|
|
1409
|
+
*/
|
|
1410
|
+
get height(): number;
|
|
1411
|
+
/**
|
|
1412
|
+
* Current pointer (mouse or touch) X position in **canvas/screen space**,
|
|
1413
|
+
* in pixels. Updated every `mousemove` / `touchmove` event.
|
|
1414
|
+
* `(0, 0)` is the top-left corner of the canvas.
|
|
1415
|
+
* To convert to world space: `worldX = game.pointerX + game.scrollX`.
|
|
1416
|
+
*
|
|
1417
|
+
* On a touch screen the pointer is one finger: the first to touch while no
|
|
1418
|
+
* finger is followed. Other fingers never move it, and when the followed
|
|
1419
|
+
* finger lifts, the pointer stays where it left the screen even if others
|
|
1420
|
+
* are still down. Use {@link Game.getPointers} to follow several fingers.
|
|
1421
|
+
*/
|
|
1422
|
+
get pointerX(): number;
|
|
1423
|
+
/**
|
|
1424
|
+
* Current pointer (mouse or touch) Y position in **canvas/screen space**,
|
|
1425
|
+
* in pixels. Updated every `mousemove` / `touchmove` event.
|
|
1426
|
+
* `(0, 0)` is the top-left corner of the canvas.
|
|
1427
|
+
* To convert to world space: `worldY = game.pointerY + game.scrollY`.
|
|
1428
|
+
*/
|
|
1429
|
+
get pointerY(): number;
|
|
1430
|
+
/**
|
|
1431
|
+
* Registers a {@link Sprite} (or subclass instance) with the engine.
|
|
1432
|
+
*
|
|
1433
|
+
* After calling `add`, the sprite is rendered and, if dynamic
|
|
1434
|
+
* (`isStatic = false`), receives built-in velocity/gravity integration every
|
|
1435
|
+
* frame until {@link Game.destroySprite} or {@link Game.reset} is called.
|
|
1436
|
+
*
|
|
1437
|
+
* **Ownership:** The game instance takes ownership of the sprite from this
|
|
1438
|
+
* point forward. It will appear in {@link Game.getSprites} on the same frame.
|
|
1439
|
+
*
|
|
1440
|
+
* **Subclasses:** Any class that extends {@link Sprite} can be passed here.
|
|
1441
|
+
* The engine stores and processes it as a live sprite; your custom properties
|
|
1442
|
+
* are preserved on the instance.
|
|
1443
|
+
*
|
|
1444
|
+
* @param sprite - A {@link Sprite} instance (or subclass) to add.
|
|
1445
|
+
* @returns The same sprite instance, for chaining or inline assignment.
|
|
1446
|
+
*
|
|
1447
|
+
* @example
|
|
1448
|
+
* ```ts
|
|
1449
|
+
* // Plain sprite
|
|
1450
|
+
* const coin = new EmojiSprite("🪙", 300, 200, 32);
|
|
1451
|
+
* game.add(coin);
|
|
1452
|
+
*
|
|
1453
|
+
* // Custom subclass
|
|
1454
|
+
* class Enemy extends EmojiSprite {
|
|
1455
|
+
* speed = 150;
|
|
1456
|
+
* constructor(x: number, y: number) {
|
|
1457
|
+
* super("👾", x, y, 40);
|
|
1458
|
+
* }
|
|
1459
|
+
* }
|
|
1460
|
+
* const enemy = game.add(new Enemy(600, 100));
|
|
1461
|
+
* ```
|
|
1462
|
+
*/
|
|
1463
|
+
add<T extends Sprite>(sprite: T): T;
|
|
1464
|
+
/**
|
|
1465
|
+
* Registers a {@link BackgroundLayer} with the engine.
|
|
1466
|
+
*
|
|
1467
|
+
* Background layers are rendered behind all sprites and are not affected by
|
|
1468
|
+
* physics, collisions, or sprite queries.
|
|
1469
|
+
*
|
|
1470
|
+
* @param layer - The background layer to add.
|
|
1471
|
+
* @returns The same background layer instance.
|
|
1472
|
+
*
|
|
1473
|
+
* @example
|
|
1474
|
+
* ```ts
|
|
1475
|
+
* const sky = game.addBackground(new BackgroundLayer("sky"));
|
|
1476
|
+
* sky.fit = "cover";
|
|
1477
|
+
* ```
|
|
1478
|
+
*/
|
|
1479
|
+
addBackground(layer: BackgroundLayer): BackgroundLayer;
|
|
1480
|
+
/**
|
|
1481
|
+
* Removes a sprite from the engine, stopping its rendering and physics updates.
|
|
1482
|
+
* Also cancels any running animations targeting this sprite.
|
|
1483
|
+
*
|
|
1484
|
+
* **Side effects:** The sprite is removed immediately. Accessing the sprite's
|
|
1485
|
+
* fields after destruction has no effect on the engine, but reading them
|
|
1486
|
+
* returns stale values. Do not keep references to destroyed sprites.
|
|
1487
|
+
*
|
|
1488
|
+
* If `sprite` is not found (already destroyed or never added), this is a no-op.
|
|
1489
|
+
*
|
|
1490
|
+
* @param sprite - The sprite instance to destroy, as passed to {@link Game.add}.
|
|
1491
|
+
*
|
|
1492
|
+
* @example
|
|
1493
|
+
* ```ts
|
|
1494
|
+
* game.destroySprite(enemy); // remove enemy from game
|
|
1495
|
+
* ```
|
|
1496
|
+
*/
|
|
1497
|
+
destroySprite(sprite: Sprite): void;
|
|
1498
|
+
/**
|
|
1499
|
+
* Removes a background layer from the engine.
|
|
1500
|
+
*
|
|
1501
|
+
* If the layer is not currently registered, this is a safe no-op.
|
|
1502
|
+
*
|
|
1503
|
+
* @param layer - The background layer to remove.
|
|
1504
|
+
*/
|
|
1505
|
+
destroyBackgroundLayer(layer: BackgroundLayer): void;
|
|
1506
|
+
/**
|
|
1507
|
+
* Returns a **read-only snapshot** of all currently active sprites.
|
|
1508
|
+
* The array is a shallow copy — mutating it has no effect on the engine.
|
|
1509
|
+
* Individual sprite objects in the array are the live instances.
|
|
1510
|
+
*
|
|
1511
|
+
* **Deterministic guarantee:** Sprites appear in creation order within each
|
|
1512
|
+
* layer. The order matches the render order (lower layer = earlier in array).
|
|
1513
|
+
*
|
|
1514
|
+
* @returns A read-only array of active {@link Sprite} instances.
|
|
1515
|
+
*
|
|
1516
|
+
* @example
|
|
1517
|
+
* ```ts
|
|
1518
|
+
* const enemies = game.getSprites().filter(s => s.sprite === "👾");
|
|
1519
|
+
* ```
|
|
1520
|
+
*/
|
|
1521
|
+
getSprites(): readonly Sprite[];
|
|
1522
|
+
/**
|
|
1523
|
+
* Returns a read-only snapshot of all active background layers.
|
|
1524
|
+
*
|
|
1525
|
+
* Background layers are returned in creation order within each layer value.
|
|
1526
|
+
*/
|
|
1527
|
+
getBackgroundLayers(): readonly BackgroundLayer[];
|
|
1528
|
+
/**
|
|
1529
|
+
* Queues an image to be loaded during {@link Game.onPreload}.
|
|
1530
|
+
*
|
|
1531
|
+
* This method registers the asset only. The actual network/image fetch begins
|
|
1532
|
+
* after `onPreload` returns and is managed automatically by the engine.
|
|
1533
|
+
*
|
|
1534
|
+
* `loadImage` may only be called from within {@link Game.onPreload} or a
|
|
1535
|
+
* scene's {@link IScene.onPreload}.
|
|
1536
|
+
*
|
|
1537
|
+
* Images are requested with CORS, as sounds are, so the canvas stays
|
|
1538
|
+
* readable and exportable. An image on another origin loads only when its
|
|
1539
|
+
* host answers with CORS headers.
|
|
1540
|
+
*
|
|
1541
|
+
* @param key - Stable key used later by {@link BackgroundLayer.imageKey} or {@link Game.getImage}.
|
|
1542
|
+
* @param src - Image URL or relative path.
|
|
1543
|
+
*
|
|
1544
|
+
* @example
|
|
1545
|
+
* ```ts
|
|
1546
|
+
* game.onPreload = () => {
|
|
1547
|
+
* game.loadImage("sky", "assets/sky.png");
|
|
1548
|
+
* };
|
|
1549
|
+
* ```
|
|
1550
|
+
*/
|
|
1551
|
+
loadImage(key: string, src: string): void;
|
|
1552
|
+
/**
|
|
1553
|
+
* Queues an audio file to be loaded during {@link Game.onPreload}, to play
|
|
1554
|
+
* later with {@link Game.playSound}.
|
|
1555
|
+
*
|
|
1556
|
+
* Like {@link Game.loadImage}, it only registers the sound, and may only be
|
|
1557
|
+
* called from within {@link Game.onPreload} or a scene's
|
|
1558
|
+
* {@link IScene.onPreload}. The file loads and decodes with the images,
|
|
1559
|
+
* under the same loading line, and a file that fails is retried with them.
|
|
1560
|
+
* Keys are unique in the whole game: a sound cannot share its key with an
|
|
1561
|
+
* image. Prefer declaring sounds in an asset file, as `sound` entries
|
|
1562
|
+
* loaded with {@link Game.loadAssets}.
|
|
1563
|
+
*
|
|
1564
|
+
* MP3 plays in every browser; WAV does too, but its files are large. OGG
|
|
1565
|
+
* does not play in every Safari.
|
|
1566
|
+
*
|
|
1567
|
+
* @param key - Stable key used later by {@link Game.playSound}.
|
|
1568
|
+
* @param src - Audio file URL or relative path.
|
|
1569
|
+
*
|
|
1570
|
+
* @example
|
|
1571
|
+
* ```ts
|
|
1572
|
+
* game.onPreload = () => {
|
|
1573
|
+
* game.loadSound("jump", "assets/jump.mp3");
|
|
1574
|
+
* game.loadSound("theme", "assets/theme.mp3");
|
|
1575
|
+
* };
|
|
1576
|
+
* ```
|
|
1577
|
+
*/
|
|
1578
|
+
loadSound(key: string, src: string): void;
|
|
1579
|
+
/**
|
|
1580
|
+
* Queues every asset an asset file declares, as one {@link Game.loadImage}
|
|
1581
|
+
* call per `image` entry and one {@link Game.loadSound} call per `sound`
|
|
1582
|
+
* entry would.
|
|
1583
|
+
*
|
|
1584
|
+
* Pass the content of a `*.assets.json` file, obtained by JSON import. The
|
|
1585
|
+
* file is checked with {@link parseAssetFile}, and an invalid one throws an
|
|
1586
|
+
* error naming what is wrong. Like `loadImage`, `loadAssets` may only be
|
|
1587
|
+
* called from within {@link Game.onPreload} or a scene's
|
|
1588
|
+
* {@link IScene.onPreload}.
|
|
1589
|
+
*
|
|
1590
|
+
* - Keys are unique in the whole game. A key that another asset file
|
|
1591
|
+
* declares, or that {@link Game.loadImage}, {@link Game.loadSound}, or
|
|
1592
|
+
* {@link Game.createTexture} registered, throws an error naming it, and so does a later
|
|
1593
|
+
* `loadImage` or `createTexture` of a key an asset file declares.
|
|
1594
|
+
* - Loading the same file again, as a scene's `onPreload()` does each time
|
|
1595
|
+
* the scene is entered, queues only its files that are not loaded.
|
|
1596
|
+
* - An entry of a type this engine does not support is skipped, with a
|
|
1597
|
+
* console warning naming it, so the game still loads every asset it can.
|
|
1598
|
+
*
|
|
1599
|
+
* @param assets - The content of a `*.assets.json` file. See {@link AssetFile}.
|
|
1600
|
+
*
|
|
1601
|
+
* @example
|
|
1602
|
+
* ```ts
|
|
1603
|
+
* import common from "./common.assets.json" with { type: "json" };
|
|
1604
|
+
*
|
|
1605
|
+
* game.onPreload = () => game.loadAssets(common);
|
|
614
1606
|
* ```
|
|
615
1607
|
*/
|
|
616
|
-
|
|
1608
|
+
loadAssets(assets: unknown): void;
|
|
617
1609
|
/**
|
|
618
|
-
* Creates a
|
|
1610
|
+
* Creates a dynamic texture immediately and registers it under a stable key.
|
|
619
1611
|
*
|
|
620
|
-
*
|
|
621
|
-
*
|
|
622
|
-
*
|
|
1612
|
+
* Unlike {@link Game.loadImage}, this does not require {@link Game.onPreload}.
|
|
1613
|
+
* The `painter` callback receives a fresh offscreen canvas and should draw the
|
|
1614
|
+
* full texture contents into it.
|
|
623
1615
|
*
|
|
624
|
-
*
|
|
625
|
-
* @
|
|
1616
|
+
* The resulting texture can be used anywhere a normal image key is accepted,
|
|
1617
|
+
* including {@link ImageSprite}, background layers, and optional modules.
|
|
626
1618
|
*
|
|
627
|
-
* @
|
|
1619
|
+
* @param key - Stable texture key used later by sprites and render helpers.
|
|
1620
|
+
* @param width - Texture width in pixels. Minimum `1`.
|
|
1621
|
+
* @param height - Texture height in pixels. Minimum `1`.
|
|
1622
|
+
* @param painter - Function that paints into the offscreen texture canvas.
|
|
628
1623
|
*
|
|
629
1624
|
* @example
|
|
630
1625
|
* ```ts
|
|
631
|
-
*
|
|
632
|
-
*
|
|
1626
|
+
* game.createTexture("checkpoint", 128, 64, (ctx, canvas) => {
|
|
1627
|
+
* ctx.fillStyle = "#101820";
|
|
1628
|
+
* ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
1629
|
+
* ctx.fillStyle = "#ffd54f";
|
|
1630
|
+
* ctx.fillRect(8, 8, canvas.width - 16, canvas.height - 16);
|
|
1631
|
+
* });
|
|
633
1632
|
* ```
|
|
634
1633
|
*/
|
|
635
|
-
|
|
636
|
-
/**
|
|
637
|
-
* The width of the canvas in pixels. Read-only — set via constructor.
|
|
638
|
-
*/
|
|
639
|
-
get width(): number;
|
|
640
|
-
/**
|
|
641
|
-
* The height of the canvas in pixels. Read-only — set via constructor.
|
|
642
|
-
*/
|
|
643
|
-
get height(): number;
|
|
1634
|
+
createTexture(key: string, width: number, height: number, painter: (ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement) => void): HTMLCanvasElement;
|
|
644
1635
|
/**
|
|
645
|
-
*
|
|
646
|
-
*
|
|
647
|
-
*
|
|
648
|
-
* To convert to world space: `worldX = game.pointerX + game.scrollX`.
|
|
1636
|
+
* Returns a loaded image or created texture previously registered with
|
|
1637
|
+
* {@link Game.loadImage} or {@link Game.createTexture}, or `undefined` if it
|
|
1638
|
+
* is not available.
|
|
649
1639
|
*/
|
|
650
|
-
|
|
1640
|
+
getImage(key: string): HTMLImageElement | HTMLCanvasElement | undefined;
|
|
651
1641
|
/**
|
|
652
|
-
*
|
|
653
|
-
* in pixels. Updated every `mousemove` / `touchmove` event.
|
|
654
|
-
* `(0, 0)` is the top-left corner of the canvas.
|
|
655
|
-
* To convert to world space: `worldY = game.pointerY + game.scrollY`.
|
|
1642
|
+
* Returns `true` if a texture key is available.
|
|
656
1643
|
*/
|
|
657
|
-
|
|
1644
|
+
hasImage(key: string): boolean;
|
|
658
1645
|
/**
|
|
659
|
-
*
|
|
660
|
-
*
|
|
661
|
-
* (`isStatic = false`), receives built-in velocity/gravity integration every
|
|
662
|
-
* frame until {@link Game.destroySprite} or {@link Game.reset} is called.
|
|
1646
|
+
* Creates one runtime object from object data, such as a template found in
|
|
1647
|
+
* a {@link Design}, and adds it to the game.
|
|
663
1648
|
*
|
|
664
|
-
*
|
|
665
|
-
*
|
|
1649
|
+
* The object is built through the same public constructors and
|
|
1650
|
+
* {@link Game.add} or {@link Game.addBackground} that code uses, so it
|
|
1651
|
+
* behaves as the equivalent code. Its type picks its class: `image` builds
|
|
1652
|
+
* an {@link ImageSprite}, `emoji` an {@link EmojiSprite}, `text` a
|
|
1653
|
+
* {@link TextSprite}, and `background` a {@link BackgroundLayer}, unless a
|
|
1654
|
+
* builder registered with {@link Game.registerBuilderByTag} matches one of
|
|
1655
|
+
* its tags. Then every property the data holds is applied, including
|
|
1656
|
+
* `name`, `tags`, and a copy of `data`.
|
|
666
1657
|
*
|
|
667
|
-
*
|
|
668
|
-
*
|
|
669
|
-
*
|
|
1658
|
+
* A `module` object is built by its module, such as a `Flame` by the
|
|
1659
|
+
* `fire` module, which the scene must have created first, such as with
|
|
1660
|
+
* `new Fire(game)` in `onCreate()`; otherwise the creation throws an error
|
|
1661
|
+
* naming the module. Tag builders do not apply to it, and its tags are added
|
|
1662
|
+
* to those the module gives it.
|
|
670
1663
|
*
|
|
671
|
-
*
|
|
672
|
-
*
|
|
1664
|
+
* Each call creates a new object, so one template can be created any number
|
|
1665
|
+
* of times. Set its position afterwards to place it; the object is never
|
|
1666
|
+
* drawn at the template's position.
|
|
1667
|
+
*
|
|
1668
|
+
* Throws an error naming what is wrong when the data is not a valid design
|
|
1669
|
+
* object, or naming the key when it uses an image key that is not loaded.
|
|
1670
|
+
*
|
|
1671
|
+
* @param data - One design object, such as `design.findByName("player")`. Not a `Design`.
|
|
1672
|
+
* @param options - `add: false` creates the object without adding it to the game. Default: added.
|
|
1673
|
+
* @returns The created object. In TypeScript, name its type: `game.createObject<ImageSprite>(data)`.
|
|
673
1674
|
*
|
|
674
1675
|
* @example
|
|
675
1676
|
* ```ts
|
|
676
|
-
*
|
|
677
|
-
* const
|
|
678
|
-
* game.add(coin);
|
|
1677
|
+
* import charactersJson from "./characters.design.json" with { type: "json" };
|
|
1678
|
+
* const characters = new Design(charactersJson);
|
|
679
1679
|
*
|
|
680
|
-
*
|
|
681
|
-
*
|
|
682
|
-
*
|
|
683
|
-
* constructor(x: number, y: number) {
|
|
684
|
-
* super("👾", x, y, 40);
|
|
685
|
-
* }
|
|
686
|
-
* }
|
|
687
|
-
* const enemy = game.add(new Enemy(600, 100));
|
|
1680
|
+
* const bat = game.createObject(characters.findByName("bat"));
|
|
1681
|
+
* bat.x = spawn.x;
|
|
1682
|
+
* bat.y = spawn.y;
|
|
688
1683
|
* ```
|
|
689
1684
|
*/
|
|
690
|
-
|
|
1685
|
+
createObject<T extends Sprite | BackgroundLayer = Sprite | BackgroundLayer>(data: DesignObject, options?: {
|
|
1686
|
+
add?: boolean;
|
|
1687
|
+
}): T;
|
|
691
1688
|
/**
|
|
692
|
-
*
|
|
693
|
-
*
|
|
694
|
-
*
|
|
695
|
-
* **Side effects:** The sprite is removed immediately. Accessing the sprite's
|
|
696
|
-
* fields after destruction has no effect on the engine, but reading them
|
|
697
|
-
* returns stale values. Do not keep references to destroyed sprites.
|
|
1689
|
+
* Creates a runtime object from each object data, in order, and adds them
|
|
1690
|
+
* to the game, as {@link Game.createObject} does for one. Objects in the
|
|
1691
|
+
* same layer draw in the order of the data.
|
|
698
1692
|
*
|
|
699
|
-
*
|
|
1693
|
+
* Every object is checked before any is created, so invalid data or an
|
|
1694
|
+
* image key that is not loaded creates nothing.
|
|
700
1695
|
*
|
|
701
|
-
* @param
|
|
1696
|
+
* @param objects - Object data, such as `design.objects` or `design.findAllByTag("enemy")`. Not a `Design`.
|
|
1697
|
+
* @param options - `add: false` creates the objects without adding them to the game. Default: added.
|
|
1698
|
+
* @returns An {@link ObjectList} of the created objects, to find them by name or tag.
|
|
702
1699
|
*
|
|
703
1700
|
* @example
|
|
704
1701
|
* ```ts
|
|
705
|
-
*
|
|
1702
|
+
* import menuJson from "./menu.design.json" with { type: "json" };
|
|
1703
|
+
* const menu = new Design(menuJson);
|
|
1704
|
+
*
|
|
1705
|
+
* class MenuScene {
|
|
1706
|
+
* onCreate() {
|
|
1707
|
+
* const ui = game.createObjectList(menu.objects);
|
|
1708
|
+
* this.play = ui.findByName("play");
|
|
1709
|
+
* }
|
|
1710
|
+
* onUpdate() {
|
|
1711
|
+
* if (game.isPointerPressedOverSprite(this.play)) start(this.play.data.action);
|
|
1712
|
+
* }
|
|
1713
|
+
* }
|
|
706
1714
|
* ```
|
|
707
1715
|
*/
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
*
|
|
713
|
-
*
|
|
714
|
-
*
|
|
715
|
-
*
|
|
716
|
-
*
|
|
717
|
-
*
|
|
1716
|
+
createObjectList(objects: readonly DesignObject[], options?: {
|
|
1717
|
+
add?: boolean;
|
|
1718
|
+
}): ObjectList;
|
|
1719
|
+
/**
|
|
1720
|
+
* Makes {@link Game.createObject} and {@link Game.createObjectList} build
|
|
1721
|
+
* the design objects tagged `tag` with `builder`, such as an `Enemy` class
|
|
1722
|
+
* of the game's own.
|
|
1723
|
+
*
|
|
1724
|
+
* - The builder returns an instance of the object's type class or a
|
|
1725
|
+
* subclass of it: {@link ImageSprite} for `image`, {@link EmojiSprite} for
|
|
1726
|
+
* `emoji`, {@link TextSprite} for `text`, and {@link BackgroundLayer} for
|
|
1727
|
+
* `background`. Anything else throws an error naming the object.
|
|
1728
|
+
* - The engine then applies every property the data holds, so the file wins
|
|
1729
|
+
* over the constructor. Properties the data omits keep what the builder set.
|
|
1730
|
+
* An `emoji` object's `size` cannot be changed after construction, so a
|
|
1731
|
+
* builder must pass it on, or the creation throws.
|
|
1732
|
+
* - An object matching the builders of two of its tags throws an error
|
|
1733
|
+
* naming the object and both tags.
|
|
1734
|
+
* - Builders are scene state: {@link Game.reset} clears them, as it clears
|
|
1735
|
+
* timers, so each scene registers its own in `onCreate()`.
|
|
1736
|
+
* - A `module` object is always built by its module, never by a builder.
|
|
1737
|
+
*
|
|
1738
|
+
* @param tag - The tag whose objects the builder builds.
|
|
1739
|
+
* @param builder - Receives the object's data and the game, and returns the object, not yet added.
|
|
718
1740
|
*
|
|
719
1741
|
* @example
|
|
720
1742
|
* ```ts
|
|
721
|
-
*
|
|
1743
|
+
* class Enemy extends ImageSprite {
|
|
1744
|
+
* update(dt) { this.x += this.data.speed * dt; }
|
|
1745
|
+
* }
|
|
1746
|
+
*
|
|
1747
|
+
* class Level1Scene {
|
|
1748
|
+
* onCreate() {
|
|
1749
|
+
* game.registerBuilderByTag("enemy", (obj, game) => new Enemy(game, obj.imageKey));
|
|
1750
|
+
* this.enemies = game.createObjectList(level1.findAllByTag("enemy")).objects;
|
|
1751
|
+
* }
|
|
1752
|
+
* }
|
|
722
1753
|
* ```
|
|
723
1754
|
*/
|
|
724
|
-
|
|
1755
|
+
registerBuilderByTag(tag: string, builder: ObjectBuilder): void;
|
|
725
1756
|
/**
|
|
726
1757
|
* Tests whether two sprites overlap using **Axis-Aligned Bounding Box (AABB)**
|
|
727
1758
|
* collision detection.
|
|
@@ -754,7 +1785,7 @@ export declare class Game {
|
|
|
754
1785
|
*
|
|
755
1786
|
* @param listA - First group of sprites.
|
|
756
1787
|
* @param listB - Second group of sprites. May share sprites with `listA`.
|
|
757
|
-
* @returns A `[
|
|
1788
|
+
* @returns A `[EmojiSprite, EmojiSprite]` tuple of the first overlapping pair,
|
|
758
1789
|
* or `null` if no pair overlaps.
|
|
759
1790
|
*
|
|
760
1791
|
* @example
|
|
@@ -806,7 +1837,7 @@ export declare class Game {
|
|
|
806
1837
|
*
|
|
807
1838
|
* @param listA - First group of sprites.
|
|
808
1839
|
* @param listB - Second group of sprites.
|
|
809
|
-
* @returns A `[
|
|
1840
|
+
* @returns A `[EmojiSprite, EmojiSprite, CollisionInfo]` tuple for the first collision found,
|
|
810
1841
|
* or `null` if no pair overlaps.
|
|
811
1842
|
* @throws Error if the game's physics helpers are not enabled.
|
|
812
1843
|
*
|
|
@@ -859,6 +1890,8 @@ export declare class Game {
|
|
|
859
1890
|
* Use this for continuous pointer actions.
|
|
860
1891
|
*
|
|
861
1892
|
* **Hold behavior:** returns `true` every frame from press until release.
|
|
1893
|
+
* On a touch screen it follows one finger, as {@link Game.pointerX} does,
|
|
1894
|
+
* so it turns `false` when that finger lifts, even if another is down.
|
|
862
1895
|
*
|
|
863
1896
|
* @returns `true` if the pointer is currently pressed.
|
|
864
1897
|
*
|
|
@@ -887,50 +1920,50 @@ export declare class Game {
|
|
|
887
1920
|
* Returns `true` while any active pointer is held down over the target sprite.
|
|
888
1921
|
* Works with both mouse input and multiple simultaneous touches.
|
|
889
1922
|
*
|
|
890
|
-
* Pointer hit testing uses
|
|
891
|
-
*
|
|
892
|
-
*
|
|
893
|
-
*
|
|
1923
|
+
* Pointer hit testing uses the sprite's exact displayed rectangular bounds.
|
|
1924
|
+
* World-space sprites are tested against the current camera scroll. HUD
|
|
1925
|
+
* sprites with `ignoreScroll = true` are tested in screen space. For
|
|
1926
|
+
* anchored {@link TextSprite} instances, the engine first resolves
|
|
1927
|
+
* `anchorX` / `anchorY` into the final rendered center, then tests against
|
|
1928
|
+
* that rectangle.
|
|
894
1929
|
*
|
|
895
1930
|
* Use this for continuous virtual buttons such as touch movement controls.
|
|
896
1931
|
*
|
|
897
1932
|
* @param sprite - Target sprite to test. If `null` / `undefined`, returns `false`.
|
|
898
|
-
* @param radiusScale - Multiplier applied to `sprite.displaySize` to define the hit radius.
|
|
899
|
-
* Default: `0.5`.
|
|
900
1933
|
* @returns `true` if any currently held pointer overlaps the sprite hit area.
|
|
901
1934
|
*
|
|
902
1935
|
* @example
|
|
903
1936
|
* ```ts
|
|
904
|
-
* if (game.isPointerDownOverSprite(leftButton
|
|
1937
|
+
* if (game.isPointerDownOverSprite(leftButton)) {
|
|
905
1938
|
* player.x -= 200 * dt;
|
|
906
1939
|
* }
|
|
907
1940
|
* ```
|
|
908
1941
|
*/
|
|
909
|
-
isPointerDownOverSprite(sprite: Sprite | null | undefined
|
|
1942
|
+
isPointerDownOverSprite(sprite: Sprite | null | undefined): boolean;
|
|
910
1943
|
/**
|
|
911
1944
|
* Returns `true` only on the frame any pointer first pressed over the target
|
|
912
1945
|
* sprite. Works with both mouse input and multiple simultaneous touches.
|
|
913
1946
|
*
|
|
914
|
-
* Pointer hit testing uses
|
|
915
|
-
*
|
|
916
|
-
*
|
|
917
|
-
*
|
|
1947
|
+
* Pointer hit testing uses the sprite's exact displayed rectangular bounds.
|
|
1948
|
+
* World-space sprites are tested against the current camera scroll. HUD
|
|
1949
|
+
* sprites with `ignoreScroll = true` are tested in screen space. For
|
|
1950
|
+
* anchored {@link TextSprite} instances, the engine first resolves
|
|
1951
|
+
* `anchorX` / `anchorY` into the final rendered center, then tests against
|
|
1952
|
+
* that rectangle.
|
|
918
1953
|
*
|
|
919
1954
|
* Use this for one-shot virtual buttons such as menu taps.
|
|
920
1955
|
*
|
|
921
1956
|
* @param sprite - Target sprite to test. If `null` / `undefined`, returns `false`.
|
|
922
|
-
* @param radiusScale - Multiplier applied to `sprite.displaySize` to define the hit radius.
|
|
923
|
-
* Default: `0.5`.
|
|
924
1957
|
* @returns `true` if any pointer began pressing this frame over the sprite hit area.
|
|
925
1958
|
*
|
|
926
1959
|
* @example
|
|
927
1960
|
* ```ts
|
|
928
|
-
* if (game.isPointerPressedOverSprite(startButton
|
|
1961
|
+
* if (game.isPointerPressedOverSprite(startButton)) {
|
|
929
1962
|
* startGame();
|
|
930
1963
|
* }
|
|
931
1964
|
* ```
|
|
932
1965
|
*/
|
|
933
|
-
isPointerPressedOverSprite(sprite: Sprite | null | undefined
|
|
1966
|
+
isPointerPressedOverSprite(sprite: Sprite | null | undefined): boolean;
|
|
934
1967
|
/**
|
|
935
1968
|
* Returns a read-only snapshot of all currently active pointers.
|
|
936
1969
|
*
|
|
@@ -957,29 +1990,29 @@ export declare class Game {
|
|
|
957
1990
|
* Returns a read-only snapshot of all active pointers currently overlapping
|
|
958
1991
|
* the target sprite.
|
|
959
1992
|
*
|
|
960
|
-
* Pointer hit testing uses
|
|
961
|
-
*
|
|
962
|
-
*
|
|
963
|
-
*
|
|
1993
|
+
* Pointer hit testing uses the sprite's exact displayed rectangular bounds.
|
|
1994
|
+
* World-space sprites are tested against the current camera scroll. HUD
|
|
1995
|
+
* sprites with `ignoreScroll = true` are tested in screen space. For
|
|
1996
|
+
* anchored {@link TextSprite} instances, the engine first resolves
|
|
1997
|
+
* `anchorX` / `anchorY` into the final rendered center, then tests against
|
|
1998
|
+
* that rectangle.
|
|
964
1999
|
*
|
|
965
2000
|
* Use this when you need more than a boolean result, such as reading the exact
|
|
966
2001
|
* pointer position over a virtual joystick or draggable control.
|
|
967
2002
|
*
|
|
968
2003
|
* @param sprite - Target sprite to test. If `null` / `undefined`, returns an empty array.
|
|
969
|
-
* @param radiusScale - Multiplier applied to `sprite.displaySize` to define the hit radius.
|
|
970
|
-
* Default: `0.5`.
|
|
971
2004
|
* @returns A read-only array of active pointer snapshots currently over the sprite.
|
|
972
2005
|
*
|
|
973
2006
|
* @example
|
|
974
2007
|
* ```ts
|
|
975
|
-
* const touches = game.getPointersOverSprite(joystickBase
|
|
2008
|
+
* const touches = game.getPointersOverSprite(joystickBase);
|
|
976
2009
|
* if (touches.length > 0) {
|
|
977
2010
|
* const p = touches[0];
|
|
978
2011
|
* const dx = p.x - joystickBase.x;
|
|
979
2012
|
* }
|
|
980
2013
|
* ```
|
|
981
2014
|
*/
|
|
982
|
-
getPointersOverSprite(sprite: Sprite | null | undefined
|
|
2015
|
+
getPointersOverSprite(sprite: Sprite | null | undefined): readonly PointerInfo[];
|
|
983
2016
|
/**
|
|
984
2017
|
* Returns `true` when the current device appears to be mobile/touch-first.
|
|
985
2018
|
*
|
|
@@ -999,16 +2032,67 @@ export declare class Game {
|
|
|
999
2032
|
* ```
|
|
1000
2033
|
*/
|
|
1001
2034
|
isMobileDevice(): boolean;
|
|
2035
|
+
/**
|
|
2036
|
+
* Plays a sound loaded with {@link Game.loadSound} or an asset file's
|
|
2037
|
+
* `sound` entry, and returns its {@link SoundPlayback}.
|
|
2038
|
+
*
|
|
2039
|
+
* Plays overlap: playing a sound that is already playing starts another
|
|
2040
|
+
* play of it. Keep the returned playback to pause, resume, or stop it, such
|
|
2041
|
+
* as the game's music. A one-shot play stops by itself when it ends; a
|
|
2042
|
+
* looping one plays until stopped.
|
|
2043
|
+
*
|
|
2044
|
+
* - **Before the first tap.** Browsers keep a page silent until the player
|
|
2045
|
+
* taps, clicks, or presses a key. A looping sound started earlier, such as
|
|
2046
|
+
* music started in a scene's `onCreate()`, waits and begins with that
|
|
2047
|
+
* first gesture. A one-shot sound played earlier is dropped, and its
|
|
2048
|
+
* playback is returned already stopped.
|
|
2049
|
+
* - **Scenes.** {@link Game.reset} and {@link Game.transitionTo} do not stop
|
|
2050
|
+
* sounds. Stop the music yourself when a scene should change it.
|
|
2051
|
+
* - **Hidden page.** Every sound pauses while the page is hidden, and
|
|
2052
|
+
* continues when it is shown again.
|
|
2053
|
+
*
|
|
2054
|
+
* Throws an error naming the key when no sound is loaded under it.
|
|
2055
|
+
*
|
|
2056
|
+
* @param key - A key loaded with {@link Game.loadSound} or an asset file.
|
|
2057
|
+
* @param options - `loop` to repeat until stopped, and `volume` from `0` to `1`.
|
|
2058
|
+
*
|
|
2059
|
+
* @example
|
|
2060
|
+
* ```ts
|
|
2061
|
+
* game.playSound("jump");
|
|
2062
|
+
* const music = game.playSound("theme", { loop: true, volume: 0.6 });
|
|
2063
|
+
* music.pause();
|
|
2064
|
+
* music.resume();
|
|
2065
|
+
* music.stop();
|
|
2066
|
+
* ```
|
|
2067
|
+
*/
|
|
2068
|
+
playSound(key: string, options?: PlaySoundOptions): SoundPlayback;
|
|
2069
|
+
/**
|
|
2070
|
+
* Stops every sound playing from a file, such as music and effects started
|
|
2071
|
+
* with {@link Game.playSound}. Synthesized tones are not affected.
|
|
2072
|
+
*
|
|
2073
|
+
* @example
|
|
2074
|
+
* ```ts
|
|
2075
|
+
* game.stopAllSounds();
|
|
2076
|
+
* ```
|
|
2077
|
+
*/
|
|
2078
|
+
stopAllSounds(): void;
|
|
1002
2079
|
/**
|
|
1003
2080
|
* Plays a square-wave beep using the Web Audio API.
|
|
1004
2081
|
*
|
|
1005
|
-
* **
|
|
1006
|
-
*
|
|
2082
|
+
* **Retro tone, not a game's sound.** This synthesizes a square-wave tone and
|
|
2083
|
+
* needs no file, so it sounds like an old arcade machine. A game's music and
|
|
2084
|
+
* sound effects are audio files: declare them as `sound` entries in an asset
|
|
2085
|
+
* file, or load them with {@link Game.loadSound}, and play them with
|
|
2086
|
+
* {@link Game.playSound}. Use tones only for a deliberately retro game, or
|
|
2087
|
+
* when no audio file can be obtained.
|
|
1007
2088
|
*
|
|
1008
2089
|
* The AudioContext is created lazily on first call. Browsers require a user
|
|
1009
2090
|
* gesture (click, keypress) before audio can play — always call `sound()` in
|
|
1010
2091
|
* response to user input or a game event triggered by input.
|
|
1011
2092
|
*
|
|
2093
|
+
* If you need a melody/sequence, use {@link Game.soundSequence} instead of
|
|
2094
|
+
* multiple `sound()` calls in the same frame.
|
|
2095
|
+
*
|
|
1012
2096
|
* The tone fades out exponentially over `durationMs` to avoid clicks.
|
|
1013
2097
|
*
|
|
1014
2098
|
* @param freq - Frequency in Hz. Middle C = 261.6. Typical range: 100–4000 Hz.
|
|
@@ -1018,10 +2102,27 @@ export declare class Game {
|
|
|
1018
2102
|
* ```ts
|
|
1019
2103
|
* game.sound(440, 100); // 440 Hz beep for 100ms
|
|
1020
2104
|
* game.sound(261, 500); // middle C for 500ms
|
|
1021
|
-
* game.sound(880, 50); // high beep for 50ms
|
|
2105
|
+
* game.sound(880, 50); // high beep for 50ms
|
|
1022
2106
|
* ```
|
|
1023
2107
|
*/
|
|
1024
2108
|
sound(freq: number, durationMs: number): void;
|
|
2109
|
+
/**
|
|
2110
|
+
* Plays multiple square-wave tones in strict sequence.
|
|
2111
|
+
*
|
|
2112
|
+
* Like {@link Game.sound}, this is a retro tone, not a game's sound: for
|
|
2113
|
+
* music and sound effects, play audio files with {@link Game.playSound}.
|
|
2114
|
+
*
|
|
2115
|
+
* Each tuple is `[frequencyHz, durationMs]`. The next tone starts when the
|
|
2116
|
+
* previous one ends.
|
|
2117
|
+
*
|
|
2118
|
+
* @param tones - Tone tuples in playback order.
|
|
2119
|
+
*
|
|
2120
|
+
* @example
|
|
2121
|
+
* ```ts
|
|
2122
|
+
* game.soundSequence([660, 80], [820, 90], [980, 110], [1180, 150]);
|
|
2123
|
+
* ```
|
|
2124
|
+
*/
|
|
2125
|
+
soundSequence(...tones: Array<readonly [number, number]>): void;
|
|
1025
2126
|
/**
|
|
1026
2127
|
* Animates a sprite's {@link Sprite.alpha} from its current value to `to`
|
|
1027
2128
|
* over `durationMs` milliseconds using **linear interpolation**.
|
|
@@ -1070,6 +2171,289 @@ export declare class Game {
|
|
|
1070
2171
|
* ```
|
|
1071
2172
|
*/
|
|
1072
2173
|
animateRotation(sprite: Sprite, to: number, durationMs: number, onComplete?: () => void): void;
|
|
2174
|
+
/**
|
|
2175
|
+
* Animates a sprite's visual deformation using non-uniform scaling around a
|
|
2176
|
+
* normalized pivot point.
|
|
2177
|
+
*
|
|
2178
|
+
* This affects rendering only. Physics and collision bounds continue to use
|
|
2179
|
+
* {@link EmojiSprite.displaySize} and ignore the deform result.
|
|
2180
|
+
*
|
|
2181
|
+
* `pivotX` / `pivotY` are normalized anchors in the sprite's square display box:
|
|
2182
|
+
* - `0` = left/top
|
|
2183
|
+
* - `0.5` = center
|
|
2184
|
+
* - `1` = right/bottom
|
|
2185
|
+
*
|
|
2186
|
+
* For example, `pivotY = 1` keeps the bottom visually pinned while squashing
|
|
2187
|
+
* or stretching, which is useful for floor-contact animation.
|
|
2188
|
+
*
|
|
2189
|
+
* Like other MinimoJS animations, this animates from the sprite's current
|
|
2190
|
+
* deform state to the requested target and leaves the final result applied.
|
|
2191
|
+
*
|
|
2192
|
+
* @param sprite - The sprite to deform.
|
|
2193
|
+
* @param toScaleX - Target horizontal deform scale. `1` = unchanged.
|
|
2194
|
+
* @param toScaleY - Target vertical deform scale. `1` = unchanged.
|
|
2195
|
+
* @param pivotX - Horizontal pivot in normalized `[0, 1]` sprite space.
|
|
2196
|
+
* @param pivotY - Vertical pivot in normalized `[0, 1]` sprite space.
|
|
2197
|
+
* @param durationMs - Duration of the animation in **milliseconds**.
|
|
2198
|
+
* @param onComplete - Optional callback invoked when the animation finishes.
|
|
2199
|
+
*
|
|
2200
|
+
* @example
|
|
2201
|
+
* ```ts
|
|
2202
|
+
* game.animateDeform(player, 1.18, 0.85, 0.5, 1, 90, () => {
|
|
2203
|
+
* game.animateDeform(player, 1, 1, 0.5, 1, 120);
|
|
2204
|
+
* });
|
|
2205
|
+
* ```
|
|
2206
|
+
*/
|
|
2207
|
+
animateDeform(sprite: Sprite, toScaleX: number, toScaleY: number, pivotX: number, pivotY: number, durationMs: number, onComplete?: () => void): void;
|
|
2208
|
+
/**
|
|
2209
|
+
* Convenience helper that squashes a sprite around its horizontal center.
|
|
2210
|
+
*
|
|
2211
|
+
* This is equivalent to animating toward a wider, shorter visual pose using
|
|
2212
|
+
* {@link Game.animateDeform}. `pivotY = 1` is the common floor-anchored case.
|
|
2213
|
+
*
|
|
2214
|
+
* @param sprite - The sprite to squash.
|
|
2215
|
+
* @param pivotY - Vertical pivot in normalized `[0, 1]` sprite space.
|
|
2216
|
+
* @param durationMs - Duration of the animation in **milliseconds**.
|
|
2217
|
+
* @param onComplete - Optional callback invoked when the animation finishes.
|
|
2218
|
+
*/
|
|
2219
|
+
animateSquash(sprite: Sprite, pivotY: number, durationMs: number, onComplete?: () => void): void;
|
|
2220
|
+
/**
|
|
2221
|
+
* Convenience helper that stretches a sprite around its horizontal center.
|
|
2222
|
+
*
|
|
2223
|
+
* This is equivalent to animating toward a narrower, taller visual pose using
|
|
2224
|
+
* {@link Game.animateDeform}. `pivotY = 1` is the common floor-anchored case.
|
|
2225
|
+
*
|
|
2226
|
+
* @param sprite - The sprite to stretch.
|
|
2227
|
+
* @param pivotY - Vertical pivot in normalized `[0, 1]` sprite space.
|
|
2228
|
+
* @param durationMs - Duration of the animation in **milliseconds**.
|
|
2229
|
+
* @param onComplete - Optional callback invoked when the animation finishes.
|
|
2230
|
+
*/
|
|
2231
|
+
animateStretch(sprite: Sprite, pivotY: number, durationMs: number, onComplete?: () => void): void;
|
|
2232
|
+
/**
|
|
2233
|
+
* Convenience helper that applies a centered uniform scale pulse and then
|
|
2234
|
+
* returns the sprite to its neutral shape.
|
|
2235
|
+
*
|
|
2236
|
+
* Internally this runs two deform animations back-to-back using
|
|
2237
|
+
* {@link Game.animateDeform}.
|
|
2238
|
+
*
|
|
2239
|
+
* @param sprite - The sprite to pulse.
|
|
2240
|
+
* @param scale - Peak uniform scale reached midway through the pulse. `1` leaves the sprite unchanged.
|
|
2241
|
+
* @param durationMs - Total pulse duration in **milliseconds**.
|
|
2242
|
+
* @param onComplete - Optional callback invoked after the sprite returns to neutral.
|
|
2243
|
+
*
|
|
2244
|
+
* @example
|
|
2245
|
+
* ```ts
|
|
2246
|
+
* game.animatePulse(coin, 1.25, 220);
|
|
2247
|
+
* ```
|
|
2248
|
+
*/
|
|
2249
|
+
animatePulse(sprite: Sprite, scale: number, durationMs: number, onComplete?: () => void): void;
|
|
2250
|
+
/**
|
|
2251
|
+
* Applies a decaying screen-space shake to a sprite without changing its
|
|
2252
|
+
* logical position.
|
|
2253
|
+
*
|
|
2254
|
+
* This is a render-only effect. Physics, collisions, and the sprite's
|
|
2255
|
+
* `x` / `y` values are not modified.
|
|
2256
|
+
*
|
|
2257
|
+
* @param sprite - The sprite to shake.
|
|
2258
|
+
* @param intensity - Maximum shake offset in pixels.
|
|
2259
|
+
* @param durationMs - Duration of the shake in **milliseconds**.
|
|
2260
|
+
* @param onComplete - Optional callback invoked when the shake ends.
|
|
2261
|
+
*
|
|
2262
|
+
* @example
|
|
2263
|
+
* ```ts
|
|
2264
|
+
* game.animateShake(player, 18, 300);
|
|
2265
|
+
* ```
|
|
2266
|
+
*/
|
|
2267
|
+
animateShake(sprite: Sprite, intensity: number, durationMs: number, onComplete?: () => void): void;
|
|
2268
|
+
/**
|
|
2269
|
+
* Moves a sprite upward and back down to its starting position along a simple
|
|
2270
|
+
* parabolic arc.
|
|
2271
|
+
*
|
|
2272
|
+
* This animation writes directly to {@link Sprite.x} / {@link Sprite.y} while
|
|
2273
|
+
* it is active.
|
|
2274
|
+
*
|
|
2275
|
+
* @param sprite - The sprite to bounce.
|
|
2276
|
+
* @param height - Peak bounce height in pixels.
|
|
2277
|
+
* @param durationMs - Total bounce duration in **milliseconds**.
|
|
2278
|
+
* @param onComplete - Optional callback invoked when the bounce ends.
|
|
2279
|
+
*
|
|
2280
|
+
* @example
|
|
2281
|
+
* ```ts
|
|
2282
|
+
* game.animateBounce(ball, 120, 600);
|
|
2283
|
+
* ```
|
|
2284
|
+
*/
|
|
2285
|
+
animateBounce(sprite: Sprite, height: number, durationMs: number, onComplete?: () => void): void;
|
|
2286
|
+
/**
|
|
2287
|
+
* Moves a sprite upward and back down with a smooth sine-shaped float motion.
|
|
2288
|
+
*
|
|
2289
|
+
* This animation writes directly to {@link Sprite.x} / {@link Sprite.y} while
|
|
2290
|
+
* it is active.
|
|
2291
|
+
*
|
|
2292
|
+
* @param sprite - The sprite to float.
|
|
2293
|
+
* @param distance - Maximum upward travel in pixels.
|
|
2294
|
+
* @param durationMs - Total float duration in **milliseconds**.
|
|
2295
|
+
* @param onComplete - Optional callback invoked when the float ends.
|
|
2296
|
+
*
|
|
2297
|
+
* @example
|
|
2298
|
+
* ```ts
|
|
2299
|
+
* game.animateFloat(balloon, 90, 1200);
|
|
2300
|
+
* ```
|
|
2301
|
+
*/
|
|
2302
|
+
animateFloat(sprite: Sprite, distance: number, durationMs: number, onComplete?: () => void): void;
|
|
2303
|
+
/**
|
|
2304
|
+
* Toggles a sprite's rendered opacity on and off a fixed number of times.
|
|
2305
|
+
*
|
|
2306
|
+
* This is a render-only effect. The sprite remains present in the world and
|
|
2307
|
+
* keeps receiving physics updates while blinking.
|
|
2308
|
+
*
|
|
2309
|
+
* @param sprite - The sprite to blink.
|
|
2310
|
+
* @param times - Number of visible/invisible toggle cycles.
|
|
2311
|
+
* @param durationMs - Total blink duration in **milliseconds**.
|
|
2312
|
+
* @param onComplete - Optional callback invoked when blinking ends.
|
|
2313
|
+
*
|
|
2314
|
+
* @example
|
|
2315
|
+
* ```ts
|
|
2316
|
+
* game.animateBlink(player, 4, 700);
|
|
2317
|
+
* ```
|
|
2318
|
+
*/
|
|
2319
|
+
animateBlink(sprite: Sprite, times: number, durationMs: number, onComplete?: () => void): void;
|
|
2320
|
+
/**
|
|
2321
|
+
* Applies a rapid irregular alpha variation to create a damaged, unstable, or
|
|
2322
|
+
* ghost-like flicker.
|
|
2323
|
+
*
|
|
2324
|
+
* This is a render-only effect and does not change the sprite's logical
|
|
2325
|
+
* position or collision state.
|
|
2326
|
+
*
|
|
2327
|
+
* @param sprite - The sprite to flicker.
|
|
2328
|
+
* @param durationMs - Total flicker duration in **milliseconds**.
|
|
2329
|
+
* @param onComplete - Optional callback invoked when the flicker ends.
|
|
2330
|
+
*
|
|
2331
|
+
* @example
|
|
2332
|
+
* ```ts
|
|
2333
|
+
* game.animateFlicker(ghost, 900);
|
|
2334
|
+
* ```
|
|
2335
|
+
*/
|
|
2336
|
+
animateFlicker(sprite: Sprite, durationMs: number, onComplete?: () => void): void;
|
|
2337
|
+
/**
|
|
2338
|
+
* Moves a sprite from its current position to a target position along a
|
|
2339
|
+
* parabolic arc.
|
|
2340
|
+
*
|
|
2341
|
+
* This animation writes directly to {@link Sprite.x} / {@link Sprite.y} while
|
|
2342
|
+
* it is active.
|
|
2343
|
+
*
|
|
2344
|
+
* @param sprite - The sprite to move.
|
|
2345
|
+
* @param toX - Destination X position in world space.
|
|
2346
|
+
* @param toY - Destination Y position in world space.
|
|
2347
|
+
* @param arcHeight - Maximum height of the arc above the linear path, in pixels.
|
|
2348
|
+
* @param durationMs - Total arc duration in **milliseconds**.
|
|
2349
|
+
* @param onComplete - Optional callback invoked when the arc ends.
|
|
2350
|
+
*
|
|
2351
|
+
* @example
|
|
2352
|
+
* ```ts
|
|
2353
|
+
* game.animateArc(coin, player.x, player.y, 80, 420);
|
|
2354
|
+
* ```
|
|
2355
|
+
*/
|
|
2356
|
+
animateArc(sprite: Sprite, toX: number, toY: number, arcHeight: number, durationMs: number, onComplete?: () => void): void;
|
|
2357
|
+
/**
|
|
2358
|
+
* Emits temporary afterimages from a sprite to create a motion trail.
|
|
2359
|
+
*
|
|
2360
|
+
* This is a render-only effect. Trail ghosts are not real sprites and do not
|
|
2361
|
+
* appear in {@link Game.getSprites}, collide, or receive physics.
|
|
2362
|
+
*
|
|
2363
|
+
* @param sprite - The sprite to sample for trail ghosts.
|
|
2364
|
+
* @param options - Optional trail tuning values.
|
|
2365
|
+
* @param onComplete - Optional callback invoked when the emitter stops spawning ghosts.
|
|
2366
|
+
*
|
|
2367
|
+
* @example
|
|
2368
|
+
* ```ts
|
|
2369
|
+
* game.animateTrail(player, { durationMs: 300, spacingMs: 30, fadeMs: 180 });
|
|
2370
|
+
* ```
|
|
2371
|
+
*/
|
|
2372
|
+
animateTrail(sprite: Sprite, options?: TrailOptions, onComplete?: () => void): void;
|
|
2373
|
+
/**
|
|
2374
|
+
* Breaks a sprite into visual pieces that burst outward from its current
|
|
2375
|
+
* rendered appearance.
|
|
2376
|
+
*
|
|
2377
|
+
* This is a render-only effect. The spawned pieces are not real sprites and do
|
|
2378
|
+
* not appear in {@link Game.getSprites}, receive physics, or collide.
|
|
2379
|
+
*
|
|
2380
|
+
* By default, the original sprite is destroyed immediately after the explosion
|
|
2381
|
+
* effect is spawned. Set `destroySprite: false` to hide the sprite during the
|
|
2382
|
+
* effect and restore it when the explosion ends.
|
|
2383
|
+
*
|
|
2384
|
+
* @param sprite - The sprite to explode.
|
|
2385
|
+
* @param options - Optional explosion tuning values.
|
|
2386
|
+
* @param onComplete - Optional callback invoked when the effect finishes.
|
|
2387
|
+
*
|
|
2388
|
+
* @example
|
|
2389
|
+
* ```ts
|
|
2390
|
+
* game.animateExplode(enemy, { rows: 4, cols: 4, durationMs: 650, speed: 320 });
|
|
2391
|
+
* ```
|
|
2392
|
+
*/
|
|
2393
|
+
animateExplode(sprite: Sprite, options?: ExplodeOptions, onComplete?: () => void): void;
|
|
2394
|
+
/**
|
|
2395
|
+
* Spawns visual pieces around a sprite and converges them back into its
|
|
2396
|
+
* current rendered appearance.
|
|
2397
|
+
*
|
|
2398
|
+
* This is a render-only effect. The spawned pieces are not real sprites and
|
|
2399
|
+
* do not appear in {@link Game.getSprites}, receive physics, or collide.
|
|
2400
|
+
*
|
|
2401
|
+
* The original sprite is hidden while the assembly plays and is restored when
|
|
2402
|
+
* the effect finishes.
|
|
2403
|
+
*
|
|
2404
|
+
* @param sprite - The sprite to assemble.
|
|
2405
|
+
* @param options - Optional assembly tuning values.
|
|
2406
|
+
* @param onComplete - Optional callback invoked when the effect finishes.
|
|
2407
|
+
*/
|
|
2408
|
+
animateAssemble(sprite: Sprite, options?: AssembleOptions, onComplete?: () => void): void;
|
|
2409
|
+
/**
|
|
2410
|
+
* Breaks a sprite apart locally inside its own bounds using a directional
|
|
2411
|
+
* dissolve sweep.
|
|
2412
|
+
*
|
|
2413
|
+
* This is a render-only effect. The spawned pieces are not real sprites and
|
|
2414
|
+
* do not appear in {@link Game.getSprites}, receive physics, or collide.
|
|
2415
|
+
*
|
|
2416
|
+
* By default, the original sprite is destroyed immediately after the effect
|
|
2417
|
+
* is spawned. Set `destroySprite: false` to leave the sprite hidden instead.
|
|
2418
|
+
*
|
|
2419
|
+
* @param sprite - The sprite to disintegrate.
|
|
2420
|
+
* @param options - Optional disintegration tuning values.
|
|
2421
|
+
* @param onComplete - Optional callback invoked when the effect finishes.
|
|
2422
|
+
*/
|
|
2423
|
+
animateDisintegrate(sprite: Sprite, options?: DisintegrateOptions, onComplete?: () => void): void;
|
|
2424
|
+
/**
|
|
2425
|
+
* Reconstructs a sprite locally inside its own bounds using a directional
|
|
2426
|
+
* integration sweep.
|
|
2427
|
+
*
|
|
2428
|
+
* This is a render-only effect. The spawned pieces are not real sprites and
|
|
2429
|
+
* do not appear in {@link Game.getSprites}, receive physics, or collide.
|
|
2430
|
+
*
|
|
2431
|
+
* The original sprite is hidden while the integration plays and is restored
|
|
2432
|
+
* when the effect finishes.
|
|
2433
|
+
*
|
|
2434
|
+
* @param sprite - The sprite to integrate.
|
|
2435
|
+
* @param options - Optional integration tuning values.
|
|
2436
|
+
* @param onComplete - Optional callback invoked when the effect finishes.
|
|
2437
|
+
*/
|
|
2438
|
+
animateIntegrate(sprite: Sprite, options?: IntegrateOptions, onComplete?: () => void): void;
|
|
2439
|
+
/**
|
|
2440
|
+
* Reveals or covers a sprite with a directional wipe mask.
|
|
2441
|
+
*
|
|
2442
|
+
* This is a render-only effect that captures the sprite's current appearance
|
|
2443
|
+
* and animates a clipping region over that snapshot.
|
|
2444
|
+
*
|
|
2445
|
+
* For `mode: "reveal"`, the original sprite is hidden during the wipe and is
|
|
2446
|
+
* restored when the effect finishes.
|
|
2447
|
+
*
|
|
2448
|
+
* For `mode: "cover"`, the effect hides the sprite over time. If
|
|
2449
|
+
* `destroySprite` is omitted or `true`, the sprite is destroyed immediately
|
|
2450
|
+
* after the wipe starts and only the wipe snapshot remains visible.
|
|
2451
|
+
*
|
|
2452
|
+
* @param sprite - The sprite to wipe.
|
|
2453
|
+
* @param options - Optional wipe tuning values.
|
|
2454
|
+
* @param onComplete - Optional callback invoked when the effect finishes.
|
|
2455
|
+
*/
|
|
2456
|
+
animateWipe(sprite: Sprite, options?: WipeOptions, onComplete?: () => void): void;
|
|
1073
2457
|
/**
|
|
1074
2458
|
* Schedules a callback to fire after `delayMs` milliseconds, driven by the
|
|
1075
2459
|
* rAF loop (not `setTimeout`). Timers accumulate elapsed time each frame and
|
|
@@ -1116,21 +2500,26 @@ export declare class Game {
|
|
|
1116
2500
|
*/
|
|
1117
2501
|
clearTimer(id: number): void;
|
|
1118
2502
|
/**
|
|
1119
|
-
* Draws text on screen as a **screen-space overlay** this frame.
|
|
2503
|
+
* Draws text on screen as a **simple screen-space overlay** this frame.
|
|
1120
2504
|
*
|
|
1121
2505
|
* **Overlay behavior:** Text is drawn in canvas/screen space — it ignores
|
|
1122
2506
|
* `scrollX` / `scrollY`. Position `(0, 0)` is always the top-left of the canvas.
|
|
1123
|
-
* Use this for HUD elements: score, lives, timer, debug info.
|
|
2507
|
+
* Use this for lightweight HUD elements: score, lives, timer, debug info.
|
|
1124
2508
|
*
|
|
1125
2509
|
* **Per-frame:** `drawText` must be called every frame to keep text visible.
|
|
1126
2510
|
* The text overlay list is cleared after each render. Call this inside `onUpdate`.
|
|
1127
2511
|
*
|
|
1128
2512
|
* **Layer:** Text is always drawn on top of all sprites.
|
|
1129
|
-
* **Font:** Text uses `
|
|
1130
|
-
*
|
|
1131
|
-
*
|
|
1132
|
-
*
|
|
1133
|
-
*
|
|
2513
|
+
* **Font:** Text always uses `monospace`. Use {@link TextSprite} for any
|
|
2514
|
+
* other family.
|
|
2515
|
+
*
|
|
2516
|
+
* Prefer {@link TextSprite} for UI buttons or labels that need persistent
|
|
2517
|
+
* bounds, hit testing, fixed sizes, backgrounds, borders, or text stroke.
|
|
2518
|
+
* `drawText()` is the lightweight overlay API, not the primary UI API.
|
|
2519
|
+
*
|
|
2520
|
+
* For controls that are only a single emoji, prefer {@link EmojiSprite} over
|
|
2521
|
+
* {@link TextSprite}. Emoji-only buttons do not benefit from text padding and
|
|
2522
|
+
* usually fit more naturally in the sprite pipeline.
|
|
1134
2523
|
*
|
|
1135
2524
|
* @param text - The string to render. Supports emoji and Unicode.
|
|
1136
2525
|
* @param x - X position in **screen space** (pixels from canvas left edge).
|
|
@@ -1167,6 +2556,25 @@ export declare class Game {
|
|
|
1167
2556
|
* ```
|
|
1168
2557
|
*/
|
|
1169
2558
|
clearSpriteCache(): void;
|
|
2559
|
+
/**
|
|
2560
|
+
* Registers a web font family that must be loaded before the first frame.
|
|
2561
|
+
*
|
|
2562
|
+
* Call this before {@link Game.start}, typically right after constructing the
|
|
2563
|
+
* game or inside {@link Game.onPreload}. MinimoJS waits for every registered
|
|
2564
|
+
* font via `document.fonts.load(...)` before rendering anything. Host
|
|
2565
|
+
* environments may also pre-register fonts by setting
|
|
2566
|
+
* `globalThis.__MINIMO_WEB_FONT_REQUIREMENTS__` before your game code runs.
|
|
2567
|
+
*
|
|
2568
|
+
* The font itself must still be declared by your page (for example with a
|
|
2569
|
+
* `<link rel="stylesheet">` in `index.html`). MinimoJS only waits for it.
|
|
2570
|
+
*
|
|
2571
|
+
* @example
|
|
2572
|
+
* ```ts
|
|
2573
|
+
* game.requireFont('"Press Start 2P"');
|
|
2574
|
+
* game.requireFont('"Bangers"', { weight: "700" });
|
|
2575
|
+
* ```
|
|
2576
|
+
*/
|
|
2577
|
+
requireFont(family: string, options?: FontRequirementOptions): void;
|
|
1170
2578
|
/**
|
|
1171
2579
|
* Returns a pseudo-random floating-point number in the range `[0, 1)`.
|
|
1172
2580
|
* Delegates to `Math.random()`.
|
|
@@ -1188,9 +2596,12 @@ export declare class Game {
|
|
|
1188
2596
|
* Performs a full engine state reset to enable scene switching.
|
|
1189
2597
|
*
|
|
1190
2598
|
* **Cleared by reset:**
|
|
2599
|
+
* - All background layers
|
|
1191
2600
|
* - All sprites (equivalent to calling {@link Game.destroySprite} on every sprite)
|
|
1192
2601
|
* - All timers (regardless of repeat state)
|
|
1193
2602
|
* - All running animations
|
|
2603
|
+
* - All active explosion effects
|
|
2604
|
+
* - All active trail effects
|
|
1194
2605
|
* - All pending text overlays
|
|
1195
2606
|
* - Scroll position (`scrollX = 0`, `scrollY = 0`)
|
|
1196
2607
|
* - Per-frame input state (pressed keys, pressed pointer)
|
|
@@ -1203,49 +2614,95 @@ export declare class Game {
|
|
|
1203
2614
|
* - Canvas dimensions
|
|
1204
2615
|
* - AudioContext
|
|
1205
2616
|
*
|
|
1206
|
-
* After clearing, `reset()` immediately calls
|
|
1207
|
-
*
|
|
2617
|
+
* After clearing, `reset()` immediately calls the active scene's
|
|
2618
|
+
* `onCreate()` (or legacy {@link Game.onCreate} if no scene is active) so it
|
|
2619
|
+
* can rebuild synchronously.
|
|
2620
|
+
*
|
|
2621
|
+
* The exception is a scene whose {@link IScene.onPreload} registers images
|
|
2622
|
+
* that are not loaded yet. Then the current scene freezes and dims under a progress
|
|
2623
|
+
* ring, nothing is cleared until the images load, and `reset()` returns
|
|
2624
|
+
* before the scene is rebuilt; its `onCreate()` runs once they have loaded.
|
|
2625
|
+
* A `reset()` called while a scene is loading is ignored.
|
|
2626
|
+
*
|
|
2627
|
+
* @param scene - Optional new scene to make active before rebuilding.
|
|
1208
2628
|
*
|
|
1209
2629
|
* @example
|
|
1210
2630
|
* ```ts
|
|
1211
|
-
*
|
|
1212
|
-
*
|
|
1213
|
-
*
|
|
1214
|
-
*
|
|
1215
|
-
*
|
|
1216
|
-
*
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
*
|
|
1220
|
-
* game.addTimer(3000, false, () => game.reset()); // auto-restart
|
|
1221
|
-
* };
|
|
2631
|
+
* class GameOverScene {
|
|
2632
|
+
* onCreate() {
|
|
2633
|
+
* const skull = new EmojiSprite("💀", 400, 300, 96);
|
|
2634
|
+
* game.add(skull);
|
|
2635
|
+
* game.addTimer(3000, false, () => game.reset());
|
|
2636
|
+
* }
|
|
2637
|
+
* }
|
|
2638
|
+
*
|
|
2639
|
+
* game.reset(new GameOverScene());
|
|
1222
2640
|
* ```
|
|
1223
2641
|
*/
|
|
1224
|
-
reset(): void;
|
|
2642
|
+
reset(scene?: IScene): void;
|
|
2643
|
+
/**
|
|
2644
|
+
* Changes to a new scene using a full-screen transition between frozen scene
|
|
2645
|
+
* snapshots.
|
|
2646
|
+
*
|
|
2647
|
+
* `transitionTo()` does not change the behavior of {@link Game.reset}. It
|
|
2648
|
+
* captures the current scene as a snapshot, rebuilds the target scene
|
|
2649
|
+
* immediately, captures the new scene as another snapshot, and then animates
|
|
2650
|
+
* between those two images for the requested duration.
|
|
2651
|
+
*
|
|
2652
|
+
* While the transition is active, gameplay updates are paused.
|
|
2653
|
+
*
|
|
2654
|
+
* If the target scene's {@link IScene.onPreload} registers images that are
|
|
2655
|
+
* not loaded yet, the current scene first freezes and dims under a progress ring
|
|
2656
|
+
* until they load, and the transition plays after that. `transitionTo()`
|
|
2657
|
+
* then returns before the target scene exists; continue in its
|
|
2658
|
+
* `onCreate()` or in `onComplete`. If the player declines to retry failed
|
|
2659
|
+
* images, the game stays on the current scene and `onComplete` is not
|
|
2660
|
+
* called.
|
|
2661
|
+
*
|
|
2662
|
+
* A call made while a transition plays or a scene loads is ignored.
|
|
2663
|
+
*
|
|
2664
|
+
* If the game loop is not running yet, this falls back to
|
|
2665
|
+
* {@link Game.reset}.
|
|
2666
|
+
*
|
|
2667
|
+
* @param scene - Target scene to make active.
|
|
2668
|
+
* @param options - Transition style and optional tuning values.
|
|
2669
|
+
* @param onComplete - Optional callback invoked when the transition finishes.
|
|
2670
|
+
*/
|
|
2671
|
+
transitionTo(scene: IScene, options: SceneTransitionOptions, onComplete?: () => void): void;
|
|
1225
2672
|
/**
|
|
1226
2673
|
* Starts the `requestAnimationFrame` game loop.
|
|
1227
2674
|
* Safe to call multiple times — does nothing if already running.
|
|
1228
|
-
*
|
|
1229
|
-
*
|
|
1230
|
-
*
|
|
1231
|
-
*
|
|
1232
|
-
*
|
|
2675
|
+
* On the first start, MinimoJS runs {@link Game.onPreload} and the active
|
|
2676
|
+
* scene's {@link IScene.onPreload}, loads the images they queued while
|
|
2677
|
+
* showing a thin loading line, and waits for all fonts registered via
|
|
2678
|
+
* {@link Game.requireFont}. After that, the active scene's `onCreate()` is
|
|
2679
|
+
* called before the first frame.
|
|
2680
|
+
*
|
|
2681
|
+
* The loop calls the active scene's `onUpdate(dt)` (or legacy
|
|
2682
|
+
* {@link Game.onUpdate}) once per frame, then renders all sprites and text
|
|
2683
|
+
* overlays. Order per frame:
|
|
1233
2684
|
* 1. Accumulate timer elapsed time; fire ready callbacks.
|
|
1234
2685
|
* 2. Advance animations (linear interpolation).
|
|
1235
|
-
* 3.
|
|
1236
|
-
* 4. Apply
|
|
1237
|
-
* 5.
|
|
1238
|
-
* 6.
|
|
1239
|
-
* 7.
|
|
1240
|
-
* 8.
|
|
2686
|
+
* 3. Advance active piece and wipe effects.
|
|
2687
|
+
* 4. Apply gravity to sprite velocities.
|
|
2688
|
+
* 5. Apply velocities to sprite positions.
|
|
2689
|
+
* 6. Call `onUpdate(dt)`.
|
|
2690
|
+
* 7. Advance active trail effects.
|
|
2691
|
+
* 8. Render sprites/effects (with scroll offset).
|
|
2692
|
+
* 9. Render text overlays (screen space, on top of sprites).
|
|
2693
|
+
* 10. Clear per-frame input state.
|
|
1241
2694
|
*
|
|
1242
2695
|
* @example
|
|
1243
2696
|
* ```ts
|
|
1244
|
-
*
|
|
1245
|
-
*
|
|
2697
|
+
* class DemoScene {
|
|
2698
|
+
* onCreate() {}
|
|
2699
|
+
* onUpdate(dt: number) {}
|
|
2700
|
+
* }
|
|
2701
|
+
*
|
|
2702
|
+
* game.start(new DemoScene());
|
|
1246
2703
|
* ```
|
|
1247
2704
|
*/
|
|
1248
|
-
start(): void;
|
|
2705
|
+
start(scene?: IScene): void;
|
|
1249
2706
|
/**
|
|
1250
2707
|
* Stops the game loop. The canvas retains its last rendered frame.
|
|
1251
2708
|
* Call {@link Game.start} to resume.
|