minimojs 1.0.0-alpha.3 → 1.0.0-alpha.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +87 -284
  2. package/dist/internal/AnimationSystem.js +345 -0
  3. package/dist/internal/AssetSystem.d.ts +6 -0
  4. package/dist/internal/AssetSystem.js +273 -0
  5. package/dist/internal/BackgroundSystem.d.ts +1 -0
  6. package/dist/internal/BackgroundSystem.js +26 -0
  7. package/dist/internal/CanvasSystem.d.ts +1 -0
  8. package/dist/internal/CanvasSystem.js +51 -0
  9. package/dist/internal/DesignNamingCheck.d.ts +1 -0
  10. package/dist/internal/DesignNamingCheck.js +7 -0
  11. package/dist/internal/ExplosionSystem.d.ts +1 -0
  12. package/dist/internal/ExplosionSystem.js +540 -0
  13. package/dist/internal/InputSystem.d.ts +1 -0
  14. package/dist/internal/InputSystem.js +292 -0
  15. package/dist/internal/LoopSystem.d.ts +1 -0
  16. package/dist/internal/LoopSystem.js +61 -0
  17. package/dist/internal/PhysicsSystem.d.ts +1 -0
  18. package/dist/internal/PhysicsSystem.js +174 -0
  19. package/dist/internal/RenderSystem.d.ts +1 -0
  20. package/dist/internal/RenderSystem.js +1021 -0
  21. package/dist/internal/SoundSystem.d.ts +39 -0
  22. package/dist/internal/SoundSystem.js +292 -0
  23. package/dist/internal/SpriteSystem.d.ts +1 -0
  24. package/dist/internal/SpriteSystem.js +32 -0
  25. package/dist/internal/TextSystem.d.ts +1 -0
  26. package/dist/internal/TextSystem.js +16 -0
  27. package/dist/internal/TimerSystem.d.ts +1 -0
  28. package/dist/internal/TimerSystem.js +43 -0
  29. package/dist/internal/TrailSystem.d.ts +1 -0
  30. package/dist/internal/TrailSystem.js +116 -0
  31. package/dist/internal/TransitionSystem.d.ts +1 -0
  32. package/dist/internal/TransitionSystem.js +74 -0
  33. package/dist/internal/arcade-racer/ArcadeRacerCollisionSystem.d.ts +1 -0
  34. package/dist/internal/arcade-racer/ArcadeRacerCollisionSystem.js +198 -0
  35. package/dist/internal/arcade-racer/ArcadeRacerLaneSystem.d.ts +1 -0
  36. package/dist/internal/arcade-racer/ArcadeRacerLaneSystem.js +120 -0
  37. package/dist/internal/arcade-racer/ArcadeRacerRenderSystem.d.ts +1 -0
  38. package/dist/internal/arcade-racer/ArcadeRacerRenderSystem.js +599 -0
  39. package/dist/internal/arcade-racer/ArcadeRacerRoadSprite.d.ts +1 -0
  40. package/dist/internal/arcade-racer/ArcadeRacerRoadSprite.js +13 -0
  41. package/dist/internal/arcade-racer/ArcadeRacerTrackSystem.d.ts +1 -0
  42. package/dist/internal/arcade-racer/ArcadeRacerTrackSystem.js +447 -0
  43. package/dist/minimo-ambient.d.ts +299 -0
  44. package/dist/minimo-ambient.js +1445 -0
  45. package/dist/minimo-arcaderacer.d.ts +1431 -0
  46. package/dist/minimo-arcaderacer.js +2060 -0
  47. package/dist/minimo-cards.d.ts +359 -0
  48. package/dist/minimo-cards.js +819 -0
  49. package/dist/minimo-format.d.ts +429 -0
  50. package/dist/minimo-format.js +447 -0
  51. package/dist/minimo.d.ts +1815 -209
  52. package/dist/minimo.js +2660 -783
  53. package/package.json +10 -3
  54. package/dist/animations.js +0 -30
  55. package/dist/audio.js +0 -17
  56. package/dist/game.js +0 -1105
  57. package/dist/input.js +0 -185
  58. package/dist/internal-types.js +0 -4
  59. package/dist/physics.js +0 -10
  60. package/dist/render.js +0 -75
  61. package/dist/sprite.js +0 -149
  62. package/dist/timers.js +0 -23
  63. /package/dist/{pointer-info.js → internal/AnimationSystem.d.ts} +0 -0
@@ -0,0 +1,429 @@
1
+ /**
2
+ * @module minimojs/format
3
+ *
4
+ * The file formats MinimoJS reads: asset files, `*.assets.json`, and design
5
+ * files, `*.design.json`.
6
+ *
7
+ * This module uses no DOM, so tools such as an editor or a validating server
8
+ * import the same code a game runs: `import { parseAssetFile, Design } from
9
+ * "minimojs/format"`. Games reach it through `minimo.js`, which re-exports it.
10
+ */
11
+ /**
12
+ * An image declared in an asset file, loaded as
13
+ * `game.loadImage(key, src)` would load it.
14
+ *
15
+ * @example
16
+ * ```json
17
+ * { "key": "player", "type": "image", "src": "assets/player.png" }
18
+ * ```
19
+ */
20
+ export interface ImageAsset {
21
+ /**
22
+ * The key sprites and backgrounds use for this image, as in
23
+ * `new ImageSprite("player")`. Non-empty, with no leading or trailing
24
+ * spaces, and unique in the whole game: no other entry of any asset file,
25
+ * of any type, and no `loadImage` or `createTexture` call may use it.
26
+ */
27
+ key: string;
28
+ /** Always `"image"`. */
29
+ type: "image";
30
+ /** The image's URL or path, as `game.loadImage(key, src)` takes it. Non-empty. */
31
+ src: string;
32
+ }
33
+ /**
34
+ * A sound declared in an asset file, loaded as
35
+ * `game.loadSound(key, src)` would load it, and played with
36
+ * `game.playSound(key)`.
37
+ *
38
+ * @example
39
+ * ```json
40
+ * { "key": "jump", "type": "sound", "src": "assets/jump.mp3" }
41
+ * ```
42
+ */
43
+ export interface SoundAsset {
44
+ /**
45
+ * The key `game.playSound` uses for this sound. Non-empty, with no leading
46
+ * or trailing spaces, and unique in the whole game, images included.
47
+ */
48
+ key: string;
49
+ /** Always `"sound"`. */
50
+ type: "sound";
51
+ /** The audio file's URL or path, as `game.loadSound(key, src)` takes it. Non-empty. */
52
+ src: string;
53
+ }
54
+ /**
55
+ * An entry whose `type` this engine does not support, such as one written for
56
+ * a newer engine. It is kept as written, so a tool that saves the file does
57
+ * not drop it, and `game.loadAssets` warns about it and skips it. Its key
58
+ * still counts toward the game's unique keys.
59
+ */
60
+ export interface UnknownAsset {
61
+ /** The entry's key, unique in the whole game like every other. */
62
+ key: string;
63
+ /** A type this engine does not support. */
64
+ type: string;
65
+ /** The fields of that type, kept unchecked. */
66
+ [field: string]: unknown;
67
+ }
68
+ /**
69
+ * The content of an asset file, `*.assets.json`, which declares assets once,
70
+ * by key, for {@link parseAssetFile} and `game.loadAssets`.
71
+ *
72
+ * A game may have any number of asset files, such as `common.assets.json`
73
+ * and `level3.assets.json`.
74
+ *
75
+ * @example
76
+ * ```json
77
+ * {
78
+ * "format": "minimo-assets",
79
+ * "version": 1,
80
+ * "assets": [
81
+ * { "key": "player", "type": "image", "src": "assets/player.png" },
82
+ * { "key": "bat", "type": "image", "src": "assets/bat.png" },
83
+ * { "key": "jump", "type": "sound", "src": "assets/jump.mp3" }
84
+ * ]
85
+ * }
86
+ * ```
87
+ */
88
+ export interface AssetFile {
89
+ /** Always `"minimo-assets"`. */
90
+ format: "minimo-assets";
91
+ /** The version of the file's shape. Version `1` is the only one so far. */
92
+ version: 1;
93
+ /** The declared assets, in file order. */
94
+ assets: (ImageAsset | SoundAsset | UnknownAsset)[];
95
+ }
96
+ /**
97
+ * Validates the content of an asset file and returns a copy of it.
98
+ *
99
+ * Parsing is strict. It throws an error naming what is wrong for:
100
+ * - a value that is not an asset file object, or an unknown field anywhere;
101
+ * - a `format` other than `"minimo-assets"`;
102
+ * - a `version` newer than this engine reads, or one that is not a positive integer;
103
+ * - an entry without a string `key` and `type`;
104
+ * - an empty key, or one with leading or trailing spaces;
105
+ * - a key repeated in the file, whatever the types of its entries;
106
+ * - an `image` or `sound` entry without a non-empty string `src`.
107
+ *
108
+ * An entry of a type this engine does not support is kept unchanged, without
109
+ * checking its other fields, so nothing is lost when a tool saves the file.
110
+ *
111
+ * @param json - The parsed JSON of a `*.assets.json` file.
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * import common from "./common.assets.json" with { type: "json" };
116
+ * const file = parseAssetFile(common);
117
+ * ```
118
+ */
119
+ export declare function parseAssetFile(json: unknown): AssetFile;
120
+ /**
121
+ * The built-in type of a design object. Each maps to one runtime class:
122
+ * `image` to `ImageSprite`, `emoji` to `EmojiSprite`, `text` to `TextSprite`,
123
+ * and `background` to `BackgroundLayer`.
124
+ */
125
+ export type DesignObjectType = "image" | "emoji" | "text" | "background";
126
+ /**
127
+ * The properties every design object has, whatever its type.
128
+ *
129
+ * Every property of a design object is named as its runtime class names it,
130
+ * so the same names work in code and in files. A property the file omits
131
+ * keeps the runtime object's default.
132
+ */
133
+ export interface DesignObjectBase {
134
+ /**
135
+ * Required. A UUID unique in the file, such as
136
+ * `"6f1c2a0e-3b7d-4c1e-9a52-0d8e4f6b1a27"`. Tools use it to select, undo,
137
+ * and compare objects, and it survives renames. It is the only property
138
+ * with no runtime counterpart.
139
+ */
140
+ id: string;
141
+ /** Optional name, which may repeat. Becomes `Sprite.name`. */
142
+ name?: string;
143
+ /** Tags for grouping and for builders. Becomes `Sprite.tags`. Default: `[]`. */
144
+ tags?: string[];
145
+ /**
146
+ * The game's own values, such as a button's action or an enemy's speed.
147
+ * Always a JSON object, never a bare number or string. Becomes a copy in
148
+ * `Sprite.data`. Default: `{}`.
149
+ */
150
+ data?: Record<string, unknown>;
151
+ }
152
+ /** The properties of every sprite type: `image`, `emoji`, and `text`. */
153
+ export interface DesignSpriteBase extends DesignObjectBase {
154
+ /** Horizontal center in world space, in pixels. Default: `0`. */
155
+ x?: number;
156
+ /** Vertical center in world space, in pixels. Positive is down. Default: `0`. */
157
+ y?: number;
158
+ /** Uniform visual scale. Default: `1`. */
159
+ scale?: number;
160
+ /** Rotation in degrees, clockwise. Default: `0`. */
161
+ rotation?: number;
162
+ /** Mirrors the sprite left to right. Default: `false`. */
163
+ flipX?: boolean;
164
+ /** Mirrors the sprite top to bottom. Default: `false`. */
165
+ flipY?: boolean;
166
+ /** Opacity, from `0` to `1`. Default: `1`. */
167
+ alpha?: number;
168
+ /** Whether the sprite is drawn. Default: `true`. */
169
+ visible?: boolean;
170
+ /** Render order; higher layers draw on top. Default: `0`. */
171
+ layer?: number;
172
+ /** CSS color, used by monochrome glyphs and by text. Default: `"#000000"`, and `"#ffffff"` for `text`. */
173
+ color?: string;
174
+ /** Draws the sprite in screen space, unaffected by scrolling. Default: `false`. */
175
+ ignoreScroll?: boolean;
176
+ /** Whether the engine leaves the sprite where it is, as a static obstacle. Default: `false`. */
177
+ isStatic?: boolean;
178
+ /** Horizontal velocity in pixels per second. Default: `0`. */
179
+ vx?: number;
180
+ /** Vertical velocity in pixels per second. Default: `0`. */
181
+ vy?: number;
182
+ /** Gravity multiplier. Default: `0`, immune to gravity. */
183
+ gravityScale?: number;
184
+ /** Width of the collision body in pixels, before scale; `null` uses the sprite's width. Default: `null`. */
185
+ bodyWidth?: number | null;
186
+ /** Height of the collision body in pixels, before scale; `null` uses the sprite's height. Default: `null`. */
187
+ bodyHeight?: number | null;
188
+ /** Horizontal offset of the body's center from the sprite's center, in pixels, before scale. Default: `0`. */
189
+ bodyOffsetX?: number;
190
+ /** Vertical offset of the body's center from the sprite's center, in pixels, before scale. Default: `0`. */
191
+ bodyOffsetY?: number;
192
+ }
193
+ /**
194
+ * An `ImageSprite` in a design file.
195
+ *
196
+ * @example
197
+ * ```json
198
+ * { "id": "a93e51b4-6c0d-4f2a-8b17-3e5d9c2f0a61", "name": "play", "type": "image", "imageKey": "btn-play", "x": 360, "y": 700 }
199
+ * ```
200
+ */
201
+ export interface DesignImage extends DesignSpriteBase {
202
+ /** Always `"image"`. */
203
+ type: "image";
204
+ /** Required. The key of an image declared in one of the game's asset files. */
205
+ imageKey: string;
206
+ }
207
+ /**
208
+ * An `EmojiSprite` in a design file.
209
+ *
210
+ * @example
211
+ * ```json
212
+ * { "id": "0b9a7c3e-2d4f-4e61-a8c5-7f1e3d2b6a90", "type": "emoji", "sprite": "⭐", "size": 64, "x": 200, "y": 300 }
213
+ * ```
214
+ */
215
+ export interface DesignEmoji extends DesignSpriteBase {
216
+ /** Always `"emoji"`. */
217
+ type: "emoji";
218
+ /** Required. The emoji to draw. */
219
+ sprite: string;
220
+ /** Base size in pixels. Default: `32`. */
221
+ size?: number;
222
+ }
223
+ /**
224
+ * A `TextSprite` in a design file.
225
+ *
226
+ * @example
227
+ * ```json
228
+ * { "id": "5c2e8f1a-9b3d-4a7e-b6c0-1d4f8e2a7c35", "type": "text", "text": "GAME OVER", "fontSize": 64, "x": 360, "y": 400 }
229
+ * ```
230
+ */
231
+ export interface DesignText extends DesignSpriteBase {
232
+ /** Always `"text"`. */
233
+ type: "text";
234
+ /** Required. The text to draw. */
235
+ text: string;
236
+ /** Font size in pixels. Default: `16`. */
237
+ fontSize?: number;
238
+ /** CSS font family. Default: `"monospace"`. */
239
+ fontFamily?: string;
240
+ /** CSS font weight. Default: `"400"`. */
241
+ fontWeight?: string;
242
+ /** Line height as a multiple of the font size. Default: `1.2`. */
243
+ lineHeight?: number;
244
+ /** Which edge of the text `x` names. Default: `"center"`. */
245
+ anchorX?: "left" | "center" | "right";
246
+ /** Which edge of the text `y` names. Default: `"middle"`. */
247
+ anchorY?: "top" | "middle" | "bottom";
248
+ /** Alignment of the lines. Default: `"center"`. */
249
+ textAlign?: "left" | "right" | "center" | "start" | "end";
250
+ /** Width at which lines wrap, in pixels; `0` never wraps. Default: `0`. */
251
+ maxWidth?: number;
252
+ /** Fixed box width in pixels; `0` fits the text. Default: `0`. */
253
+ fixedWidth?: number;
254
+ /** Fixed box height in pixels; `0` fits the text. Default: `0`. */
255
+ fixedHeight?: number;
256
+ /** Horizontal padding inside the box, in pixels. Default: `2`. */
257
+ paddingX?: number;
258
+ /** Vertical padding inside the box, in pixels. Default: `2`. */
259
+ paddingY?: number;
260
+ /** CSS color of the box; `null` draws none. Default: `null`. */
261
+ backgroundColor?: string | null;
262
+ /** CSS color of the box's border; `null` draws none. Default: `null`. */
263
+ borderColor?: string | null;
264
+ /** Width of the box's border in pixels. Default: `0`. */
265
+ borderWidth?: number;
266
+ /** Corner radius of the box in pixels. Default: `0`. */
267
+ cornerRadius?: number;
268
+ /** CSS color of the text's outline; `null` draws none. Default: `null`. */
269
+ strokeColor?: string | null;
270
+ /** Width of the text's outline in pixels. Default: `0`. */
271
+ strokeWidth?: number;
272
+ }
273
+ /**
274
+ * A `BackgroundLayer` in a design file. Unlike sprites, its `x` and `y` are
275
+ * the top-left corner in screen space.
276
+ *
277
+ * @example
278
+ * ```json
279
+ * { "id": "6f1c2a0e-3b7d-4c1e-9a52-0d8e4f6b1a27", "type": "background", "imageKey": "sky" }
280
+ * ```
281
+ */
282
+ export interface DesignBackground extends DesignObjectBase {
283
+ /** Always `"background"`. */
284
+ type: "background";
285
+ /** Required. The key of an image declared in one of the game's asset files. */
286
+ imageKey: string;
287
+ /** Left edge in screen space, in pixels. Default: `0`. */
288
+ x?: number;
289
+ /** Top edge in screen space, in pixels. Default: `0`. */
290
+ y?: number;
291
+ /** Width in pixels; `0` uses the canvas width. Default: `0`. */
292
+ width?: number;
293
+ /** Height in pixels; `0` uses the canvas height. Default: `0`. */
294
+ height?: number;
295
+ /** Opacity, from `0` to `1`. Default: `1`. */
296
+ alpha?: number;
297
+ /** Whether the layer is drawn. Default: `true`. */
298
+ visible?: boolean;
299
+ /** Order among background layers; all of them draw behind sprites. Default: `0`. */
300
+ layer?: number;
301
+ /** How the image fits its rectangle. Default: `"cover"`. */
302
+ fit?: "none" | "stretch" | "contain" | "cover";
303
+ }
304
+ /** Any object of a design file. Its `type` says which. */
305
+ export type DesignObject = DesignImage | DesignEmoji | DesignText | DesignBackground;
306
+ /**
307
+ * The content of a design file, `*.design.json`: a flat list of objects that
308
+ * a game creates with `game.createObject` and `game.createObjectList`, read
309
+ * through {@link Design}.
310
+ *
311
+ * @example
312
+ * ```json
313
+ * {
314
+ * "format": "minimo-design",
315
+ * "version": 1,
316
+ * "objects": [
317
+ * { "id": "6f1c2a0e-3b7d-4c1e-9a52-0d8e4f6b1a27", "type": "background", "imageKey": "sky" },
318
+ * { "id": "a93e51b4-6c0d-4f2a-8b17-3e5d9c2f0a61", "name": "play", "tags": ["button"], "type": "image", "imageKey": "btn-play", "x": 360, "y": 700, "data": { "action": "start" } }
319
+ * ]
320
+ * }
321
+ * ```
322
+ */
323
+ export interface DesignFile {
324
+ /** Always `"minimo-design"`. */
325
+ format: "minimo-design";
326
+ /** The version of the file's shape. Version `1` is the only one so far. */
327
+ version: 1;
328
+ /** The objects, in file order, which is the order they are created and drawn in. */
329
+ objects: DesignObject[];
330
+ }
331
+ /**
332
+ * How one property of a design object is written, for tools that read or edit
333
+ * designs without the TypeScript types, such as a property panel. See
334
+ * {@link designObjectProperties}.
335
+ */
336
+ export interface DesignProperty {
337
+ /** The property's name, in the file and on the runtime object. */
338
+ readonly name: string;
339
+ /**
340
+ * The JSON type of its value. `"string-list"` is a list of strings, as
341
+ * `tags`; `"object"` is a JSON object, as `data`.
342
+ */
343
+ readonly type: "number" | "string" | "boolean" | "string-list" | "object";
344
+ /** Whether `null` is accepted besides values of its type, as for `bodyWidth`. */
345
+ readonly nullable: boolean;
346
+ /** The only strings accepted, as for `fit`; `null` when any value of its type is. */
347
+ readonly values: readonly string[] | null;
348
+ /** Whether every object of its type must have it. A required property has no default. */
349
+ readonly required: boolean;
350
+ /**
351
+ * The runtime object's value when the file omits the property.
352
+ * `undefined` for a required property and for `name`.
353
+ */
354
+ readonly default: unknown;
355
+ }
356
+ /**
357
+ * Every property each type of design object accepts besides `id` and `type`,
358
+ * with its JSON type, whether it is required, and its default.
359
+ *
360
+ * It is the runtime form of {@link DesignImage}, {@link DesignEmoji},
361
+ * {@link DesignText}, and {@link DesignBackground}, which the compiler checks
362
+ * it against, for tools that cannot read TypeScript types, such as an
363
+ * editor's property panel. `new Design(json)` validates objects with it.
364
+ *
365
+ * @example
366
+ * ```ts
367
+ * for (const property of designObjectProperties.image) {
368
+ * console.log(property.name, property.type, property.default);
369
+ * }
370
+ * ```
371
+ */
372
+ export declare const designObjectProperties: Readonly<Record<DesignObjectType, readonly DesignProperty[]>>;
373
+ /**
374
+ * The data of a design file, `*.design.json`, validated: its objects and
375
+ * searches on them. A `Design` needs no game and creates nothing; pass its
376
+ * objects, or the results of its searches, to `game.createObject` or
377
+ * `game.createObjectList`. Data alone also serves markers, such as spawn
378
+ * points, which code reads without creating anything.
379
+ *
380
+ * Obtain the file by JSON import. One `Design` can be created any number of
381
+ * times.
382
+ *
383
+ * @example
384
+ * ```ts
385
+ * import menuJson from "./menu.design.json" with { type: "json" };
386
+ *
387
+ * const menu = new Design(menuJson);
388
+ *
389
+ * class MenuScene {
390
+ * onCreate() {
391
+ * const ui = game.createObjectList(menu.objects);
392
+ * this.play = ui.findByName("play");
393
+ * }
394
+ * }
395
+ * ```
396
+ */
397
+ export declare class Design {
398
+ /**
399
+ * Every object of the design, as object data, in file order.
400
+ */
401
+ readonly objects: readonly DesignObject[];
402
+ /**
403
+ * Validates a design file's content and keeps a copy of it.
404
+ *
405
+ * Parsing is strict. It throws an error naming what is wrong for a value
406
+ * that is not a design, an unknown field, a `format` other than
407
+ * `"minimo-design"`, a `version` newer than this engine reads, an object
408
+ * whose `type` is not one of the built-in types, an `id` that is not a UUID
409
+ * or is used twice, a value of the wrong type, a missing required property,
410
+ * and a `data` that is not a JSON object.
411
+ *
412
+ * @param json - The content of a `*.design.json` file. See {@link DesignFile}.
413
+ */
414
+ constructor(json: unknown);
415
+ /**
416
+ * Returns the first object whose `name` is `name`, in file order.
417
+ * Throws an error naming `name` when there is none.
418
+ */
419
+ findByName(name: string): DesignObject;
420
+ /** Returns every object whose `name` is `name`, in file order; an empty list when there is none. */
421
+ findAllByName(name: string): DesignObject[];
422
+ /**
423
+ * Returns the first object whose `tags` include `tag`, in file order.
424
+ * Throws an error naming `tag` when there is none.
425
+ */
426
+ findByTag(tag: string): DesignObject;
427
+ /** Returns every object whose `tags` include `tag`, in file order; an empty list when there is none. */
428
+ findAllByTag(tag: string): DesignObject[];
429
+ }