like2d 2.6.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +55 -8
  2. package/dist/core/graphics.d.ts +10 -0
  3. package/dist/core/graphics.d.ts.map +1 -1
  4. package/dist/core/graphics.js +18 -0
  5. package/dist/core/like.d.ts +5 -0
  6. package/dist/core/like.d.ts.map +1 -1
  7. package/dist/engine.d.ts +4 -7
  8. package/dist/engine.d.ts.map +1 -1
  9. package/dist/engine.js +46 -50
  10. package/dist/index.d.ts +13 -33
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +15 -20
  13. package/dist/scene.d.ts +10 -0
  14. package/dist/scene.d.ts.map +1 -0
  15. package/dist/scenes/startup.d.ts +18 -0
  16. package/dist/scenes/startup.d.ts.map +1 -0
  17. package/dist/scenes/startup.js +48 -0
  18. package/package.json +9 -17
  19. package/dist/adapters/callback/index.d.ts +0 -23
  20. package/dist/adapters/callback/index.d.ts.map +0 -1
  21. package/dist/adapters/callback/index.js +0 -30
  22. package/dist/adapters/scene/index.d.ts +0 -18
  23. package/dist/adapters/scene/index.d.ts.map +0 -1
  24. package/dist/adapters/scene/index.js +0 -57
  25. package/dist/adapters/scene/scene.d.ts +0 -19
  26. package/dist/adapters/scene/scene.d.ts.map +0 -1
  27. package/dist/adapters/scene/startup-scene.d.ts +0 -18
  28. package/dist/adapters/scene/startup-scene.d.ts.map +0 -1
  29. package/dist/adapters/scene/startup-scene.js +0 -61
  30. package/dist/core/gamepad-button-map.d.ts +0 -5
  31. package/dist/core/gamepad-button-map.d.ts.map +0 -1
  32. package/dist/core/gamepad-button-map.js +0 -56
  33. package/dist/core/gamepad-db.d.ts +0 -49
  34. package/dist/core/gamepad-db.d.ts.map +0 -1
  35. package/dist/core/gamepad-db.js +0 -192
  36. package/dist/core/player-movement.d.ts +0 -16
  37. package/dist/core/player-movement.d.ts.map +0 -1
  38. package/dist/core/player-movement.js +0 -20
  39. /package/dist/{adapters/scene/scene.js → scene.js} +0 -0
package/README.md CHANGED
@@ -43,7 +43,7 @@ pnpm add like2d
43
43
  Ideal for small games, jams, or prototyping.
44
44
 
45
45
  ```typescript
46
- import { createLike } from 'like2d/callback';
46
+ import { createLike } from 'like2d';
47
47
 
48
48
  const like = createLike(document.body);
49
49
 
@@ -72,7 +72,7 @@ await like.start();
72
72
  Ideal for larger projects with menus, levels, and explicit state management.
73
73
 
74
74
  ```typescript
75
- import { SceneRunner, type Scene } from 'like2d/scene';
75
+ import { type Scene, StartupScene } from 'like2d';
76
76
  import type { Like } from 'like2d';
77
77
 
78
78
  class MyScene implements Scene {
@@ -90,18 +90,65 @@ class MyScene implements Scene {
90
90
  }
91
91
  }
92
92
 
93
- const runner = new SceneRunner(document.body);
94
- await runner.start(new MyScene());
93
+ const like = createLike(document.body);
94
+ like.setScene(new StartupScene(new MyScene()));
95
+ await like.start();
96
+ ```
97
+
98
+ ## Module Overview
99
+
100
+ Everything imports from `'like2d'`:
101
+
102
+ ```typescript
103
+ import {
104
+ createLike, // Main entry point
105
+ type Scene, // Scene interface
106
+ StartupScene, // Built-in startup/loading scene
107
+ Vec2, Rect, // Math utilities
108
+ type Like // Core type
109
+ } from 'like2d';
110
+ ```
111
+
112
+ ### Scene Pattern (Class-based)
113
+
114
+ Ideal for larger projects with menus, levels, and explicit state management.
115
+
116
+ ```typescript
117
+ import { type Scene, StartupScene } from 'like2d';
118
+ import type { Like } from 'like2d';
119
+
120
+ class MyScene implements Scene {
121
+ load(like: Like) {
122
+ console.log('Scene loaded!');
123
+ }
124
+
125
+ update(like: Like, dt: number) {
126
+ // update logic
127
+ }
128
+
129
+ draw(like: Like) {
130
+ like.gfx.clear([0.1, 0.1, 0.1, 1]);
131
+ like.gfx.print('white', 'Hello Like2D!', [20, 20]);
132
+ }
133
+ }
134
+
135
+ const like = createLike(document.body);
136
+ like.setScene(new StartupScene(new MyScene()));
137
+ await like.start();
95
138
  ```
96
139
 
97
140
  ## Module Overview
98
141
 
99
- Pick your pattern, import what you need:
142
+ Everything imports from `'like2d'`:
100
143
 
101
144
  ```typescript
102
- import { createLike } from 'like2d/callback'; // Love2D-style
103
- import { SceneRunner, type Scene } from 'like2d/scene'; // Class-based scenes
104
- import { Vec2, Rect, type Like } from 'like2d'; // Core types and math
145
+ import {
146
+ createLike, // Main entry point
147
+ type Scene, // Scene interface
148
+ StartupScene, // Built-in startup/loading scene
149
+ Vec2, Rect, // Math utilities
150
+ type Like // Core type
151
+ } from 'like2d';
105
152
  ```
106
153
 
107
154
  See the [PHILOSOPHY.md](../../docs/PHILOSOPHY.md) for the principles behind the design.
@@ -59,6 +59,11 @@ export declare function setCanvas(s: GraphicsState, canvas?: Canvas | null): voi
59
59
  export declare function clip(s: GraphicsState, rect?: Rect): void;
60
60
  export declare function polygon(s: GraphicsState, mode: DrawMode, color: Color, points: Vector2[], props?: ShapeProps): void;
61
61
  export declare function points(s: GraphicsState, color: Color, pts: Vector2[]): void;
62
+ export declare function push(s: GraphicsState): void;
63
+ export declare function pop(s: GraphicsState): void;
64
+ export declare function translate(s: GraphicsState, offset: Vector2): void;
65
+ export declare function rotate(s: GraphicsState, angle: number): void;
66
+ export declare function scale(s: GraphicsState, factor: number | Vector2): void;
62
67
  type Bind<F> = F extends (s: GraphicsState, ...args: infer A) => infer R ? (...args: A) => R : never;
63
68
  export type BoundGraphics = {
64
69
  [K in keyof typeof graphicsFns]: Bind<(typeof graphicsFns)[K]>;
@@ -77,6 +82,11 @@ declare const graphicsFns: {
77
82
  readonly polygon: typeof polygon;
78
83
  readonly points: typeof points;
79
84
  readonly newImage: typeof newImage;
85
+ readonly push: typeof push;
86
+ readonly pop: typeof pop;
87
+ readonly translate: typeof translate;
88
+ readonly rotate: typeof rotate;
89
+ readonly scale: typeof scale;
80
90
  };
81
91
  export declare function bindGraphics(s: GraphicsState): BoundGraphics;
82
92
  //# sourceMappingURL=graphics.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"graphics.d.ts","sourceRoot":"","sources":["../../src/core/graphics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEnC,KAAK,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAEhC,MAAM,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC;AAC/D,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC;AAExB,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAE9B,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,iBAAiB,CAAC;IAC3B,GAAG,EAAE,wBAAwB,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG;IACnC,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,wBAAwB,CAAC;IACpC,UAAU,EAAE,wBAAwB,CAAC;IACrC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;CAC7B,CAAC;AAEF,qBAAa,WAAW;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,QAAQ,CAAS;gBAEb,IAAI,EAAE,MAAM;IAiBxB,OAAO,IAAI,OAAO;IAIlB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,IAAI,IAAI,IAAI,OAAO,CAElB;IAED,UAAU,IAAI,gBAAgB,GAAG,IAAI;CAGtC;AAmBD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,wBAAwB,GAAG,aAAa,CAMrE;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,GAAE,KAAoB,GAAG,IAAI,CAIzE;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,CAY9G;AAED,wBAAgB,MAAM,CACpB,CAAC,EAAE,aAAa,EAChB,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,MAAM,GAAG,OAAO,EACvB,KAAK,CAAC,EAAE,UAAU,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC9D,IAAI,CAyBN;AAED,wBAAgB,IAAI,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,CAUhG;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,CAoB/G;AAwBD,wBAAgB,SAAS,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI,CAsB3G;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,aAAa,GAAG,OAAO,CAEvD;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAErE;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAUjE;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAExE;AAED,wBAAgB,IAAI,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAUxD;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,CAiBnH;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,IAAI,CAI3E;AAID,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,aAAa,EAAE,GAAG,IAAI,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;AAErG,MAAM,MAAM,aAAa,GAAG;KACzB,CAAC,IAAI,MAAM,OAAO,WAAW,GAAG,IAAI,CAAC,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/D,CAAC;AAEF,QAAA,MAAM,WAAW;;;;;;;;;;;;;;CAIP,CAAC;AAEX,wBAAgB,YAAY,CAAC,CAAC,EAAE,aAAa,GAAG,aAAa,CAM5D"}
1
+ {"version":3,"file":"graphics.d.ts","sourceRoot":"","sources":["../../src/core/graphics.ts"],"names":[],"mappings":"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"}
@@ -253,10 +253,28 @@ export function points(s, color, pts) {
253
253
  ctx.fillStyle = applyColor(color);
254
254
  pts.forEach(([x, y]) => ctx.fillRect(x, y, 1, 1));
255
255
  }
256
+ export function push(s) {
257
+ s.currentCtx.save();
258
+ }
259
+ export function pop(s) {
260
+ s.currentCtx.restore();
261
+ }
262
+ export function translate(s, offset) {
263
+ const [x, y] = offset;
264
+ s.currentCtx.translate(x, y);
265
+ }
266
+ export function rotate(s, angle) {
267
+ s.currentCtx.rotate(angle);
268
+ }
269
+ export function scale(s, factor) {
270
+ const [sx, sy] = typeof factor === 'number' ? [factor, factor] : factor;
271
+ s.currentCtx.scale(sx, sy);
272
+ }
256
273
  const graphicsFns = {
257
274
  clear, rectangle, circle, line, print,
258
275
  draw: drawImage, getCanvasSize, newCanvas, setCanvas,
259
276
  clip, polygon, points, newImage,
277
+ push, pop, translate, rotate, scale,
260
278
  };
261
279
  export function bindGraphics(s) {
262
280
  const bound = {};
@@ -7,6 +7,7 @@ import type { Gamepad } from './gamepad';
7
7
  import type { Vector2 } from './vector2';
8
8
  import type { CanvasMode, PartialCanvasMode } from './canvas-config';
9
9
  import type { BoundGraphics } from './graphics';
10
+ import type { Scene } from '../scene';
10
11
  /**
11
12
  * The Like interface provides access to all core systems and APIs
12
13
  * that are passed to game callbacks (load, update, draw, etc.).
@@ -43,6 +44,10 @@ export interface Like {
43
44
  * @returns The canvas size as a Vector2 [width, height]
44
45
  */
45
46
  getCanvasSize(): Vector2;
47
+ /**
48
+ * Set the active scene. Pass null to revert to global callbacks.
49
+ */
50
+ setScene(scene: Scene | null): void;
46
51
  }
47
52
  export type { Audio, Source, SourceOptions } from './audio';
48
53
  export type { Timer } from './timer';
@@ -1 +1 @@
1
- {"version":3,"file":"like.d.ts","sourceRoot":"","sources":["../../src/core/like.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,WAAW,IAAI;IACnB,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAEtB,qDAAqD;IACrD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAEtB,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAEtB,8BAA8B;IAC9B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAEtB,6BAA6B;IAC7B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,gDAAgD;IAChD,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;IAE5B;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAEvC;;;OAGG;IACH,OAAO,IAAI,UAAU,GAAG,SAAS,CAAC;IAElC;;;OAGG;IACH,aAAa,IAAI,OAAO,CAAC;CAC1B;AAGD,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC5D,YAAY,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9D,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,YAAY,EAAE,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAC7D,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACxE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"like.d.ts","sourceRoot":"","sources":["../../src/core/like.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEtC;;;;;GAKG;AACH,MAAM,WAAW,IAAI;IACnB,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAEtB,qDAAqD;IACrD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAEtB,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAEtB,8BAA8B;IAC9B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAEtB,6BAA6B;IAC7B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,gDAAgD;IAChD,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;IAE5B;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAEvC;;;OAGG;IACH,OAAO,IAAI,UAAU,GAAG,SAAS,CAAC;IAElC;;;OAGG;IACH,aAAa,IAAI,OAAO,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC;CACrC;AAGD,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC5D,YAAY,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9D,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,YAAY,EAAE,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAC7D,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACxE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/engine.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import type { Like2DEvent } from './core/events';
2
2
  import type { PartialCanvasMode } from './core/canvas-config';
3
3
  import type { Like } from './core/like';
4
- export type { CanvasMode, PartialCanvasMode } from './core/canvas-config';
5
4
  export declare class Engine {
6
5
  private canvas;
7
6
  private ctx;
@@ -9,15 +8,13 @@ export declare class Engine {
9
8
  private lastTime;
10
9
  private container;
11
10
  private canvasManager;
12
- private onEvent;
11
+ private handleEvent;
12
+ private currentScene;
13
13
  readonly like: Like;
14
14
  constructor(container: HTMLElement);
15
- private handleFullscreenChange;
15
+ private dispatch;
16
16
  setMode(mode: PartialCanvasMode): void;
17
- private dispatchEvent;
18
- start(onEvent: (event: Like2DEvent) => void): Promise<void>;
19
- stop(): void;
17
+ start(handleEvent: (event: Like2DEvent) => void): Promise<void>;
20
18
  dispose(): void;
21
- getCanvasSize(): [number, number];
22
19
  }
23
20
  //# sourceMappingURL=engine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAa,MAAM,eAAe,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAGxC,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE1E,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,GAAG,CAA2B;IACtC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,OAAO,CAA+C;IAG9D,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;gBAER,SAAS,EAAE,WAAW;IAgElC,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI;IAgBtC,OAAO,CAAC,aAAa;IAMf,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI;IAgCjD,IAAI;IAIJ,OAAO,IAAI,IAAI;IAWf,aAAa,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;CAGlC"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAa,MAAM,eAAe,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAIxC,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,GAAG,CAA2B;IACtC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,WAAW,CAA+C;IAClE,OAAO,CAAC,YAAY,CAAsB;IAE1C,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;gBAER,SAAS,EAAE,WAAW;IAkElC,OAAO,CAAC,QAAQ;IAchB,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI;IAWhC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IA+BrE,OAAO,IAAI,IAAI;CAUhB"}
package/dist/engine.js CHANGED
@@ -44,13 +44,18 @@ export class Engine {
44
44
  writable: true,
45
45
  value: void 0
46
46
  });
47
- Object.defineProperty(this, "onEvent", {
47
+ Object.defineProperty(this, "handleEvent", {
48
+ enumerable: true,
49
+ configurable: true,
50
+ writable: true,
51
+ value: null
52
+ });
53
+ Object.defineProperty(this, "currentScene", {
48
54
  enumerable: true,
49
55
  configurable: true,
50
56
  writable: true,
51
57
  value: null
52
58
  });
53
- // Public Like object with all systems - initialized in constructor
54
59
  Object.defineProperty(this, "like", {
55
60
  enumerable: true,
56
61
  configurable: true,
@@ -67,17 +72,14 @@ export class Engine {
67
72
  this.container = container;
68
73
  this.container.appendChild(this.canvas);
69
74
  this.canvasManager = new CanvasManager(this.canvas, this.container, this.ctx, { pixelResolution: null, fullscreen: false });
70
- // Create graphics state and bind it
71
75
  const gfxState = newState(this.ctx);
72
76
  const gfx = bindGraphics(gfxState);
73
- // Create all subsystems
74
77
  const audio = new Audio();
75
78
  const timer = new Timer();
76
79
  const keyboard = new Keyboard();
77
80
  const mouse = new Mouse((cssX, cssY) => this.canvasManager.transformMousePosition(cssX, cssY));
78
81
  const gamepad = new Gamepad();
79
82
  const input = new Input({ keyboard, mouse, gamepad });
80
- // Create the Like object with all systems
81
83
  this.like = {
82
84
  audio,
83
85
  timer,
@@ -89,81 +91,78 @@ export class Engine {
89
91
  setMode: (m) => this.setMode(m),
90
92
  getMode: () => this.canvasManager.getMode(),
91
93
  getCanvasSize: () => [this.canvas.width, this.canvas.height],
94
+ setScene: (scene) => {
95
+ this.currentScene = scene;
96
+ scene?.load?.(this.like);
97
+ },
92
98
  };
93
- // Set up input event handlers
94
99
  keyboard.onKeyEvent = (scancode, keycode, type) => {
95
- this.dispatchEvent(type === 'keydown' ? 'keypressed' : 'keyreleased', [scancode, keycode]);
100
+ this.dispatch(type === 'keydown' ? 'keypressed' : 'keyreleased', [scancode, keycode]);
96
101
  };
97
102
  mouse.onMouseEvent = (clientX, clientY, button, type) => {
98
103
  const [x, y] = this.canvasManager.transformMousePosition(clientX, clientY);
99
- const b = (button ?? 0) + 1;
100
- this.dispatchEvent(type === 'mousedown' ? 'mousepressed' : 'mousereleased', [x, y, b]);
104
+ this.dispatch(type === 'mousedown' ? 'mousepressed' : 'mousereleased', [x, y, (button ?? 0) + 1]);
101
105
  };
102
106
  gamepad.onButtonEvent = (gpIndex, buttonIndex, buttonName, pressed) => {
103
- this.dispatchEvent(pressed ? 'gamepadpressed' : 'gamepadreleased', [gpIndex, buttonIndex, buttonName]);
107
+ this.dispatch(pressed ? 'gamepadpressed' : 'gamepadreleased', [gpIndex, buttonIndex, buttonName]);
104
108
  };
105
- // Internal listener to forward resize events
106
109
  this.canvasManager.onResize = (size, pixelSize, fullscreen) => {
107
- this.dispatchEvent('resize', [size, pixelSize, fullscreen]);
110
+ this.dispatch('resize', [size, pixelSize, fullscreen]);
108
111
  };
109
- // Listen for fullscreen changes to update mode
110
- document.addEventListener('fullscreenchange', () => this.handleFullscreenChange());
112
+ document.addEventListener('fullscreenchange', () => {
113
+ const mode = this.canvasManager.getMode();
114
+ const isFullscreen = !!document.fullscreenElement;
115
+ if (mode.fullscreen !== isFullscreen) {
116
+ this.canvasManager.setMode({ ...mode, fullscreen: isFullscreen });
117
+ }
118
+ });
111
119
  }
112
- handleFullscreenChange() {
113
- const mode = this.canvasManager.getMode();
114
- const isFullscreen = !!document.fullscreenElement;
115
- if (mode.fullscreen !== isFullscreen) {
116
- this.canvasManager.setMode({ ...mode, fullscreen: isFullscreen });
120
+ dispatch(type, args) {
121
+ if (!this.handleEvent)
122
+ return;
123
+ const event = { type, args, timestamp: performance.now() };
124
+ if (this.currentScene) {
125
+ this.currentScene.handleEvent?.(this.like, event);
126
+ const method = this.currentScene[event.type];
127
+ method?.call(this.currentScene, this.like, ...args);
128
+ }
129
+ else {
130
+ this.handleEvent(event);
117
131
  }
118
132
  }
119
133
  setMode(mode) {
120
134
  const currentMode = this.canvasManager.getMode();
121
135
  const mergedMode = { ...currentMode, ...mode };
122
- const needsFullscreenChange = mode.fullscreen !== undefined && mode.fullscreen !== currentMode.fullscreen;
123
- if (needsFullscreenChange) {
124
- if (mergedMode.fullscreen) {
125
- this.container.requestFullscreen().catch(console.error);
126
- }
127
- else {
128
- document.exitFullscreen();
129
- }
136
+ if (mode.fullscreen !== undefined && mode.fullscreen !== currentMode.fullscreen) {
137
+ mergedMode.fullscreen ? this.container.requestFullscreen().catch(console.error) : document.exitFullscreen();
130
138
  }
131
139
  this.canvasManager.setMode(mode);
132
140
  }
133
- dispatchEvent(type, args) {
134
- if (this.onEvent) {
135
- this.onEvent({ type, args, timestamp: performance.now() });
136
- }
137
- }
138
- async start(onEvent) {
139
- this.onEvent = onEvent;
141
+ async start(handleEvent) {
142
+ this.handleEvent = handleEvent;
140
143
  this.isRunning = true;
141
144
  this.lastTime = performance.now();
142
- // Initialize gamepad
143
145
  await this.like.gamepad.init();
144
146
  const loop = () => {
145
147
  if (!this.isRunning)
146
148
  return;
147
- const currentTime = performance.now();
148
- const dt = (currentTime - this.lastTime) / 1000;
149
- this.lastTime = currentTime;
149
+ const now = performance.now();
150
+ const dt = (now - this.lastTime) / 1000;
151
+ this.lastTime = now;
150
152
  if (!this.like.timer.isSleeping()) {
151
153
  this.like.timer.update(dt);
152
- const inputEvents = this.like.input.update();
153
- inputEvents.pressed.forEach(action => this.dispatchEvent('actionpressed', [action]));
154
- inputEvents.released.forEach(action => this.dispatchEvent('actionreleased', [action]));
155
- this.dispatchEvent('update', [dt]);
154
+ const { pressed, released } = this.like.input.update();
155
+ pressed.forEach(action => this.dispatch('actionpressed', [action]));
156
+ released.forEach(action => this.dispatch('actionreleased', [action]));
157
+ this.dispatch('update', [dt]);
156
158
  }
157
- this.dispatchEvent('draw', []);
159
+ this.dispatch('draw', []);
158
160
  this.canvasManager.present();
159
161
  requestAnimationFrame(loop);
160
162
  };
161
- this.dispatchEvent('load', []);
163
+ this.dispatch('load', []);
162
164
  requestAnimationFrame(loop);
163
165
  }
164
- stop() {
165
- this.isRunning = false;
166
- }
167
166
  dispose() {
168
167
  this.isRunning = false;
169
168
  this.like.keyboard.dispose();
@@ -174,7 +173,4 @@ export class Engine {
174
173
  this.container.removeChild(this.canvas);
175
174
  }
176
175
  }
177
- getCanvasSize() {
178
- return [this.canvas.width, this.canvas.height];
179
- }
180
176
  }
package/dist/index.d.ts CHANGED
@@ -1,45 +1,25 @@
1
- /**
2
- * Main API interface containing all core systems.
3
- * Passed as first argument to all callbacks.
4
- */
1
+ import type { EventMap, EventType } from './core/events';
2
+ import type { Like } from './core/like';
5
3
  export type { Like } from './core/like';
6
- /**
7
- * 2D vector as a tuple: [x, y]
8
- */
9
4
  export type { Vector2 } from './core/vector2';
10
- /**
11
- * 2D vector math and utility functions
12
- */
13
5
  export { Vec2 } from './core/vector2';
14
- /**
15
- * Rectangle math and utility functions.
16
- * Rects are represented as [x, y, width, height] tuples.
17
- */
18
6
  export { Rect } from './core/rect';
19
- /**
20
- * Common event structure for all engine events.
21
- */
22
7
  export type { Like2DEvent, EventType, EventMap } from './core/events';
23
8
  export type { CanvasMode, PartialCanvasMode } from './core/canvas-config';
24
- /**
25
- * Graphics types for drawing operations.
26
- */
27
9
  export type { Color, Quad, ShapeProps, DrawProps, PrintProps } from './core/graphics';
28
- /**
29
- * Handle to an image asset that may be loading in the background.
30
- */
31
10
  export { ImageHandle } from './core/graphics';
32
- /**
33
- * Audio source types for sound playback.
34
- */
35
11
  export type { Source, SourceOptions } from './core/audio';
36
- /**
37
- * Core Scene interface for class-based game architecture.
38
- */
39
- export type { Scene } from './adapters/scene/scene';
40
- /**
41
- * Gamepad utility functions and types.
42
- */
12
+ export type { Scene } from './scene';
13
+ export { StartupScene } from './scenes/startup';
43
14
  export { getGPName, GP } from './core/gamepad';
44
15
  export type { StickPosition } from './core/gamepad';
16
+ type Callback<K extends EventType> = (...args: EventMap[K]) => void;
17
+ type Callbacks = {
18
+ [K in EventType]?: Callback<K>;
19
+ };
20
+ export type LikeWithCallbacks = Like & Callbacks & {
21
+ start(): Promise<void>;
22
+ dispose(): void;
23
+ };
24
+ export declare function createLike(container: HTMLElement): LikeWithCallbacks;
45
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,YAAY,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC;;GAEG;AACH,YAAY,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;GAEG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtC;;;GAGG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC;;GAEG;AACH,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACtE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE1E;;GAEG;AACH,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEtF;;GAEG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C;;GAEG;AACH,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE1D;;GAEG;AACH,YAAY,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAEpD;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,QAAQ,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC,YAAY,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACtE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1D,YAAY,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,KAAK,QAAQ,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,GAAG,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAEpE,KAAK,SAAS,GAAG;KACd,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,SAAS,GAAG;IACjD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,IAAI,IAAI,CAAC;CACjB,CAAC;AAEF,wBAAgB,UAAU,CAAC,SAAS,EAAE,WAAW,GAAG,iBAAiB,CAapE"}
package/dist/index.js CHANGED
@@ -1,24 +1,19 @@
1
- // Like2D - Multi-adapter game framework
2
- // Use specific adapters for different patterns:
3
- // - import { createLike, graphics } from 'like2d/callback' (Love2D-style callbacks)
4
- // - import { SceneRunner, Scene } from 'like2d/scene' (Class-based scenes)
5
- /**
6
- * 2D vector math and utility functions
7
- */
1
+ import { Engine } from './engine';
8
2
  export { Vec2 } from './core/vector2';
9
- /**
10
- * Rectangle math and utility functions.
11
- * Rects are represented as [x, y, width, height] tuples.
12
- */
13
3
  export { Rect } from './core/rect';
14
- /**
15
- * Handle to an image asset that may be loading in the background.
16
- */
17
4
  export { ImageHandle } from './core/graphics';
18
- /**
19
- * Gamepad utility functions and types.
20
- */
5
+ export { StartupScene } from './scenes/startup';
21
6
  export { getGPName, GP } from './core/gamepad';
22
- // Note: For actual usage, import from specific adapters:
23
- // import { createLike, graphics } from 'like2d/callback';
24
- // import { SceneRunner, Scene } from 'like2d/scene';
7
+ export function createLike(container) {
8
+ const engine = new Engine(container);
9
+ const callbacks = {};
10
+ const handleEvent = (event) => {
11
+ const cb = callbacks[event.type];
12
+ if (cb)
13
+ cb(...event.args);
14
+ };
15
+ return Object.assign(engine.like, callbacks, {
16
+ start: () => engine.start(handleEvent),
17
+ dispose: () => engine.dispose(),
18
+ });
19
+ }
@@ -0,0 +1,10 @@
1
+ import type { Like2DEvent, EventMap, EventType } from './core/events';
2
+ import type { Like } from './core/like';
3
+ type EventHandler<K extends EventType> = (like: Like, ...args: EventMap[K]) => void;
4
+ export type Scene = {
5
+ [K in EventType]?: EventHandler<K>;
6
+ } & {
7
+ handleEvent?(like: Like, event: Like2DEvent): void;
8
+ };
9
+ export {};
10
+ //# sourceMappingURL=scene.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC,KAAK,YAAY,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAEpF,MAAM,MAAM,KAAK,GAAG;KACjB,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;CACnC,GAAG;IACF,WAAW,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;CACpD,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { Scene, Like } from '../index';
2
+ /**
3
+ * A simple startup scene that waits for a mouse click before advancing.
4
+ *
5
+ * This exists to work around browser autoplay restrictions - browsers require
6
+ * user interaction (like a click) before allowing audio playback. Show this
7
+ * scene first, then transition to your game scene on click.
8
+ */
9
+ export declare class StartupScene implements Scene {
10
+ private next;
11
+ private onDraw?;
12
+ private logo;
13
+ constructor(next: Scene, onDraw?: ((like: Like) => void) | undefined);
14
+ load(like: Like): void;
15
+ draw(like: Like): void;
16
+ mousepressed(like: Like): void;
17
+ }
18
+ //# sourceMappingURL=startup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startup.d.ts","sourceRoot":"","sources":["../../src/scenes/startup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAM5C;;;;;;GAMG;AACH,qBAAa,YAAa,YAAW,KAAK;IAItC,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM,CAAC;IAJjB,OAAO,CAAC,IAAI,CAAe;gBAGjB,IAAI,EAAE,KAAK,EACX,MAAM,CAAC,GAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,aAAA;IAGvC,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAItB,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAWtB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;CAG/B"}
@@ -0,0 +1,48 @@
1
+ import { Vec2 } from '../core/vector2';
2
+ const LOGO = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCEtLSBDcmVhdGVkIHdpdGggSW5rc2NhcGUgKGh0dHA6Ly93d3cuaW5rc2NhcGUub3JnLykgLS0+Cjxzdmcgd2lkdGg9IjMwMG1tIiBoZWlnaHQ9IjEwNW1tIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAzMDAgMTA1IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogPHJlY3QgeD0iMTAiIHk9IjExLjIzIiB3aWR0aD0iMjgwIiBoZWlnaHQ9IjgzLjU0NCIgZmlsbD0iI2U0ODA4MCIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjIiLz4KIDxnIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+CiAgPHJlY3QgeD0iOTcuNDg0IiB5PSIxMS4yMyIgd2lkdGg9IjUyLjUxNiIgaGVpZ2h0PSI0Ni4yMzciLz4KICA8cmVjdCB4PSIxNTAiIHk9IjExLjIzIiB3aWR0aD0iMzUuMDExIiBoZWlnaHQ9IjQ2LjIzNyIvPgogIDxyZWN0IHg9IjE4NS4wMSIgeT0iMTEuMjMiIHdpZHRoPSI1Mi41MTYiIGhlaWdodD0iNDYuMjM3Ii8+CiAgPHJlY3QgeD0iMjM3LjUzIiB5PSIxMS4yMyIgd2lkdGg9IjUyLjUxNiIgaGVpZ2h0PSI0Ni4yMzciLz4KIDwvZz4KIDxnPgogIDxyZWN0IHg9IjEzMi40OSIgeT0iMTEuMjMiIHdpZHRoPSIxNy41MDUiIGhlaWdodD0iMjcuNDYxIi8+CiAgPHJlY3QgeD0iMTUwIiB5PSIyOS4zMDIiIHdpZHRoPSI4Ljc1MjciIGhlaWdodD0iMTguNzc2Ii8+CiAgPHJlY3QgeD0iMTc2LjI2IiB5PSIyOS4zMDIiIHdpZHRoPSI4Ljc1MjciIGhlaWdodD0iMTguNzc2Ii8+CiA8L2c+CiA8cmVjdCB4PSIxNTAiIHk9IjExLjIzIiB3aWR0aD0iMTcuNTA1IiBoZWlnaHQ9IjguNjg0NSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CiA8cmVjdCB4PSIxNjcuNTEiIHk9IjExLjIzIiB3aWR0aD0iMTcuNTA1IiBoZWlnaHQ9IjguNjg0NSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CiA8Zz4KICA8cGF0aCBkPSJtMjM3LjUzIDM4LjY5MS0xNy41MDUtOS4zODgyIDE3LjUwNS0xOC4wNzN6Ii8+CiAgPHJlY3QgeD0iMjAyLjg4IiB5PSI0OC4wNzkiIHdpZHRoPSIxNi43NzIiIGhlaWdodD0iOS4zODgyIi8+CiAgPHJlY3QgeD0iMjcyLjU0IiB5PSIyMC4yNjYiIHdpZHRoPSIxNi43NzIiIGhlaWdodD0iOS4zODgyIi8+CiAgPHJlY3QgeD0iMjcyLjU0IiB5PSIzOC42OTEiIHdpZHRoPSIxNi43NzIiIGhlaWdodD0iOS4zODgyIi8+CiAgPHBhdGggZD0ibTIwMi41MiAyOS4zMDIgMC4zNjY4NS0xOC4wNzNoMTcuMTM5eiIvPgogPC9nPgogPHBhdGggZD0ibTY0LjA3OCAxLjAwNDItMzMuMzc1IDMzLjM3NS0wLjAxNzQzIDAuMDE3NGEyMy42MTIgMjMuNjEyIDAgMCAwIDAgMzMuMzkyIDIzLjYxMiAyMy42MTIgMCAwIDAgMzAuMDEyIDIuODAyMiAyMy42MTIgMjMuNjEyIDAgMCAxIDdlLTMgMC41NzAzNCAyMy42MTIgMjMuNjEyIDAgMCAxLTIzLjYxMiAyMy42MTJoNTMuOTdhMjMuNjEyIDIzLjYxMiAwIDAgMS0yMy42MTEtMjMuNjEyIDIzLjYxMiAyMy42MTIgMCAwIDEgN2UtMyAtMC41NzAzNCAyMy42MTIgMjMuNjEyIDAgMCAwIDMwLjAxMi0yLjgwMjkgMjMuNjEyIDIzLjYxMiAwIDAgMC02Ljg4ZS00IC0zMy4zOTJ6IiBmaWxsPSIjODBjM2U0IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KIDxnIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuNSI+CiAgPGNpcmNsZSB0cmFuc2Zvcm09InJvdGF0ZSgxMzUpIiBjeD0iLTIwLjk4OCIgY3k9Ii05My4yNDMiIHI9IjIzLjYxMiIvPgogIDxjaXJjbGUgdHJhbnNmb3JtPSJyb3RhdGUoMTM1KSIgY3g9IjIuNjIzOCIgY3k9Ii02OS42MzIiIHI9IjIzLjYxMiIvPgogIDxjaXJjbGUgY3g9IjkxLjA2MiIgY3k9IjcxLjE2MSIgcj0iMjMuNjEyIi8+CiAgPGNpcmNsZSBjeD0iMzcuMDkzIiBjeT0iNzEuMTYxIiByPSIyMy42MTIiLz4KIDwvZz4KPC9zdmc+Cg==';
3
+ /**
4
+ * A simple startup scene that waits for a mouse click before advancing.
5
+ *
6
+ * This exists to work around browser autoplay restrictions - browsers require
7
+ * user interaction (like a click) before allowing audio playback. Show this
8
+ * scene first, then transition to your game scene on click.
9
+ */
10
+ export class StartupScene {
11
+ constructor(next, onDraw) {
12
+ Object.defineProperty(this, "next", {
13
+ enumerable: true,
14
+ configurable: true,
15
+ writable: true,
16
+ value: next
17
+ });
18
+ Object.defineProperty(this, "onDraw", {
19
+ enumerable: true,
20
+ configurable: true,
21
+ writable: true,
22
+ value: onDraw
23
+ });
24
+ Object.defineProperty(this, "logo", {
25
+ enumerable: true,
26
+ configurable: true,
27
+ writable: true,
28
+ value: void 0
29
+ });
30
+ }
31
+ load(like) {
32
+ this.logo = like.gfx.newImage(LOGO);
33
+ }
34
+ draw(like) {
35
+ if (this.onDraw) {
36
+ this.onDraw(like);
37
+ }
38
+ else if (this.logo.isReady()) {
39
+ like.gfx.clear([0.05, 0.05, 0.08, 1]);
40
+ const winSize = like.gfx.getCanvasSize();
41
+ const scale = (winSize[0] * 0.5) / this.logo.size[0];
42
+ like.gfx.draw(this.logo, Vec2.div(winSize, 2), { scale, origin: Vec2.div(this.logo.size, 2) });
43
+ }
44
+ }
45
+ mousepressed(like) {
46
+ like.setScene(this.next);
47
+ }
48
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "like2d",
3
- "version": "2.6.0",
3
+ "version": "2.7.0",
4
4
  "description": "A web-native game framework inspired by Love2D",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -10,14 +10,6 @@
10
10
  ".": {
11
11
  "import": "./dist/index.js",
12
12
  "types": "./dist/index.d.ts"
13
- },
14
- "./callback": {
15
- "import": "./dist/adapters/callback/index.js",
16
- "types": "./dist/adapters/callback/index.d.ts"
17
- },
18
- "./scene": {
19
- "import": "./dist/adapters/scene/index.js",
20
- "types": "./dist/adapters/scene/index.d.ts"
21
13
  }
22
14
  },
23
15
  "files": [
@@ -26,6 +18,13 @@
26
18
  "README.md",
27
19
  "LICENSE"
28
20
  ],
21
+ "scripts": {
22
+ "build": "tsc && cp src/gamecontrollerdb.txt dist/",
23
+ "typecheck": "tsc --noEmit",
24
+ "lint": "echo 'No linting configured'",
25
+ "clean": "rm -rf dist",
26
+ "test": "vitest run"
27
+ },
29
28
  "keywords": [
30
29
  "game",
31
30
  "framework",
@@ -39,12 +38,5 @@
39
38
  "license": "MIT",
40
39
  "devDependencies": {
41
40
  "typescript": "^5.9.3"
42
- },
43
- "scripts": {
44
- "build": "tsc && cp src/gamecontrollerdb.txt dist/",
45
- "typecheck": "tsc --noEmit",
46
- "lint": "echo 'No linting configured'",
47
- "clean": "rm -rf dist",
48
- "test": "vitest run"
49
41
  }
50
- }
42
+ }