like2d 2.4.0 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,12 +8,21 @@ A web-native 2D game framework inspired by [LÖVE](https://love2d.org/), built f
8
8
 
9
9
  ## What it is
10
10
 
11
- Like2D is a thin, performant wrapper around the browser's Canvas and Web Audio APIs. It provides:
12
- - **Stateless Graphics:** No more `ctx.save()` and `ctx.restore()` for colors and transforms.
13
- - **Fire-and-forget Assets:** Synchronous handles for images and audio that load in the background.
14
- - **Unified Input:** Normalized keyboard, mouse, and gamepad support with action mapping.
15
- - **Scaling Modes:** Built-in support for "pixel" resolution with pixel-perfect scaling.
16
- - **Flexible Patterns:** Use Love2D-style global callbacks or class-based scenes.
11
+ LIKE is a **curated toolkit** around browser APIs.
12
+
13
+ It does less, because it **does the right thing**. And when that's not the right thing for you, we hand you the wrench.
14
+
15
+ - **Stateless Graphics:** Forget to reset native Canvas state (like LineCap) between calls and things break mysteriously. We make drawing explicit: what you see is what you set.
16
+
17
+ - **Fire-and-forget Assets:** Async asset loading directly on realtime web games is annoying. We let you pretend it's instant and synchronous.
18
+
19
+ - **Physical Joypad:** Our gamepad module auto-maps to physical buttons like "bottom" and "top". Because A isn't always in the same spot.
20
+
21
+ - **Actions System:** Of course you can use device input callbacks just like love2d -- but you can also map inputs to actions and get callbacks on that.
22
+
23
+ - **Scaling Modes:** Pixel art games need pixel-perfect scaling. So we do that: integer nearest -> linear. Or not; turn off pixelart mode to have a canvas that stays at native resolution.
24
+
25
+ - **Sane Architecture:** Everything is built around a centralized event handler for browser-native events. We won't reinvent the wheel.
17
26
 
18
27
  ## Installation
19
28
 
@@ -25,31 +34,37 @@ pnpm add like2d
25
34
 
26
35
  ## Quick Start
27
36
 
37
+ [Like2D Starter Template](https://github.com/44100hertz/Like2D-starter)
38
+
39
+ ## Usage Examples
40
+
28
41
  ### Callback Pattern (Love2D-style)
29
42
 
30
43
  Ideal for small games, jams, or prototyping.
31
44
 
32
45
  ```typescript
33
- import { love, graphics, input } from 'like2d/callback';
46
+ import { createLike } from 'like2d/callback';
34
47
 
35
- love.load = () => {
36
- love.setMode({ pixelResolution: [800, 600] });
37
- input.map('jump', ['Space', 'ButtonBottom']);
48
+ const like = createLike(document.body);
49
+
50
+ like.load = () => {
51
+ like.setMode({ pixelResolution: [800, 600] });
52
+ like.input.map('jump', ['Space', 'ButtonBottom']);
38
53
  };
39
54
 
40
- love.update = (dt) => {
41
- if (input.justPressed('jump')) {
55
+ like.update = (dt) => {
56
+ if (like.input.justPressed('jump')) {
42
57
  console.log('Jump!');
43
58
  }
44
59
  };
45
60
 
46
- love.draw = () => {
47
- graphics.clear([0.1, 0.1, 0.1, 1]);
48
- graphics.circle('fill', 'dodgerblue', [400, 300], 50);
49
- graphics.print('white', 'Hello Like2D!', [20, 20]);
61
+ like.draw = () => {
62
+ like.gfx.clear([0.1, 0.1, 0.1, 1]);
63
+ like.gfx.circle('fill', 'dodgerblue', [400, 300], 50);
64
+ like.gfx.print('white', 'Hello Like2D!', [20, 20]);
50
65
  };
51
66
 
52
- love.init(document.body);
67
+ await like.start();
53
68
  ```
54
69
 
55
70
  ### Scene Pattern (Class-based)
@@ -57,19 +72,21 @@ love.init(document.body);
57
72
  Ideal for larger projects with menus, levels, and explicit state management.
58
73
 
59
74
  ```typescript
60
- import { SceneRunner, type Scene, Vec2 } from 'like2d/scene';
75
+ import { SceneRunner, type Scene } from 'like2d/scene';
76
+ import type { Like } from 'like2d';
61
77
 
62
78
  class MyScene implements Scene {
63
- load() {
79
+ load(like: Like) {
64
80
  console.log('Scene loaded!');
65
81
  }
66
82
 
67
- update(dt: number) {
83
+ update(like: Like, dt: number) {
68
84
  // update logic
69
85
  }
70
86
 
71
- draw(canvas: HTMLCanvasElement) {
72
- // draw logic
87
+ draw(like: Like) {
88
+ like.gfx.clear([0.1, 0.1, 0.1, 1]);
89
+ like.gfx.print('white', 'Hello Like2D!', [20, 20]);
73
90
  }
74
91
  }
75
92
 
@@ -77,21 +94,17 @@ const runner = new SceneRunner(document.body);
77
94
  await runner.start(new MyScene());
78
95
  ```
79
96
 
80
- ## API Overview
81
-
82
- Like2D exports pure library functions for math and geometry that work with native arrays.
97
+ ## Module Overview
83
98
 
84
- - **Vec2:** Vector operations using `[number, number]` tuples.
85
- - **Rect:** Rectangle operations using `[x, y, w, h]` tuples.
86
- - **Graphics:** Stateless drawing commands.
87
- - **Audio:** Simple source/playback management.
88
- - **Input:** Action-based input mapping.
99
+ Pick your pattern, import what you need:
89
100
 
90
- See the [PHILOSOPHY.md](./docs/PHILOSOPHY.md) for the principles behind the design.
91
-
92
- ## Quick Start Template
101
+ ```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
105
+ ```
93
106
 
94
- Get started quickly with the [Like2D Starter](https://github.com/44100hertz/Like2D-starter) template!
107
+ See the [PHILOSOPHY.md](../../docs/PHILOSOPHY.md) for the principles behind the design.
95
108
 
96
109
  ## License
97
110
 
@@ -1,44 +1,23 @@
1
- import { Graphics } from '../../core/graphics';
2
- import { Audio } from '../../core/audio';
3
- import { Input } from '../../core/input';
4
- import { Timer } from '../../core/timer';
5
- import { Keyboard } from '../../core/keyboard';
6
- import { Mouse } from '../../core/mouse';
7
- import { Gamepad } from '../../core/gamepad';
8
- import type { CanvasMode, PartialCanvasMode } from '../../core/canvas-config';
9
1
  import type { Like2DEvent } from '../../core/events';
10
- import type { Vector2 } from '../../core/vector2';
11
- export { ImageHandle } from '../../core/graphics';
12
- export { getGPName, GP } from '../../core/gamepad';
13
- export { Vec2 } from '../../core/vector2';
14
- export { Rect } from '../../core/rect';
15
- export { calcFixedScale } from '../../core/canvas-config';
16
- export type { CanvasMode, PartialCanvasMode } from '../../core/canvas-config';
17
- export declare let graphics: Graphics;
18
- export declare const audio: Audio;
19
- export declare const timer: Timer;
20
- export declare let keyboard: Keyboard;
21
- export declare let mouse: Mouse;
22
- export declare let gamepad: Gamepad;
23
- export declare let input: Input;
24
- export declare const like: {
25
- load: (() => void) | undefined;
26
- update: ((dt: number) => void) | undefined;
27
- draw: ((canvas: HTMLCanvasElement) => void) | undefined;
28
- resize: ((size: Vector2, pixelSize: Vector2, fullscreen: boolean) => void) | undefined;
29
- keypressed: ((scancode: string, keycode: string) => void) | undefined;
30
- keyreleased: ((scancode: string, keycode: string) => void) | undefined;
31
- mousepressed: ((x: number, y: number, button: number) => void) | undefined;
32
- mousereleased: ((x: number, y: number, button: number) => void) | undefined;
33
- gamepadpressed: ((i: number, b: number, n: string) => void) | undefined;
34
- gamepadreleased: ((i: number, b: number, n: string) => void) | undefined;
35
- actionpressed: ((action: string) => void) | undefined;
36
- actionreleased: ((action: string) => void) | undefined;
37
- handleEvent: ((event: Like2DEvent) => void) | undefined;
38
- setMode(mode: PartialCanvasMode): void;
39
- getMode(): CanvasMode | undefined;
40
- init(container: HTMLElement): Promise<void>;
41
- dispose(): void;
2
+ import type { Like } from '../../core/like';
3
+ type LikeWithCallbacks = Like & {
4
+ load?: () => void;
5
+ update?: (dt: number) => void;
6
+ draw?: () => void;
7
+ resize?: (size: import('../../core/vector2').Vector2, pixelSize: import('../../core/vector2').Vector2, fullscreen: boolean) => void;
8
+ keypressed?: (scancode: string, keycode: string) => void;
9
+ keyreleased?: (scancode: string, keycode: string) => void;
10
+ mousepressed?: (x: number, y: number, button: number) => void;
11
+ mousereleased?: (x: number, y: number, button: number) => void;
12
+ gamepadpressed?: (gamepadIndex: number, buttonIndex: number, buttonName: string) => void;
13
+ gamepadreleased?: (gamepadIndex: number, buttonIndex: number, buttonName: string) => void;
14
+ actionpressed?: (action: string) => void;
15
+ actionreleased?: (action: string) => void;
16
+ handleEvent?: (event: Like2DEvent) => void;
17
+ start: () => Promise<void>;
18
+ dispose: () => void;
42
19
  };
43
- export { like as love };
20
+ export declare function routeEvents(like: LikeWithCallbacks): (event: Like2DEvent) => void;
21
+ export declare function createLike(container: HTMLElement): LikeWithCallbacks;
22
+ export {};
44
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/callback/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/callback/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,mBAAmB,CAAC;AAC1E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAM5C,KAAK,iBAAiB,GAAG,IAAI,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,oBAAoB,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,oBAAoB,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IACpI,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/D,cAAc,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACzF,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1F,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAC3C,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAGF,wBAAgB,WAAW,CAAC,IAAI,EAAE,iBAAiB,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAKjF;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,WAAW,GAAG,iBAAiB,CAqBpE"}
@@ -1,80 +1,30 @@
1
- import { Graphics } from '../../core/graphics';
2
- import { Audio } from '../../core/audio';
3
- import { Input } from '../../core/input';
4
- import { Timer } from '../../core/timer';
5
- import { Keyboard } from '../../core/keyboard';
6
- import { Mouse } from '../../core/mouse';
7
- import { Gamepad } from '../../core/gamepad';
8
1
  import { Engine } from '../../engine';
9
- export { ImageHandle } from '../../core/graphics';
10
- export { getGPName, GP } from '../../core/gamepad';
11
- export { Vec2 } from '../../core/vector2';
12
- export { Rect } from '../../core/rect';
13
- export { calcFixedScale } from '../../core/canvas-config';
14
- export let graphics;
15
- export const audio = new Audio();
16
- export const timer = new Timer();
17
- export let keyboard;
18
- export let mouse;
19
- export let gamepad;
20
- export let input;
21
- let engine = null;
22
- export const like = {
23
- load: undefined,
24
- update: undefined,
25
- draw: undefined,
26
- resize: undefined,
27
- keypressed: undefined,
28
- keyreleased: undefined,
29
- mousepressed: undefined,
30
- mousereleased: undefined,
31
- gamepadpressed: undefined,
32
- gamepadreleased: undefined,
33
- actionpressed: undefined,
34
- actionreleased: undefined,
35
- handleEvent: undefined,
36
- setMode(mode) {
37
- engine?.setMode(mode);
38
- },
39
- getMode() {
40
- return engine?.getMode();
41
- },
42
- async init(container) {
43
- engine = new Engine(container);
44
- graphics = new Graphics(engine.getContext());
45
- keyboard = new Keyboard();
46
- mouse = new Mouse((cssX, cssY) => engine.transformMousePosition(cssX, cssY));
47
- gamepad = new Gamepad();
48
- input = new Input({ keyboard, mouse, gamepad });
49
- engine.setDeps({ graphics, input, timer, audio, keyboard, mouse, gamepad });
50
- await gamepad.init();
51
- engine.start((event) => {
52
- // 1. handleEvent first
53
- like.handleEvent?.(event);
54
- // 2. Direct handlers
55
- const handler = like[event.type];
56
- if (handler) {
57
- handler(...event.args);
58
- }
59
- });
60
- },
61
- dispose() {
62
- engine?.stop();
63
- engine?.dispose();
64
- engine = null;
65
- this.load = undefined;
66
- this.update = undefined;
67
- this.draw = undefined;
68
- this.resize = undefined;
69
- this.keypressed = undefined;
70
- this.keyreleased = undefined;
71
- this.mousepressed = undefined;
72
- this.mousereleased = undefined;
73
- this.gamepadpressed = undefined;
74
- this.gamepadreleased = undefined;
75
- this.actionpressed = undefined;
76
- this.actionreleased = undefined;
77
- this.handleEvent = undefined;
78
- }
79
- };
80
- export { like as love };
2
+ // Routes events to callback properties on the like object
3
+ export function routeEvents(like) {
4
+ return (event) => {
5
+ const cb = like[event.type];
6
+ if (cb)
7
+ cb(...event.args);
8
+ };
9
+ }
10
+ export function createLike(container) {
11
+ const engine = new Engine(container);
12
+ // Create the like object that combines engine.like with callback properties and methods
13
+ const like = {
14
+ ...engine.like,
15
+ handleEvent: undefined,
16
+ start: async () => {
17
+ const handleEvent = (event) => {
18
+ like.handleEvent?.(event);
19
+ const cb = like[event.type];
20
+ if (cb)
21
+ cb(...event.args);
22
+ };
23
+ await engine.start(handleEvent);
24
+ },
25
+ dispose: () => {
26
+ engine.dispose();
27
+ }
28
+ };
29
+ return like;
30
+ }
@@ -1,42 +1,17 @@
1
- import { Graphics } from '../../core/graphics';
2
- import { Audio } from '../../core/audio';
3
- import { Input } from '../../core/input';
4
- import { Timer } from '../../core/timer';
5
- import { Keyboard } from '../../core/keyboard';
6
- import { Mouse } from '../../core/mouse';
7
- import { Gamepad } from '../../core/gamepad';
1
+ import { Engine } from '../../engine';
8
2
  import type { Scene } from './scene';
9
- import type { CanvasMode, PartialCanvasMode } from '../../core/canvas-config';
10
3
  import { StartupScene } from './startup-scene';
11
- export { Graphics, ImageHandle } from '../../core/graphics';
4
+ import type { Like2DEvent } from '../../core/events';
12
5
  export { StartupScene };
13
- export { Audio } from '../../core/audio';
14
- export { Input } from '../../core/input';
15
- export { Timer } from '../../core/timer';
16
- export { Keyboard } from '../../core/keyboard';
17
- export { Mouse } from '../../core/mouse';
18
- export { Gamepad, getGPName, GP } from '../../core/gamepad';
19
- export type { Like2DEvent as Event } from '../../core/events';
20
- export type { Scene } from './scene';
21
- export type { Vector2 } from '../../core/vector2';
22
- export { Vec2 } from '../../core/vector2';
23
- export { Rect } from '../../core/rect';
24
- export type { CanvasMode, PartialCanvasMode } from '../../core/canvas-config';
25
- export { calcFixedScale } from '../../core/canvas-config';
6
+ export type { Scene };
7
+ export declare function createDefaultHandler(scene: Scene, like: Engine['like']): (event: Like2DEvent) => void;
26
8
  export declare class SceneRunner {
27
9
  private engine;
28
10
  private scene;
29
- readonly graphics: Graphics;
30
- readonly audio: Audio;
31
- readonly timer: Timer;
32
- readonly input: Input;
33
- readonly keyboard: Keyboard;
34
- readonly mouse: Mouse;
35
- readonly gamepad: Gamepad;
36
11
  constructor(container: HTMLElement);
37
- setMode(mode: PartialCanvasMode): void;
38
- getMode(): CanvasMode;
12
+ get like(): import("../..").Like;
39
13
  setScene(scene: Scene): void;
14
+ handleEvent: (event: Like2DEvent) => void;
40
15
  start(scene: Scene): Promise<void>;
41
16
  dispose(): void;
42
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/scene/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,CAAC;AACxB,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAC5D,YAAY,EAAE,WAAW,IAAI,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC9D,YAAY,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,YAAY,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAsB;IAEnC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBAEd,SAAS,EAAE,WAAW;IAWlC,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI;IAItC,OAAO,IAAI,UAAU;IAIrB,QAAQ,CAAC,KAAK,EAAE,KAAK;IAKf,KAAK,CAAC,KAAK,EAAE,KAAK;IAiBxB,OAAO,IAAI,IAAI;CAKhB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/scene/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,YAAY,EAAE,CAAC;AACxB,YAAY,EAAE,KAAK,EAAE,CAAC;AAGtB,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAMrG;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAsB;gBAEvB,SAAS,EAAE,WAAW;IAIlC,IAAI,IAAI,yBAEP;IAED,QAAQ,CAAC,KAAK,EAAE,KAAK;IAKrB,WAAW,GAAI,OAAO,WAAW,KAAG,IAAI,CAKtC;IAEI,KAAK,CAAC,KAAK,EAAE,KAAK;IAKxB,OAAO;CAIR"}
@@ -1,23 +1,15 @@
1
- import { Graphics } from '../../core/graphics';
2
- import { Audio } from '../../core/audio';
3
- import { Input } from '../../core/input';
4
- import { Timer } from '../../core/timer';
5
- import { Keyboard } from '../../core/keyboard';
6
- import { Mouse } from '../../core/mouse';
7
- import { Gamepad } from '../../core/gamepad';
8
1
  import { Engine } from '../../engine';
9
2
  import { StartupScene } from './startup-scene';
10
- export { Graphics, ImageHandle } from '../../core/graphics';
11
3
  export { StartupScene };
12
- export { Audio } from '../../core/audio';
13
- export { Input } from '../../core/input';
14
- export { Timer } from '../../core/timer';
15
- export { Keyboard } from '../../core/keyboard';
16
- export { Mouse } from '../../core/mouse';
17
- export { Gamepad, getGPName, GP } from '../../core/gamepad';
18
- export { Vec2 } from '../../core/vector2';
19
- export { Rect } from '../../core/rect';
20
- export { calcFixedScale } from '../../core/canvas-config';
4
+ // Default handler that routes events to scene methods
5
+ export function createDefaultHandler(scene, like) {
6
+ return (event) => {
7
+ scene.handleEvent?.(like, event);
8
+ const method = scene[event.type];
9
+ if (method)
10
+ method.call(scene, like, ...event.args);
11
+ };
12
+ }
21
13
  export class SceneRunner {
22
14
  constructor(container) {
23
15
  Object.defineProperty(this, "engine", {
@@ -32,83 +24,33 @@ export class SceneRunner {
32
24
  writable: true,
33
25
  value: null
34
26
  });
35
- Object.defineProperty(this, "graphics", {
36
- enumerable: true,
37
- configurable: true,
38
- writable: true,
39
- value: void 0
40
- });
41
- Object.defineProperty(this, "audio", {
42
- enumerable: true,
43
- configurable: true,
44
- writable: true,
45
- value: void 0
46
- });
47
- Object.defineProperty(this, "timer", {
48
- enumerable: true,
49
- configurable: true,
50
- writable: true,
51
- value: void 0
52
- });
53
- Object.defineProperty(this, "input", {
54
- enumerable: true,
55
- configurable: true,
56
- writable: true,
57
- value: void 0
58
- });
59
- Object.defineProperty(this, "keyboard", {
60
- enumerable: true,
61
- configurable: true,
62
- writable: true,
63
- value: void 0
64
- });
65
- Object.defineProperty(this, "mouse", {
66
- enumerable: true,
67
- configurable: true,
68
- writable: true,
69
- value: void 0
70
- });
71
- Object.defineProperty(this, "gamepad", {
27
+ Object.defineProperty(this, "handleEvent", {
72
28
  enumerable: true,
73
29
  configurable: true,
74
30
  writable: true,
75
- value: void 0
31
+ value: (event) => {
32
+ if (!this.scene)
33
+ return;
34
+ this.scene.handleEvent?.(this.engine.like, event);
35
+ const method = this.scene[event.type];
36
+ if (method)
37
+ method.call(this.scene, this.engine.like, ...event.args);
38
+ }
76
39
  });
77
40
  this.engine = new Engine(container);
78
- this.graphics = new Graphics(this.engine.getContext());
79
- this.keyboard = new Keyboard();
80
- this.mouse = new Mouse((cssX, cssY) => this.engine.transformMousePosition(cssX, cssY));
81
- this.gamepad = new Gamepad();
82
- this.input = new Input({ keyboard: this.keyboard, mouse: this.mouse, gamepad: this.gamepad });
83
- this.timer = new Timer();
84
- this.audio = new Audio();
85
- }
86
- setMode(mode) {
87
- this.engine.setMode(mode);
88
41
  }
89
- getMode() {
90
- return this.engine.getMode();
42
+ get like() {
43
+ return this.engine.like;
91
44
  }
92
45
  setScene(scene) {
93
46
  this.scene = scene;
94
- this.scene.load?.();
47
+ scene.load?.(this.engine.like);
95
48
  }
96
49
  async start(scene) {
97
50
  this.setScene(scene);
98
- this.engine.setDeps({ graphics: this.graphics, input: this.input, timer: this.timer, audio: this.audio, keyboard: this.keyboard, mouse: this.mouse, gamepad: this.gamepad });
99
- await this.gamepad.init();
100
- this.engine.start((event) => {
101
- // 1. handleEvent runs first
102
- this.scene?.handleEvent?.(event);
103
- // 2. Direct handlers
104
- const handler = this.scene?.[event.type];
105
- if (handler) {
106
- handler.apply(this.scene, event.args);
107
- }
108
- });
51
+ await this.engine.start(this.handleEvent);
109
52
  }
110
53
  dispose() {
111
- this.engine.stop();
112
54
  this.engine.dispose();
113
55
  this.scene = null;
114
56
  }
@@ -1,18 +1,19 @@
1
1
  import type { Vector2 } from '../../core/vector2';
2
2
  import type { Like2DEvent } from '../../core/events';
3
+ import type { Like } from '../../core/like';
3
4
  export type Scene = {
4
- load?(): void;
5
- update?(dt: number): void;
6
- draw?(canvas: HTMLCanvasElement): void;
7
- resize?(size: Vector2, pixelSize: Vector2, fullscreen: boolean): void;
8
- keypressed?(scancode: string, keycode: string): void;
9
- keyreleased?(scancode: string, keycode: string): void;
10
- mousepressed?(x: number, y: number, button: number): void;
11
- mousereleased?(x: number, y: number, button: number): void;
12
- gamepadpressed?(gamepadIndex: number, buttonIndex: number, buttonName: string): void;
13
- gamepadreleased?(gamepadIndex: number, buttonIndex: number, buttonName: string): void;
14
- actionpressed?(action: string): void;
15
- actionreleased?(action: string): void;
16
- handleEvent?(event: Like2DEvent): void;
5
+ load?(like: Like): void;
6
+ update?(like: Like, dt: number): void;
7
+ draw?(like: Like): void;
8
+ resize?(like: Like, size: Vector2, pixelSize: Vector2, fullscreen: boolean): void;
9
+ keypressed?(like: Like, scancode: string, keycode: string): void;
10
+ keyreleased?(like: Like, scancode: string, keycode: string): void;
11
+ mousepressed?(like: Like, x: number, y: number, button: number): void;
12
+ mousereleased?(like: Like, x: number, y: number, button: number): void;
13
+ gamepadpressed?(like: Like, gamepadIndex: number, buttonIndex: number, buttonName: string): void;
14
+ gamepadreleased?(like: Like, gamepadIndex: number, buttonIndex: number, buttonName: string): void;
15
+ actionpressed?(like: Like, action: string): void;
16
+ actionreleased?(like: Like, action: string): void;
17
+ handleEvent?(like: Like, event: Like2DEvent): void;
17
18
  };
18
19
  //# sourceMappingURL=scene.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../../../src/adapters/scene/scene.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,MAAM,KAAK,GAAG;IAClB,IAAI,CAAC,IAAI,IAAI,CAAC;IACd,MAAM,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,CAAC,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACvC,MAAM,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,GAAG,IAAI,CAAC;IACtE,UAAU,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACrD,WAAW,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACtD,YAAY,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1D,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3D,cAAc,CAAC,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACrF,eAAe,CAAC,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACtF,aAAa,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,cAAc,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,WAAW,CAAC,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;CACxC,CAAC"}
1
+ {"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../../../src/adapters/scene/scene.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,MAAM,KAAK,GAAG;IAClB,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,GAAG,IAAI,CAAC;IAClF,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACjE,WAAW,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAClE,YAAY,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtE,aAAa,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACvE,cAAc,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACjG,eAAe,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAClG,aAAa,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,cAAc,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAClD,WAAW,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;CACpD,CAAC"}
@@ -1,19 +1,18 @@
1
1
  import type { Scene } from './scene';
2
- import type { Graphics } from '../../core/graphics';
3
2
  import { ImageHandle } from '../../core/graphics';
3
+ import type { Like } from '../../core/like';
4
4
  export type StartupSceneConfig = {
5
5
  nextScene: Scene;
6
- draw?: (g: Graphics, canvas: HTMLCanvasElement) => void;
6
+ draw?: (like: Like, logo: ImageHandle) => void;
7
7
  logo?: ImageHandle;
8
8
  };
9
9
  export declare class StartupScene implements Scene {
10
- private graphics;
11
10
  private config;
12
11
  private setScene;
13
12
  private started;
14
13
  private logo;
15
- constructor(graphics: Graphics, config: StartupSceneConfig, setScene: (scene: Scene) => void);
16
- draw(canvas: HTMLCanvasElement): void;
17
- mousepressed(_x: number, _y: number, _button: number): void;
14
+ constructor(config: StartupSceneConfig, setScene: (scene: Scene) => void);
15
+ draw(like: Like): void;
16
+ mousepressed(_like: Like, _x: number, _y: number, _button: number): void;
18
17
  }
19
18
  //# sourceMappingURL=startup-scene.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"startup-scene.d.ts","sourceRoot":"","sources":["../../../src/adapters/scene/startup-scene.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIlD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,KAAK,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACxD,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB,CAAC;AA6BF,qBAAa,YAAa,YAAW,KAAK;IAKtC,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IANlB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,IAAI,CAAc;gBAGhB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI;IAM1C,IAAI,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAIrC,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;CAM5D"}
1
+ {"version":3,"file":"startup-scene.d.ts","sourceRoot":"","sources":["../../../src/adapters/scene/startup-scene.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,WAAW,EAAY,MAAM,qBAAqB,CAAC;AAG5D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,KAAK,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IAC/C,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB,CAAC;AA4BF,qBAAa,YAAa,YAAW,KAAK;IAKtC,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IALlB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,IAAI,CAAc;gBAGhB,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI;IAK1C,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAItB,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;CAMzE"}