minimojs 1.0.0-alpha.20 → 1.0.0-alpha.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/minimo.d.ts CHANGED
@@ -205,7 +205,7 @@ export interface IScene {
205
205
  * shared transform, visibility, physics, and animation state required by the
206
206
  * engine.
207
207
  */
208
- export declare abstract class BaseSprite {
208
+ export declare abstract class Sprite {
209
209
  protected constructor(game?: Game | null);
210
210
  /**
211
211
  * Game instance associated with this sprite, if any.
@@ -237,11 +237,11 @@ export declare abstract class BaseSprite {
237
237
  */
238
238
  scale: number;
239
239
  /**
240
- * Base logical width in pixels before applying {@link BaseSprite.scale}.
240
+ * Base logical width in pixels before applying {@link Sprite.scale}.
241
241
  */
242
242
  abstract get width(): number;
243
243
  /**
244
- * Base logical height in pixels before applying {@link BaseSprite.scale}.
244
+ * Base logical height in pixels before applying {@link Sprite.scale}.
245
245
  */
246
246
  abstract get height(): number;
247
247
  /**
@@ -255,16 +255,16 @@ export declare abstract class BaseSprite {
255
255
  /**
256
256
  * Optional logical body width used by physics helpers and collision checks.
257
257
  *
258
- * When `null` (default), MinimoJS uses the sprite's visual {@link BaseSprite.width}.
259
- * When set, this value is scaled by {@link BaseSprite.scale} the same way as the
258
+ * When `null` (default), MinimoJS uses the sprite's visual {@link Sprite.width}.
259
+ * When set, this value is scaled by {@link Sprite.scale} the same way as the
260
260
  * visual sprite size.
261
261
  */
262
262
  bodyWidth: number | null;
263
263
  /**
264
264
  * Optional logical body height used by physics helpers and collision checks.
265
265
  *
266
- * When `null` (default), MinimoJS uses the sprite's visual {@link BaseSprite.height}.
267
- * When set, this value is scaled by {@link BaseSprite.scale} the same way as the
266
+ * When `null` (default), MinimoJS uses the sprite's visual {@link Sprite.height}.
267
+ * When set, this value is scaled by {@link Sprite.scale} the same way as the
268
268
  * visual sprite size.
269
269
  */
270
270
  bodyHeight: number | null;
@@ -283,11 +283,11 @@ export declare abstract class BaseSprite {
283
283
  */
284
284
  bodyOffsetY: number;
285
285
  /**
286
- * Effective collision-body width in pixels after applying {@link BaseSprite.scale}.
286
+ * Effective collision-body width in pixels after applying {@link Sprite.scale}.
287
287
  */
288
288
  get bodyDisplayWidth(): number;
289
289
  /**
290
- * Effective collision-body height in pixels after applying {@link BaseSprite.scale}.
290
+ * Effective collision-body height in pixels after applying {@link Sprite.scale}.
291
291
  */
292
292
  get bodyDisplayHeight(): number;
293
293
  /**
@@ -406,11 +406,11 @@ export declare abstract class BaseSprite {
406
406
  *
407
407
  * @example
408
408
  * ```ts
409
- * const coin = new Sprite("🪙", 300, 200, 32);
409
+ * const coin = new EmojiSprite("🪙", 300, 200, 32);
410
410
  * game.add(coin);
411
411
  * ```
412
412
  */
413
- export declare class Sprite extends BaseSprite {
413
+ export declare class EmojiSprite extends Sprite {
414
414
  /**
415
415
  * The emoji character used to render this sprite.
416
416
  * Must be a single emoji. Change this at runtime to animate between frames.
@@ -422,7 +422,7 @@ export declare class Sprite extends BaseSprite {
422
422
  get height(): number;
423
423
  get displaySize(): number;
424
424
  /**
425
- * Creates a new Sprite with the given emoji, optional position, and base size.
425
+ * Creates a new EmojiSprite with the given emoji, optional position, and base size.
426
426
  * All other properties use their defaults and can be set after construction.
427
427
  *
428
428
  * @param sprite - The emoji character to render. Must be a single emoji.
@@ -434,7 +434,7 @@ export declare class Sprite extends BaseSprite {
434
434
  *
435
435
  * @example
436
436
  * ```ts
437
- * const enemy = new Sprite("👾", 200, 100, 40);
437
+ * const enemy = new EmojiSprite("👾", 200, 100, 40);
438
438
  * game.add(enemy);
439
439
  * ```
440
440
  */
@@ -445,9 +445,9 @@ export declare class Sprite extends BaseSprite {
445
445
  * A renderable sprite backed by a preloaded image asset.
446
446
  *
447
447
  * Width and height are always resolved from the current texture. To resize the
448
- * sprite visually, use {@link BaseSprite.scale}.
448
+ * sprite visually, use {@link Sprite.scale}.
449
449
  */
450
- export declare class ImageSprite extends BaseSprite {
450
+ export declare class ImageSprite extends Sprite {
451
451
  get imageKey(): string;
452
452
  get width(): number;
453
453
  get height(): number;
@@ -455,7 +455,7 @@ export declare class ImageSprite extends BaseSprite {
455
455
  * Creates a new image-backed sprite.
456
456
  *
457
457
  * @param game - Game instance used to resolve the texture key.
458
- * @param imageKey - Preloaded image key previously registered with {@link Game.loadImage}.
458
+ * @param imageKey - Texture key previously registered with {@link Game.loadImage} or {@link Game.createTexture}.
459
459
  * @param x - Initial X position in world space (center), in pixels. Default: `0`.
460
460
  * @param y - Initial Y position in world space (center), in pixels. Default: `0`.
461
461
  */
@@ -463,7 +463,7 @@ export declare class ImageSprite extends BaseSprite {
463
463
  /**
464
464
  * Replaces the current texture with another preloaded image.
465
465
  *
466
- * @param imageKey - New preloaded image key to render.
466
+ * @param imageKey - New texture key to render.
467
467
  */
468
468
  setTexture(imageKey: string): void;
469
469
  getRenderCacheKey(): string;
@@ -477,7 +477,7 @@ export declare class ImageSprite extends BaseSprite {
477
477
  *
478
478
  * Treat `DrawSprite` as a specialized tool, not the default sprite type.
479
479
  * Because it may execute custom Canvas 2D drawing code repeatedly, overusing it
480
- * can affect game performance much more than regular {@link Sprite},
480
+ * can affect game performance much more than regular {@link EmojiSprite},
481
481
  * {@link ImageSprite}, or {@link TextSprite} instances.
482
482
  *
483
483
  * Prefer the other sprite types whenever they can express the same result more
@@ -515,7 +515,7 @@ export declare class ImageSprite extends BaseSprite {
515
515
  * Override {@link DrawSprite.redraw} in a subclass, or assign your own method
516
516
  * on an instance if you prefer an inline style in JavaScript.
517
517
  */
518
- export declare class DrawSprite extends BaseSprite {
518
+ export declare class DrawSprite extends Sprite {
519
519
  /**
520
520
  * When `false` (default), MinimoJS clears this sprite's internal canvas and
521
521
  * calls {@link DrawSprite.redraw} on every render pass.
@@ -562,11 +562,11 @@ export declare class DrawSprite extends BaseSprite {
562
562
  * layout features such as wrapping, fixed button sizes, background/border, or
563
563
  * text stroke.
564
564
  *
565
- * For controls that are only a single emoji, prefer {@link Sprite}. Emoji-only
565
+ * For controls that are only a single emoji, prefer {@link EmojiSprite}. Emoji-only
566
566
  * buttons usually behave better as sprites because they do not need text
567
567
  * padding/layout and their bounds match the rendered emoji more directly.
568
568
  */
569
- export declare class TextSprite extends BaseSprite {
569
+ export declare class TextSprite extends Sprite {
570
570
  anchorX: "left" | "center" | "right";
571
571
  anchorY: "top" | "middle" | "bottom";
572
572
  text: string;
@@ -631,8 +631,9 @@ export type FontRequirementOptions = {
631
631
  * `x` / `y` use **top-left screen-space coordinates**, unlike {@link Sprite},
632
632
  * which uses center-based world space.
633
633
  *
634
- * The image referenced by {@link BackgroundLayer.imageKey} must be registered
635
- * with {@link Game.loadImage} during {@link Game.onPreload}.
634
+ * The texture referenced by {@link BackgroundLayer.imageKey} must be registered
635
+ * with {@link Game.loadImage} during {@link Game.onPreload}, or created
636
+ * dynamically with {@link Game.createTexture}.
636
637
  *
637
638
  * @example
638
639
  * ```ts
@@ -769,21 +770,21 @@ export interface CollisionInfo {
769
770
  * You must import it with standard ESM syntax such as:
770
771
  *
771
772
  * ```ts
772
- * import { Game, Sprite } from "minimojs";
773
+ * import { Game, EmojiSprite } from "minimojs";
773
774
  * ```
774
775
  *
775
776
  * In the browser, use it from a module script:
776
777
  *
777
778
  * ```html
778
779
  * <script type="module">
779
- * import { Game, Sprite } from "./dist/minimo.js";
780
+ * import { Game, EmojiSprite } from "./dist/minimo.js";
780
781
  * </script>
781
782
  * ```
782
783
  *
783
784
  * Or from a CDN:
784
785
  *
785
786
  * ```ts
786
- * import { Game, Sprite } from "https://cdn.jsdelivr.net/npm/minimojs@<version>/dist/minimo.js";
787
+ * import { Game, EmojiSprite } from "https://cdn.jsdelivr.net/npm/minimojs@<version>/dist/minimo.js";
787
788
  * ```
788
789
  *
789
790
  * Do NOT use a classic `<script>` tag without `type="module"`.
@@ -832,12 +833,19 @@ export interface CollisionInfo {
832
833
  * ## Quick Start
833
834
  *
834
835
  * ```ts
835
- * import { Game, Sprite } from "https://cdn.jsdelivr.net/npm/minimojs@<version>/dist/minimo.js";
836
+ * import { Game, ImageSprite } from "https://cdn.jsdelivr.net/npm/minimojs@<version>/dist/minimo.js";
836
837
  *
837
838
  * const game = new Game(720, 1280);
838
839
  *
839
- * const player = new Sprite("🐢", 400, 500, 48);
840
- * game.add(player);
840
+ * game.onPreload = () => {
841
+ * game.loadImage("player", "assets/player.png");
842
+ * };
843
+ *
844
+ * let player: ImageSprite;
845
+ *
846
+ * game.onCreate = () => {
847
+ * player = game.add(new ImageSprite(game, "player", 400, 500));
848
+ * };
841
849
  *
842
850
  * game.onUpdate = (dt) => {
843
851
  * if (game.isKeyDown("ArrowLeft")) player.vx = -200;
@@ -850,6 +858,13 @@ export interface CollisionInfo {
850
858
  * game.start();
851
859
  * ```
852
860
  *
861
+ * Prototyping, and have no art yet? Swap the texture for an emoji and drop the
862
+ * preload entirely — everything else stays the same:
863
+ *
864
+ * ```ts
865
+ * const player = game.add(new EmojiSprite("🐢", 400, 500, 48));
866
+ * ```
867
+ *
853
868
  * ---
854
869
  *
855
870
  * ## Engine Philosophy
@@ -875,13 +890,28 @@ export interface CollisionInfo {
875
890
  *
876
891
  * ---
877
892
  *
878
- * ## Emoji-Only Sprites
879
- *
880
- * Every sprite MUST use a single emoji character as its visual representation.
881
- * PNG, SVG, spritesheet, and image sprites are NOT supported.
882
- * Use Unicode emoji: `"🔥"`, `"⭐"`, `"💣"`, `"🐢"`, `"👾"`, `"🧱"`, etc.
883
- * AI agents can also use text-like emojis (regional indicators, symbols, letters)
884
- * to build fun title art, HUD labels, and expressive in-game text.
893
+ * ## Choosing a Visual Source
894
+ *
895
+ * A sprite's look comes from one of four concrete types, all of which extend the
896
+ * shared abstract {@link Sprite} type. Use `Sprite` as the type in your own
897
+ * signatures; never construct it directly.
898
+ *
899
+ * 1. {@link ImageSprite} the game's own images, and the first option to reach
900
+ * for. Register a texture with {@link Game.loadImage} inside
901
+ * {@link Game.onPreload}, or build one at runtime with
902
+ * {@link Game.createTexture}, then render it with
903
+ * `new ImageSprite(game, key, x, y)`. An image looks identical on every
904
+ * device and belongs to the game.
905
+ * 2. {@link EmojiSprite} — a single Unicode emoji, and the shortest path to a
906
+ * first prototype: `new EmojiSprite("🐢", x, y, size)`. Note that an
907
+ * emoji is drawn with the player's own system emoji font, so the same game
908
+ * looks different across iOS, Android, and Windows, and a glyph the platform
909
+ * lacks renders as an empty box. Prefer an image whenever the look matters.
910
+ * 3. {@link TextSprite} — text, labels, and buttons.
911
+ * 4. {@link DrawSprite} — procedural Canvas 2D drawing, for shapes and gauges
912
+ * the other three cannot express cleanly.
913
+ *
914
+ * Emoji and images mix freely in one game.
885
915
  *
886
916
  * ---
887
917
  *
@@ -970,7 +1000,7 @@ export interface CollisionInfo {
970
1000
  * ```ts
971
1001
  * class SkullScene implements IScene {
972
1002
  * onCreate() {
973
- * const skull = new Sprite("💀", 400, 300, 96);
1003
+ * const skull = new EmojiSprite("💀", 400, 300, 96);
974
1004
  * game.add(skull);
975
1005
  * }
976
1006
  *
@@ -990,7 +1020,7 @@ export interface CollisionInfo {
990
1020
  *
991
1021
  * ---
992
1022
  *
993
- * ## Sprite Lifecycle Ownership
1023
+ * ## EmojiSprite Lifecycle Ownership
994
1024
  *
995
1025
  * The `Game` instance owns all sprites.
996
1026
  * - Create sprites with {@link Game.add}.
@@ -1158,7 +1188,7 @@ export declare class Game {
1158
1188
  * @example
1159
1189
  * ```ts
1160
1190
  * game.onCreate = () => {
1161
- * const player = new Sprite("🐢");
1191
+ * const player = new EmojiSprite("🐢");
1162
1192
  * player.x = 200;
1163
1193
  * player.y = 300;
1164
1194
  * game.add(player);
@@ -1236,7 +1266,7 @@ export declare class Game {
1236
1266
  */
1237
1267
  get pointerY(): number;
1238
1268
  /**
1239
- * Registers a {@link BaseSprite} (or subclass instance) with the engine.
1269
+ * Registers a {@link Sprite} (or subclass instance) with the engine.
1240
1270
  *
1241
1271
  * After calling `add`, the sprite is rendered and, if dynamic
1242
1272
  * (`isStatic = false`), receives built-in velocity/gravity integration every
@@ -1245,21 +1275,21 @@ export declare class Game {
1245
1275
  * **Ownership:** The game instance takes ownership of the sprite from this
1246
1276
  * point forward. It will appear in {@link Game.getSprites} on the same frame.
1247
1277
  *
1248
- * **Subclasses:** Any class that extends {@link BaseSprite} can be passed here.
1278
+ * **Subclasses:** Any class that extends {@link Sprite} can be passed here.
1249
1279
  * The engine stores and processes it as a live sprite; your custom properties
1250
1280
  * are preserved on the instance.
1251
1281
  *
1252
- * @param sprite - A {@link BaseSprite} instance (or subclass) to add.
1282
+ * @param sprite - A {@link Sprite} instance (or subclass) to add.
1253
1283
  * @returns The same sprite instance, for chaining or inline assignment.
1254
1284
  *
1255
1285
  * @example
1256
1286
  * ```ts
1257
1287
  * // Plain sprite
1258
- * const coin = new Sprite("🪙", 300, 200, 32);
1288
+ * const coin = new EmojiSprite("🪙", 300, 200, 32);
1259
1289
  * game.add(coin);
1260
1290
  *
1261
1291
  * // Custom subclass
1262
- * class Enemy extends Sprite {
1292
+ * class Enemy extends EmojiSprite {
1263
1293
  * speed = 150;
1264
1294
  * constructor(x: number, y: number) {
1265
1295
  * super("👾", x, y, 40);
@@ -1268,7 +1298,7 @@ export declare class Game {
1268
1298
  * const enemy = game.add(new Enemy(600, 100));
1269
1299
  * ```
1270
1300
  */
1271
- add<T extends BaseSprite>(sprite: T): T;
1301
+ add<T extends Sprite>(sprite: T): T;
1272
1302
  /**
1273
1303
  * Registers a {@link BackgroundLayer} with the engine.
1274
1304
  *
@@ -1302,7 +1332,7 @@ export declare class Game {
1302
1332
  * game.destroySprite(enemy); // remove enemy from game
1303
1333
  * ```
1304
1334
  */
1305
- destroySprite(sprite: BaseSprite): void;
1335
+ destroySprite(sprite: Sprite): void;
1306
1336
  /**
1307
1337
  * Removes a background layer from the engine.
1308
1338
  *
@@ -1326,7 +1356,7 @@ export declare class Game {
1326
1356
  * const enemies = game.getSprites().filter(s => s.sprite === "👾");
1327
1357
  * ```
1328
1358
  */
1329
- getSprites(): readonly BaseSprite[];
1359
+ getSprites(): readonly Sprite[];
1330
1360
  /**
1331
1361
  * Returns a read-only snapshot of all active background layers.
1332
1362
  *
@@ -1353,12 +1383,39 @@ export declare class Game {
1353
1383
  */
1354
1384
  loadImage(key: string, src: string): void;
1355
1385
  /**
1356
- * Returns a loaded image previously registered with {@link Game.loadImage},
1357
- * or `undefined` if it is not available.
1386
+ * Creates a dynamic texture immediately and registers it under a stable key.
1387
+ *
1388
+ * Unlike {@link Game.loadImage}, this does not require {@link Game.onPreload}.
1389
+ * The `painter` callback receives a fresh offscreen canvas and should draw the
1390
+ * full texture contents into it.
1391
+ *
1392
+ * The resulting texture can be used anywhere a normal image key is accepted,
1393
+ * including {@link ImageSprite}, background layers, and optional modules.
1394
+ *
1395
+ * @param key - Stable texture key used later by sprites and render helpers.
1396
+ * @param width - Texture width in pixels. Minimum `1`.
1397
+ * @param height - Texture height in pixels. Minimum `1`.
1398
+ * @param painter - Function that paints into the offscreen texture canvas.
1399
+ *
1400
+ * @example
1401
+ * ```ts
1402
+ * game.createTexture("checkpoint", 128, 64, (ctx, canvas) => {
1403
+ * ctx.fillStyle = "#101820";
1404
+ * ctx.fillRect(0, 0, canvas.width, canvas.height);
1405
+ * ctx.fillStyle = "#ffd54f";
1406
+ * ctx.fillRect(8, 8, canvas.width - 16, canvas.height - 16);
1407
+ * });
1408
+ * ```
1409
+ */
1410
+ createTexture(key: string, width: number, height: number, painter: (ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement) => void): HTMLCanvasElement;
1411
+ /**
1412
+ * Returns a loaded image or created texture previously registered with
1413
+ * {@link Game.loadImage} or {@link Game.createTexture}, or `undefined` if it
1414
+ * is not available.
1358
1415
  */
1359
- getImage(key: string): HTMLImageElement | undefined;
1416
+ getImage(key: string): HTMLImageElement | HTMLCanvasElement | undefined;
1360
1417
  /**
1361
- * Returns `true` if an image key has completed loading.
1418
+ * Returns `true` if a texture key is available.
1362
1419
  */
1363
1420
  hasImage(key: string): boolean;
1364
1421
  /**
@@ -1382,7 +1439,7 @@ export declare class Game {
1382
1439
  * }
1383
1440
  * ```
1384
1441
  */
1385
- overlap(a: BaseSprite, b: BaseSprite): boolean;
1442
+ overlap(a: Sprite, b: Sprite): boolean;
1386
1443
  /**
1387
1444
  * Tests for any overlap between two groups of sprites.
1388
1445
  * Performs an O(n × m) AABB check for every pair `(a, b)` where `a ∈ listA`
@@ -1393,7 +1450,7 @@ export declare class Game {
1393
1450
  *
1394
1451
  * @param listA - First group of sprites.
1395
1452
  * @param listB - Second group of sprites. May share sprites with `listA`.
1396
- * @returns A `[Sprite, Sprite]` tuple of the first overlapping pair,
1453
+ * @returns A `[EmojiSprite, EmojiSprite]` tuple of the first overlapping pair,
1397
1454
  * or `null` if no pair overlaps.
1398
1455
  *
1399
1456
  * @example
@@ -1406,7 +1463,7 @@ export declare class Game {
1406
1463
  * }
1407
1464
  * ```
1408
1465
  */
1409
- overlapAny(listA: BaseSprite[], listB: BaseSprite[]): [BaseSprite, BaseSprite] | null;
1466
+ overlapAny(listA: Sprite[], listB: Sprite[]): [Sprite, Sprite] | null;
1410
1467
  /**
1411
1468
  * Tests and resolves a basic AABB collision between two sprites.
1412
1469
  *
@@ -1435,7 +1492,7 @@ export declare class Game {
1435
1492
  * }
1436
1493
  * ```
1437
1494
  */
1438
- collide(a: BaseSprite, b: BaseSprite): CollisionInfo | null;
1495
+ collide(a: Sprite, b: Sprite): CollisionInfo | null;
1439
1496
  /**
1440
1497
  * Tests and resolves the first collision found between two groups of sprites.
1441
1498
  *
@@ -1445,7 +1502,7 @@ export declare class Game {
1445
1502
  *
1446
1503
  * @param listA - First group of sprites.
1447
1504
  * @param listB - Second group of sprites.
1448
- * @returns A `[Sprite, Sprite, CollisionInfo]` tuple for the first collision found,
1505
+ * @returns A `[EmojiSprite, EmojiSprite, CollisionInfo]` tuple for the first collision found,
1449
1506
  * or `null` if no pair overlaps.
1450
1507
  * @throws Error if the game's physics helpers are not enabled.
1451
1508
  *
@@ -1457,7 +1514,7 @@ export declare class Game {
1457
1514
  * }
1458
1515
  * ```
1459
1516
  */
1460
- collideAny(listA: BaseSprite[], listB: BaseSprite[]): [BaseSprite, BaseSprite, CollisionInfo] | null;
1517
+ collideAny(listA: Sprite[], listB: Sprite[]): [Sprite, Sprite, CollisionInfo] | null;
1461
1518
  /**
1462
1519
  * Returns `true` while the specified key is held down (every frame it is held).
1463
1520
  * Use this for continuous actions like movement.
@@ -1545,7 +1602,7 @@ export declare class Game {
1545
1602
  * }
1546
1603
  * ```
1547
1604
  */
1548
- isPointerDownOverSprite(sprite: BaseSprite | null | undefined): boolean;
1605
+ isPointerDownOverSprite(sprite: Sprite | null | undefined): boolean;
1549
1606
  /**
1550
1607
  * Returns `true` only on the frame any pointer first pressed over the target
1551
1608
  * sprite. Works with both mouse input and multiple simultaneous touches.
@@ -1569,7 +1626,7 @@ export declare class Game {
1569
1626
  * }
1570
1627
  * ```
1571
1628
  */
1572
- isPointerPressedOverSprite(sprite: BaseSprite | null | undefined): boolean;
1629
+ isPointerPressedOverSprite(sprite: Sprite | null | undefined): boolean;
1573
1630
  /**
1574
1631
  * Returns a read-only snapshot of all currently active pointers.
1575
1632
  *
@@ -1618,7 +1675,7 @@ export declare class Game {
1618
1675
  * }
1619
1676
  * ```
1620
1677
  */
1621
- getPointersOverSprite(sprite: BaseSprite | null | undefined): readonly PointerInfo[];
1678
+ getPointersOverSprite(sprite: Sprite | null | undefined): readonly PointerInfo[];
1622
1679
  /**
1623
1680
  * Returns `true` when the current device appears to be mobile/touch-first.
1624
1681
  *
@@ -1698,7 +1755,7 @@ export declare class Game {
1698
1755
  * game.animateAlpha(coin, 0, 1000, () => game.destroySprite(coin));
1699
1756
  * ```
1700
1757
  */
1701
- animateAlpha(sprite: BaseSprite, to: number, durationMs: number, onComplete?: () => void): void;
1758
+ animateAlpha(sprite: Sprite, to: number, durationMs: number, onComplete?: () => void): void;
1702
1759
  /**
1703
1760
  * Animates a sprite's {@link Sprite.rotation} from its current value to `to`
1704
1761
  * (in degrees) over `durationMs` milliseconds using **linear interpolation**.
@@ -1725,13 +1782,13 @@ export declare class Game {
1725
1782
  * });
1726
1783
  * ```
1727
1784
  */
1728
- animateRotation(sprite: BaseSprite, to: number, durationMs: number, onComplete?: () => void): void;
1785
+ animateRotation(sprite: Sprite, to: number, durationMs: number, onComplete?: () => void): void;
1729
1786
  /**
1730
1787
  * Animates a sprite's visual deformation using non-uniform scaling around a
1731
1788
  * normalized pivot point.
1732
1789
  *
1733
1790
  * This affects rendering only. Physics and collision bounds continue to use
1734
- * {@link Sprite.displaySize} and ignore the deform result.
1791
+ * {@link EmojiSprite.displaySize} and ignore the deform result.
1735
1792
  *
1736
1793
  * `pivotX` / `pivotY` are normalized anchors in the sprite's square display box:
1737
1794
  * - `0` = left/top
@@ -1759,7 +1816,7 @@ export declare class Game {
1759
1816
  * });
1760
1817
  * ```
1761
1818
  */
1762
- animateDeform(sprite: BaseSprite, toScaleX: number, toScaleY: number, pivotX: number, pivotY: number, durationMs: number, onComplete?: () => void): void;
1819
+ animateDeform(sprite: Sprite, toScaleX: number, toScaleY: number, pivotX: number, pivotY: number, durationMs: number, onComplete?: () => void): void;
1763
1820
  /**
1764
1821
  * Convenience helper that squashes a sprite around its horizontal center.
1765
1822
  *
@@ -1771,7 +1828,7 @@ export declare class Game {
1771
1828
  * @param durationMs - Duration of the animation in **milliseconds**.
1772
1829
  * @param onComplete - Optional callback invoked when the animation finishes.
1773
1830
  */
1774
- animateSquash(sprite: BaseSprite, pivotY: number, durationMs: number, onComplete?: () => void): void;
1831
+ animateSquash(sprite: Sprite, pivotY: number, durationMs: number, onComplete?: () => void): void;
1775
1832
  /**
1776
1833
  * Convenience helper that stretches a sprite around its horizontal center.
1777
1834
  *
@@ -1783,7 +1840,7 @@ export declare class Game {
1783
1840
  * @param durationMs - Duration of the animation in **milliseconds**.
1784
1841
  * @param onComplete - Optional callback invoked when the animation finishes.
1785
1842
  */
1786
- animateStretch(sprite: BaseSprite, pivotY: number, durationMs: number, onComplete?: () => void): void;
1843
+ animateStretch(sprite: Sprite, pivotY: number, durationMs: number, onComplete?: () => void): void;
1787
1844
  /**
1788
1845
  * Convenience helper that applies a centered uniform scale pulse and then
1789
1846
  * returns the sprite to its neutral shape.
@@ -1801,7 +1858,7 @@ export declare class Game {
1801
1858
  * game.animatePulse(coin, 1.25, 220);
1802
1859
  * ```
1803
1860
  */
1804
- animatePulse(sprite: BaseSprite, scale: number, durationMs: number, onComplete?: () => void): void;
1861
+ animatePulse(sprite: Sprite, scale: number, durationMs: number, onComplete?: () => void): void;
1805
1862
  /**
1806
1863
  * Applies a decaying screen-space shake to a sprite without changing its
1807
1864
  * logical position.
@@ -1819,7 +1876,7 @@ export declare class Game {
1819
1876
  * game.animateShake(player, 18, 300);
1820
1877
  * ```
1821
1878
  */
1822
- animateShake(sprite: BaseSprite, intensity: number, durationMs: number, onComplete?: () => void): void;
1879
+ animateShake(sprite: Sprite, intensity: number, durationMs: number, onComplete?: () => void): void;
1823
1880
  /**
1824
1881
  * Moves a sprite upward and back down to its starting position along a simple
1825
1882
  * parabolic arc.
@@ -1837,7 +1894,7 @@ export declare class Game {
1837
1894
  * game.animateBounce(ball, 120, 600);
1838
1895
  * ```
1839
1896
  */
1840
- animateBounce(sprite: BaseSprite, height: number, durationMs: number, onComplete?: () => void): void;
1897
+ animateBounce(sprite: Sprite, height: number, durationMs: number, onComplete?: () => void): void;
1841
1898
  /**
1842
1899
  * Moves a sprite upward and back down with a smooth sine-shaped float motion.
1843
1900
  *
@@ -1854,7 +1911,7 @@ export declare class Game {
1854
1911
  * game.animateFloat(balloon, 90, 1200);
1855
1912
  * ```
1856
1913
  */
1857
- animateFloat(sprite: BaseSprite, distance: number, durationMs: number, onComplete?: () => void): void;
1914
+ animateFloat(sprite: Sprite, distance: number, durationMs: number, onComplete?: () => void): void;
1858
1915
  /**
1859
1916
  * Toggles a sprite's rendered opacity on and off a fixed number of times.
1860
1917
  *
@@ -1871,7 +1928,7 @@ export declare class Game {
1871
1928
  * game.animateBlink(player, 4, 700);
1872
1929
  * ```
1873
1930
  */
1874
- animateBlink(sprite: BaseSprite, times: number, durationMs: number, onComplete?: () => void): void;
1931
+ animateBlink(sprite: Sprite, times: number, durationMs: number, onComplete?: () => void): void;
1875
1932
  /**
1876
1933
  * Applies a rapid irregular alpha variation to create a damaged, unstable, or
1877
1934
  * ghost-like flicker.
@@ -1888,7 +1945,7 @@ export declare class Game {
1888
1945
  * game.animateFlicker(ghost, 900);
1889
1946
  * ```
1890
1947
  */
1891
- animateFlicker(sprite: BaseSprite, durationMs: number, onComplete?: () => void): void;
1948
+ animateFlicker(sprite: Sprite, durationMs: number, onComplete?: () => void): void;
1892
1949
  /**
1893
1950
  * Moves a sprite from its current position to a target position along a
1894
1951
  * parabolic arc.
@@ -1908,7 +1965,7 @@ export declare class Game {
1908
1965
  * game.animateArc(coin, player.x, player.y, 80, 420);
1909
1966
  * ```
1910
1967
  */
1911
- animateArc(sprite: BaseSprite, toX: number, toY: number, arcHeight: number, durationMs: number, onComplete?: () => void): void;
1968
+ animateArc(sprite: Sprite, toX: number, toY: number, arcHeight: number, durationMs: number, onComplete?: () => void): void;
1912
1969
  /**
1913
1970
  * Emits temporary afterimages from a sprite to create a motion trail.
1914
1971
  *
@@ -1924,7 +1981,7 @@ export declare class Game {
1924
1981
  * game.animateTrail(player, { durationMs: 300, spacingMs: 30, fadeMs: 180 });
1925
1982
  * ```
1926
1983
  */
1927
- animateTrail(sprite: BaseSprite, options?: TrailOptions, onComplete?: () => void): void;
1984
+ animateTrail(sprite: Sprite, options?: TrailOptions, onComplete?: () => void): void;
1928
1985
  /**
1929
1986
  * Breaks a sprite into visual pieces that burst outward from its current
1930
1987
  * rendered appearance.
@@ -1945,7 +2002,7 @@ export declare class Game {
1945
2002
  * game.animateExplode(enemy, { rows: 4, cols: 4, durationMs: 650, speed: 320 });
1946
2003
  * ```
1947
2004
  */
1948
- animateExplode(sprite: BaseSprite, options?: ExplodeOptions, onComplete?: () => void): void;
2005
+ animateExplode(sprite: Sprite, options?: ExplodeOptions, onComplete?: () => void): void;
1949
2006
  /**
1950
2007
  * Spawns visual pieces around a sprite and converges them back into its
1951
2008
  * current rendered appearance.
@@ -1960,7 +2017,7 @@ export declare class Game {
1960
2017
  * @param options - Optional assembly tuning values.
1961
2018
  * @param onComplete - Optional callback invoked when the effect finishes.
1962
2019
  */
1963
- animateAssemble(sprite: BaseSprite, options?: AssembleOptions, onComplete?: () => void): void;
2020
+ animateAssemble(sprite: Sprite, options?: AssembleOptions, onComplete?: () => void): void;
1964
2021
  /**
1965
2022
  * Breaks a sprite apart locally inside its own bounds using a directional
1966
2023
  * dissolve sweep.
@@ -1975,7 +2032,7 @@ export declare class Game {
1975
2032
  * @param options - Optional disintegration tuning values.
1976
2033
  * @param onComplete - Optional callback invoked when the effect finishes.
1977
2034
  */
1978
- animateDisintegrate(sprite: BaseSprite, options?: DisintegrateOptions, onComplete?: () => void): void;
2035
+ animateDisintegrate(sprite: Sprite, options?: DisintegrateOptions, onComplete?: () => void): void;
1979
2036
  /**
1980
2037
  * Reconstructs a sprite locally inside its own bounds using a directional
1981
2038
  * integration sweep.
@@ -1990,7 +2047,7 @@ export declare class Game {
1990
2047
  * @param options - Optional integration tuning values.
1991
2048
  * @param onComplete - Optional callback invoked when the effect finishes.
1992
2049
  */
1993
- animateIntegrate(sprite: BaseSprite, options?: IntegrateOptions, onComplete?: () => void): void;
2050
+ animateIntegrate(sprite: Sprite, options?: IntegrateOptions, onComplete?: () => void): void;
1994
2051
  /**
1995
2052
  * Reveals or covers a sprite with a directional wipe mask.
1996
2053
  *
@@ -2008,7 +2065,7 @@ export declare class Game {
2008
2065
  * @param options - Optional wipe tuning values.
2009
2066
  * @param onComplete - Optional callback invoked when the effect finishes.
2010
2067
  */
2011
- animateWipe(sprite: BaseSprite, options?: WipeOptions, onComplete?: () => void): void;
2068
+ animateWipe(sprite: Sprite, options?: WipeOptions, onComplete?: () => void): void;
2012
2069
  /**
2013
2070
  * Schedules a callback to fire after `delayMs` milliseconds, driven by the
2014
2071
  * rAF loop (not `setTimeout`). Timers accumulate elapsed time each frame and
@@ -2078,7 +2135,7 @@ export declare class Game {
2078
2135
  * bounds, hit testing, fixed sizes, backgrounds, borders, or text stroke.
2079
2136
  * `drawText()` is the lightweight overlay API, not the primary UI API.
2080
2137
  *
2081
- * For controls that are only a single emoji, prefer {@link Sprite} over
2138
+ * For controls that are only a single emoji, prefer {@link EmojiSprite} over
2082
2139
  * {@link TextSprite}. Emoji-only buttons do not benefit from text padding and
2083
2140
  * usually fit more naturally in the sprite pipeline.
2084
2141
  *
@@ -2185,7 +2242,7 @@ export declare class Game {
2185
2242
  * ```ts
2186
2243
  * class GameOverScene {
2187
2244
  * onCreate() {
2188
- * const skull = new Sprite("💀", 400, 300, 96);
2245
+ * const skull = new EmojiSprite("💀", 400, 300, 96);
2189
2246
  * game.add(skull);
2190
2247
  * game.addTimer(3000, false, () => game.reset());
2191
2248
  * }