like2d 2.9.0 → 2.10.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.
- package/README.md +21 -17
- package/dist/__benchmarks__/vector2.bench.d.ts +2 -0
- package/dist/__benchmarks__/vector2.bench.d.ts.map +1 -0
- package/dist/__benchmarks__/vector2.bench.js +74 -0
- package/dist/{core → audio}/audio.d.ts +12 -3
- package/dist/audio/audio.d.ts.map +1 -0
- package/dist/{core → audio}/audio.js +10 -2
- package/dist/audio/index.d.ts +2 -0
- package/dist/audio/index.d.ts.map +1 -0
- package/dist/audio/index.js +1 -0
- package/dist/engine.d.ts +12 -42
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +34 -76
- package/dist/{core/events.d.ts → events.d.ts} +27 -50
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +5 -0
- package/dist/gamecontrollerdb.txt +2222 -0
- package/dist/{core → graphics}/canvas.d.ts +18 -11
- package/dist/graphics/canvas.d.ts.map +1 -0
- package/dist/{core → graphics}/canvas.js +73 -58
- package/dist/{core/graphics.d.ts → graphics/drawing.d.ts} +25 -25
- package/dist/graphics/drawing.d.ts.map +1 -0
- package/dist/{core/graphics.js → graphics/drawing.js} +59 -52
- package/dist/graphics/index.d.ts +19 -0
- package/dist/graphics/index.d.ts.map +1 -0
- package/dist/graphics/index.js +13 -0
- package/dist/index.d.ts +3 -30
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -21
- package/dist/input/gamepad-mapping.d.ts +134 -0
- package/dist/input/gamepad-mapping.d.ts.map +1 -0
- package/dist/input/gamepad-mapping.js +146 -0
- package/dist/input/gamepad.d.ts +74 -0
- package/dist/input/gamepad.d.ts.map +1 -0
- package/dist/input/gamepad.js +288 -0
- package/dist/input/index.d.ts +6 -0
- package/dist/input/index.d.ts.map +1 -0
- package/dist/input/index.js +1 -0
- package/dist/input/input.d.ts +76 -0
- package/dist/input/input.d.ts.map +1 -0
- package/dist/input/input.js +164 -0
- package/dist/input/keyboard.d.ts +15 -0
- package/dist/input/keyboard.d.ts.map +1 -0
- package/dist/{core → input}/keyboard.js +11 -21
- package/dist/input/mouse.d.ts +108 -0
- package/dist/input/mouse.d.ts.map +1 -0
- package/dist/input/mouse.js +241 -0
- package/dist/like.d.ts +80 -0
- package/dist/like.d.ts.map +1 -0
- package/dist/like.js +5 -0
- package/dist/math/index.d.ts +16 -0
- package/dist/math/index.d.ts.map +1 -1
- package/dist/math/index.js +16 -0
- package/dist/math/rect.d.ts +24 -27
- package/dist/math/rect.d.ts.map +1 -1
- package/dist/math/rect.js +47 -73
- package/dist/math/vector2.d.ts +87 -32
- package/dist/math/vector2.d.ts.map +1 -1
- package/dist/math/vector2.js +92 -110
- package/dist/prefab-scenes/index.d.ts +1 -0
- package/dist/prefab-scenes/index.d.ts.map +1 -1
- package/dist/prefab-scenes/index.js +1 -0
- package/dist/prefab-scenes/mapGamepad.d.ts +28 -0
- package/dist/prefab-scenes/mapGamepad.d.ts.map +1 -0
- package/dist/prefab-scenes/mapGamepad.js +181 -0
- package/dist/prefab-scenes/startScreen.d.ts +2 -2
- package/dist/prefab-scenes/startScreen.js +2 -2
- package/dist/scene.d.ts +2 -2
- package/dist/scene.d.ts.map +1 -1
- package/dist/timer/index.d.ts +2 -0
- package/dist/timer/index.d.ts.map +1 -0
- package/dist/timer/index.js +1 -0
- package/dist/timer/timer.d.ts +32 -0
- package/dist/timer/timer.d.ts.map +1 -0
- package/dist/{core → timer}/timer.js +20 -3
- package/package.json +22 -13
- package/dist/core/audio.d.ts.map +0 -1
- package/dist/core/canvas.d.ts.map +0 -1
- package/dist/core/events.d.ts.map +0 -1
- package/dist/core/events.js +0 -21
- package/dist/core/gamepad-mapping.d.ts +0 -58
- package/dist/core/gamepad-mapping.d.ts.map +0 -1
- package/dist/core/gamepad-mapping.js +0 -23
- package/dist/core/gamepad.d.ts +0 -37
- package/dist/core/gamepad.d.ts.map +0 -1
- package/dist/core/gamepad.js +0 -103
- package/dist/core/graphics.d.ts.map +0 -1
- package/dist/core/input-state.d.ts +0 -14
- package/dist/core/input-state.d.ts.map +0 -1
- package/dist/core/input-state.js +0 -50
- package/dist/core/input.d.ts +0 -40
- package/dist/core/input.d.ts.map +0 -1
- package/dist/core/input.js +0 -105
- package/dist/core/keyboard.d.ts +0 -15
- package/dist/core/keyboard.d.ts.map +0 -1
- package/dist/core/like.d.ts +0 -113
- package/dist/core/like.d.ts.map +0 -1
- package/dist/core/like.js +0 -9
- package/dist/core/mouse.d.ts +0 -52
- package/dist/core/mouse.d.ts.map +0 -1
- package/dist/core/mouse.js +0 -142
- package/dist/core/timer.d.ts +0 -15
- package/dist/core/timer.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -31,9 +31,10 @@
|
|
|
31
31
|
</g>
|
|
32
32
|
</svg>
|
|
33
33
|
|
|
34
|
-
Lightweight
|
|
34
|
+
Lightweight web game framework inspired by [LÖVE](https://love2d.org/).
|
|
35
35
|
|
|
36
36
|
## <div style="color:red">During v2.x.x, LIKE's API will change.</div>
|
|
37
|
+
|
|
37
38
|
## What it is
|
|
38
39
|
|
|
39
40
|
LIKE is a cozy way to make 2d games for browser.
|
|
@@ -43,11 +44,11 @@ LIKE is a cozy way to make 2d games for browser.
|
|
|
43
44
|
- **🔥 Fire-and-forget Assets:** Graphics and audio that pretend to be synchronous.
|
|
44
45
|
- **🎯 DWIM graphics:** Turns repetitive draw calls into one while removing state bleed for properties like `lineCap`.
|
|
45
46
|
- **↔️ Two Canvas Modes:**
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
- **⭕ Easier Geometry:** `Vector2` and `Rect` are just number tuples (arrays), but a pure-functional library makes them easy to work with and plays nice with `map` and `reduce`.
|
|
49
|
-
- **🚲 Easy Input:** Keyboard, Mouse, and Gamepad all are given both event-based and
|
|
50
|
-
- **👟
|
|
47
|
+
- 🖊️ Audio-resize the canvas; sharp at any resolution.
|
|
48
|
+
- 👾 For retro-style developers, pixels stay crisp but smooth via prescaling.
|
|
49
|
+
- **⭕ Easier Geometry:** `Vector2` and `Rect` are just number tuples (arrays), but a pure-functional library makes them easy to work with and plays nice with `map` and `reduce`.
|
|
50
|
+
- **🚲 Easy Input:** Keyboard, Mouse, and Gamepad all are given both event-based and query-based options. Choose what fits your architecture. Most gamepads get auto-mapped perfectly, are easy to remap, and LIKE can load and save user mappings automatically.
|
|
51
|
+
- **👟Consistent APIs:** Colors 0-1, not 0-255. Seconds, not milliseconds. Physical gamepad buttons, not "A" or "B".
|
|
51
52
|
- **👉 Actions System:** An input layer maps inputs to actions, which fire usable events.
|
|
52
53
|
- **🌎 Global control:** Choose how to handle LIKE events, and manage resources with centralized trackers. LIKE is a great foundation for your own engine.
|
|
53
54
|
- **🐦 Light and Elegant:** Zero dependencies and less than 5000 lines of code -- focused entirely on what matters.
|
|
@@ -55,6 +56,7 @@ LIKE is a cozy way to make 2d games for browser.
|
|
|
55
56
|
## Installation
|
|
56
57
|
|
|
57
58
|
Most package managers will work.
|
|
59
|
+
|
|
58
60
|
```bash
|
|
59
61
|
npm install like2d
|
|
60
62
|
# or ...
|
|
@@ -66,6 +68,7 @@ deno add jsr:@like2d/like
|
|
|
66
68
|
|
|
67
69
|
To try Like2D quickly, use this starter with
|
|
68
70
|
hot reloading and a basic webpage.
|
|
71
|
+
|
|
69
72
|
```bash
|
|
70
73
|
npx degit 44100hertz/Like2D/examples/starter my-game
|
|
71
74
|
```
|
|
@@ -73,25 +76,25 @@ npx degit 44100hertz/Like2D/examples/starter my-game
|
|
|
73
76
|
## Usage Example
|
|
74
77
|
|
|
75
78
|
```typescript
|
|
76
|
-
import { createLike } from
|
|
79
|
+
import { createLike } from "like2d";
|
|
77
80
|
|
|
78
81
|
const like = createLike(document.body);
|
|
79
82
|
|
|
80
83
|
like.load = () => {
|
|
81
84
|
like.setMode([800, 600]);
|
|
82
|
-
like.input.setAction(
|
|
85
|
+
like.input.setAction("jump", ["Space", "BBottom"]);
|
|
83
86
|
};
|
|
84
87
|
|
|
85
88
|
like.update = (dt) => {
|
|
86
|
-
if (like.input.justPressed(
|
|
87
|
-
console.log(
|
|
89
|
+
if (like.input.justPressed("jump")) {
|
|
90
|
+
console.log("Jump!");
|
|
88
91
|
}
|
|
89
92
|
};
|
|
90
93
|
|
|
91
94
|
like.draw = () => {
|
|
92
95
|
like.gfx.clear([0.1, 0.1, 0.1, 1]);
|
|
93
|
-
like.gfx.circle(
|
|
94
|
-
like.gfx.print(
|
|
96
|
+
like.gfx.circle("fill", "dodgerblue", [400, 300], 50);
|
|
97
|
+
like.gfx.print("white", "Hello Like2D!", [20, 20]);
|
|
95
98
|
};
|
|
96
99
|
|
|
97
100
|
await like.start();
|
|
@@ -100,11 +103,12 @@ await like.start();
|
|
|
100
103
|
## For Love2D Developers
|
|
101
104
|
|
|
102
105
|
LIKE's API is not the same as LOVE, but similar in spirit. Notable differences:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
|
|
107
|
+
- Draw your graphics in one call, that's all. No setup or state bleed.
|
|
108
|
+
- You manage your own instance of like in a big friendly object. This allows us to have multiple games on one page.
|
|
109
|
+
- We use Vector2 and Rect tuples (like `[x, y]`) instead of loose coordinates.
|
|
110
|
+
- Theres an actions system -- `input.setAction` / `actionpressed` and `actionreleased` callbacks.
|
|
111
|
+
- Some things are missing either due to browser limitations or smaller scope.
|
|
108
112
|
|
|
109
113
|
## Feedback welcome
|
|
110
114
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector2.bench.d.ts","sourceRoot":"","sources":["../../src/__benchmarks__/vector2.bench.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { bench, describe } from 'vitest';
|
|
2
|
+
import { Vec2 } from '../math/vector2';
|
|
3
|
+
const VEC2_COUNT = 10000;
|
|
4
|
+
function makeVec2s(count) {
|
|
5
|
+
const vec2s = [];
|
|
6
|
+
for (let i = 0; i < count; i++) {
|
|
7
|
+
vec2s.push([Math.random() * 1000, Math.random() * 1000]);
|
|
8
|
+
}
|
|
9
|
+
return vec2s;
|
|
10
|
+
}
|
|
11
|
+
describe('Vector2', () => {
|
|
12
|
+
const a = makeVec2s(VEC2_COUNT);
|
|
13
|
+
const b = makeVec2s(VEC2_COUNT);
|
|
14
|
+
describe('binary operations', () => {
|
|
15
|
+
bench('add', () => {
|
|
16
|
+
let sum = 0;
|
|
17
|
+
for (let i = 0; i < VEC2_COUNT; i++) {
|
|
18
|
+
const result = Vec2.add(a[i], b[i]);
|
|
19
|
+
sum += result[0];
|
|
20
|
+
}
|
|
21
|
+
if (sum === -1)
|
|
22
|
+
console.log(sum);
|
|
23
|
+
});
|
|
24
|
+
bench('sub', () => {
|
|
25
|
+
let sum = 0;
|
|
26
|
+
for (let i = 0; i < VEC2_COUNT; i++) {
|
|
27
|
+
const result = Vec2.sub(a[i], b[i]);
|
|
28
|
+
sum += result[0];
|
|
29
|
+
}
|
|
30
|
+
if (sum === -1)
|
|
31
|
+
console.log(sum);
|
|
32
|
+
});
|
|
33
|
+
bench('mul', () => {
|
|
34
|
+
let sum = 0;
|
|
35
|
+
for (let i = 0; i < VEC2_COUNT; i++) {
|
|
36
|
+
const result = Vec2.mul(a[i], b[i]);
|
|
37
|
+
sum += result[0];
|
|
38
|
+
}
|
|
39
|
+
if (sum === -1)
|
|
40
|
+
console.log(sum);
|
|
41
|
+
});
|
|
42
|
+
bench('div', () => {
|
|
43
|
+
let sum = 0;
|
|
44
|
+
for (let i = 0; i < VEC2_COUNT; i++) {
|
|
45
|
+
const result = Vec2.div(a[i], b[i]);
|
|
46
|
+
sum += result[0];
|
|
47
|
+
}
|
|
48
|
+
if (sum === -1)
|
|
49
|
+
console.log(sum);
|
|
50
|
+
});
|
|
51
|
+
bench('dot', () => {
|
|
52
|
+
let sum = 0;
|
|
53
|
+
for (let i = 0; i < VEC2_COUNT; i++) {
|
|
54
|
+
const result = Vec2.dot(a[i], b[i]);
|
|
55
|
+
sum += result;
|
|
56
|
+
}
|
|
57
|
+
if (sum === -1)
|
|
58
|
+
console.log(sum);
|
|
59
|
+
});
|
|
60
|
+
bench('chained ops (add, sub, mul, div, dot)', () => {
|
|
61
|
+
let sum = 0;
|
|
62
|
+
for (let i = 0; i < VEC2_COUNT; i++) {
|
|
63
|
+
const r1 = Vec2.add(a[i], b[i]);
|
|
64
|
+
const r2 = Vec2.sub(r1, a[i]);
|
|
65
|
+
const r3 = Vec2.mul(r2, 2);
|
|
66
|
+
const r4 = Vec2.div(r3, b[i]);
|
|
67
|
+
const result = Vec2.dot(r4, a[i]);
|
|
68
|
+
sum += result;
|
|
69
|
+
}
|
|
70
|
+
if (sum === -1)
|
|
71
|
+
console.log(sum);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
});
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
*
|
|
6
6
|
* ## Track and give global control to all audio objects
|
|
7
7
|
* Start, stop, or set global volume for every currently playing sound.
|
|
8
|
-
*
|
|
9
8
|
*/
|
|
9
|
+
/** Pass this into like.audio.newSource as config. */
|
|
10
10
|
export type AudioSourceOptions = {
|
|
11
11
|
volume?: number;
|
|
12
12
|
};
|
|
@@ -21,12 +21,13 @@ export declare class AudioSource {
|
|
|
21
21
|
readonly path: string;
|
|
22
22
|
/** Underlying HTMLAudioElement. Modify directly for looping, pitch, etc. Use methods for playback control. Avoid setting volume directly. */
|
|
23
23
|
readonly audio: HTMLAudioElement;
|
|
24
|
+
/** Avoid setting these directly. */
|
|
24
25
|
readonly options: Required<AudioSourceOptions>;
|
|
25
26
|
/** Resolves when the audio is loaded and ready to play. */
|
|
26
27
|
readonly ready: Promise<void>;
|
|
27
28
|
private loadState;
|
|
28
29
|
private audioRef;
|
|
29
|
-
constructor(path: string, audioRef:
|
|
30
|
+
constructor(path: string, audioRef: Audio, options?: AudioSourceOptions);
|
|
30
31
|
isReady(): boolean;
|
|
31
32
|
play(): void;
|
|
32
33
|
stop(): void;
|
|
@@ -42,7 +43,15 @@ export declare class AudioSource {
|
|
|
42
43
|
getVolume(): number;
|
|
43
44
|
getDuration(): number;
|
|
44
45
|
}
|
|
45
|
-
|
|
46
|
+
/**
|
|
47
|
+
* The audio subsystem.
|
|
48
|
+
*
|
|
49
|
+
* Manages a handful of AudioSource objects, for things like global volume,
|
|
50
|
+
* global play/pause, etc..
|
|
51
|
+
*
|
|
52
|
+
* To make a new source, use `like.audio.newSource`.
|
|
53
|
+
*/
|
|
54
|
+
export declare class Audio {
|
|
46
55
|
private sources;
|
|
47
56
|
private globalVolume;
|
|
48
57
|
/**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../../src/audio/audio.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,qDAAqD;AACrD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAA;AAMD;;;;;;GAMG;AACH,qBAAa,WAAW;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6IAA6I;IAC7I,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,oCAAoC;IACpC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAC/C,2DAA2D;IAC3D,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,CAAC,SAAS,CAAoE;IACrF,OAAO,CAAC,QAAQ,CAAQ;gBAEZ,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,GAAE,kBAAuB;IAmC3E,OAAO,IAAI,OAAO;IAIlB,IAAI,IAAI,IAAI;IAUZ,IAAI,IAAI,IAAI;IAUZ,KAAK,IAAI,IAAI;IAQb,MAAM,IAAI,IAAI;IAYd,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAQ5B,IAAI,IAAI,MAAM;IAKd,SAAS,IAAI,OAAO;IAKpB,QAAQ,IAAI,OAAO;IAKnB,SAAS,IAAI,OAAO;IAKpB,+FAA+F;IAC/F,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK/B,SAAS,IAAI,MAAM;IAInB,WAAW,IAAI,MAAM;CAItB;AAED;;;;;;;GAOG;AACH,qBAAa,KAAK;IAChB,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,YAAY,CAAK;IAEzB;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,WAAW;IAMlE;;;QAGI;IACJ,aAAa,IAAI,WAAW,EAAE;IAS9B,OAAO,IAAI,IAAI;IAIf,QAAQ,IAAI,IAAI;IAIhB,SAAS,IAAI,IAAI;IAIjB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAO/B,SAAS,IAAI,MAAM;IAInB,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW;CAGxC"}
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*
|
|
6
6
|
* ## Track and give global control to all audio objects
|
|
7
7
|
* Start, stop, or set global volume for every currently playing sound.
|
|
8
|
-
*
|
|
9
8
|
*/
|
|
10
9
|
/**
|
|
11
10
|
* Handle to a loaded audio resource, which pretends to be synchronous.
|
|
@@ -29,6 +28,7 @@ export class AudioSource {
|
|
|
29
28
|
writable: true,
|
|
30
29
|
value: void 0
|
|
31
30
|
});
|
|
31
|
+
/** Avoid setting these directly. */
|
|
32
32
|
Object.defineProperty(this, "options", {
|
|
33
33
|
enumerable: true,
|
|
34
34
|
configurable: true,
|
|
@@ -169,7 +169,15 @@ export class AudioSource {
|
|
|
169
169
|
return 0;
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
|
-
|
|
172
|
+
/**
|
|
173
|
+
* The audio subsystem.
|
|
174
|
+
*
|
|
175
|
+
* Manages a handful of AudioSource objects, for things like global volume,
|
|
176
|
+
* global play/pause, etc..
|
|
177
|
+
*
|
|
178
|
+
* To make a new source, use `like.audio.newSource`.
|
|
179
|
+
*/
|
|
180
|
+
export class Audio {
|
|
173
181
|
constructor() {
|
|
174
182
|
Object.defineProperty(this, "sources", {
|
|
175
183
|
enumerable: true,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/audio/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,kBAAkB,EAAC,MAAM,SAAS,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/engine.d.ts
CHANGED
|
@@ -1,69 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module engine
|
|
3
3
|
* @description Core game engine - lifecycle management and event dispatch.
|
|
4
|
-
*
|
|
5
|
-
* You've reached the most evil part of the codebase -- the man
|
|
6
|
-
* behind the curtain.
|
|
7
|
-
*
|
|
8
|
-
* The secret force gluing everything together.
|
|
9
|
-
*
|
|
10
|
-
* If you want to use modules independently, look here first.
|
|
11
|
-
*
|
|
12
|
-
* ## Memory Management
|
|
13
|
-
*
|
|
14
|
-
* Always call `dispose()` when destroying an engine instance:
|
|
15
|
-
* - Removes all event listeners
|
|
16
|
-
* - Stops the game loop
|
|
17
|
-
* - Removes canvas from DOM
|
|
18
|
-
* - Cleans up canvas manager resources
|
|
19
|
-
*
|
|
20
4
|
*/
|
|
21
|
-
import type {
|
|
22
|
-
|
|
5
|
+
import type { EventType, EventMap, Dispatcher } from './events';
|
|
6
|
+
import type { Like } from './like';
|
|
7
|
+
export type EngineDispatcher = Dispatcher<EventType>;
|
|
8
|
+
export type EngineProps<T extends keyof EventMap> = {
|
|
9
|
+
canvas: HTMLCanvasElement;
|
|
10
|
+
abort: AbortSignal;
|
|
11
|
+
dispatch: Dispatcher<T>;
|
|
12
|
+
};
|
|
23
13
|
/**
|
|
14
|
+
* @private
|
|
24
15
|
* Core game engine managing the event loop and subsystems.
|
|
25
|
-
*
|
|
26
|
-
* Normally you don't instantiate this directly - use {@link createLike} instead.
|
|
27
|
-
* The Engine class is exposed for advanced use cases like testing or
|
|
28
|
-
* custom initialization sequences.
|
|
29
|
-
*
|
|
30
|
-
* All subsystems are accessible via the {@link like} property.
|
|
31
16
|
*/
|
|
32
17
|
export declare class Engine {
|
|
33
18
|
private container;
|
|
19
|
+
/** The canvas on which we bind all events. Not always the same canvas
|
|
20
|
+
* that we render to. */
|
|
34
21
|
private canvas;
|
|
35
22
|
private isRunning;
|
|
36
23
|
private lastTime;
|
|
37
24
|
private abort;
|
|
38
25
|
/**
|
|
39
26
|
* The Like interface providing access to all engine subsystems.
|
|
40
|
-
* This object is passed to all scene callbacks and game code.
|
|
41
27
|
*/
|
|
42
|
-
readonly like:
|
|
28
|
+
readonly like: Like;
|
|
43
29
|
constructor(container: HTMLElement);
|
|
44
30
|
private dispatch;
|
|
45
31
|
/**
|
|
46
32
|
* Start the game loop.
|
|
47
|
-
*
|
|
48
|
-
* @remarks
|
|
49
|
-
* This method:
|
|
50
|
-
* 1. Dispatches the initial `load` event
|
|
51
|
-
* 2. Starts the requestAnimationFrame loop
|
|
52
|
-
*
|
|
53
|
-
* The engine runs until dispose() is called.
|
|
54
33
|
*/
|
|
55
34
|
start(): Promise<void>;
|
|
56
35
|
/**
|
|
57
36
|
* Clean up all resources and stop the engine.
|
|
58
|
-
*
|
|
59
|
-
* @remarks
|
|
60
|
-
* This method:
|
|
61
|
-
* - Stops the game loop
|
|
62
|
-
* - Removes all event listeners (keyboard, mouse, window, fullscreen)
|
|
63
|
-
* - Disposes canvas manager (removes resize observer)
|
|
64
|
-
* - Removes the canvas element from the DOM
|
|
65
|
-
*
|
|
66
|
-
* The engine cannot be restarted after disposal - create a new instance.
|
|
67
37
|
*/
|
|
68
38
|
dispose(): void;
|
|
69
39
|
}
|
package/dist/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,KAAK,EAAa,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAInC,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;AACrD,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,MAAM,QAAQ,IAAI;IAClD,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;CACzB,CAAA;AAED;;;GAGG;AACH,qBAAa,MAAM;IAaL,OAAO,CAAC,SAAS;IAZ7B;4BACwB;IACxB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,KAAK,CAAyB;IAEtC;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;gBAEA,SAAS,EAAE,WAAW;IAuD1C,OAAO,CAAC,QAAQ;IAShB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4B5B;;OAEG;IACH,OAAO,IAAI,IAAI;CAIhB"}
|
package/dist/engine.js
CHANGED
|
@@ -1,40 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module engine
|
|
3
3
|
* @description Core game engine - lifecycle management and event dispatch.
|
|
4
|
-
*
|
|
5
|
-
* You've reached the most evil part of the codebase -- the man
|
|
6
|
-
* behind the curtain.
|
|
7
|
-
*
|
|
8
|
-
* The secret force gluing everything together.
|
|
9
|
-
*
|
|
10
|
-
* If you want to use modules independently, look here first.
|
|
11
|
-
*
|
|
12
|
-
* ## Memory Management
|
|
13
|
-
*
|
|
14
|
-
* Always call `dispose()` when destroying an engine instance:
|
|
15
|
-
* - Removes all event listeners
|
|
16
|
-
* - Stops the game loop
|
|
17
|
-
* - Removes canvas from DOM
|
|
18
|
-
* - Cleans up canvas manager resources
|
|
19
|
-
*
|
|
20
4
|
*/
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import { bindGraphics } from './
|
|
28
|
-
import {
|
|
5
|
+
import { Audio } from './audio/audio';
|
|
6
|
+
import { Input } from './input/input';
|
|
7
|
+
import { Timer } from './timer/timer';
|
|
8
|
+
import { Keyboard } from './input/keyboard';
|
|
9
|
+
import { Mouse } from './input/mouse';
|
|
10
|
+
import { Gamepad } from './input/gamepad';
|
|
11
|
+
import { bindGraphics } from './graphics/index';
|
|
12
|
+
import { Canvas } from './graphics/canvas';
|
|
29
13
|
import { sceneDispatch } from './scene';
|
|
30
14
|
/**
|
|
15
|
+
* @private
|
|
31
16
|
* Core game engine managing the event loop and subsystems.
|
|
32
|
-
*
|
|
33
|
-
* Normally you don't instantiate this directly - use {@link createLike} instead.
|
|
34
|
-
* The Engine class is exposed for advanced use cases like testing or
|
|
35
|
-
* custom initialization sequences.
|
|
36
|
-
*
|
|
37
|
-
* All subsystems are accessible via the {@link like} property.
|
|
38
17
|
*/
|
|
39
18
|
export class Engine {
|
|
40
19
|
constructor(container) {
|
|
@@ -44,6 +23,8 @@ export class Engine {
|
|
|
44
23
|
writable: true,
|
|
45
24
|
value: container
|
|
46
25
|
});
|
|
26
|
+
/** The canvas on which we bind all events. Not always the same canvas
|
|
27
|
+
* that we render to. */
|
|
47
28
|
Object.defineProperty(this, "canvas", {
|
|
48
29
|
enumerable: true,
|
|
49
30
|
configurable: true,
|
|
@@ -70,7 +51,6 @@ export class Engine {
|
|
|
70
51
|
});
|
|
71
52
|
/**
|
|
72
53
|
* The Like interface providing access to all engine subsystems.
|
|
73
|
-
* This object is passed to all scene callbacks and game code.
|
|
74
54
|
*/
|
|
75
55
|
Object.defineProperty(this, "like", {
|
|
76
56
|
enumerable: true,
|
|
@@ -78,22 +58,26 @@ export class Engine {
|
|
|
78
58
|
writable: true,
|
|
79
59
|
value: void 0
|
|
80
60
|
});
|
|
81
|
-
this.canvas =
|
|
82
|
-
const canvas = this.canvas.
|
|
83
|
-
canvas.addEventListener("like:updateRenderTarget", (event) => {
|
|
61
|
+
this.canvas = document.createElement('canvas');
|
|
62
|
+
const canvas = new Canvas(this.canvas, this.dispatch.bind(this), this.abort.signal);
|
|
63
|
+
this.canvas.addEventListener("like:updateRenderTarget", (event) => {
|
|
84
64
|
if (!(event instanceof CustomEvent))
|
|
85
65
|
return;
|
|
86
66
|
this.like.gfx = bindGraphics(event.detail.target.getContext('2d'));
|
|
87
67
|
});
|
|
88
|
-
this.container.appendChild(canvas);
|
|
89
|
-
let gfx = bindGraphics(canvas.getContext('2d'));
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
const
|
|
68
|
+
this.container.appendChild(this.canvas);
|
|
69
|
+
let gfx = bindGraphics(this.canvas.getContext('2d'));
|
|
70
|
+
const props = {
|
|
71
|
+
canvas: this.canvas,
|
|
72
|
+
dispatch: this.dispatch.bind(this),
|
|
73
|
+
abort: this.abort.signal,
|
|
74
|
+
};
|
|
75
|
+
const audio = new Audio();
|
|
76
|
+
const timer = new Timer(props);
|
|
77
|
+
const keyboard = new Keyboard(props);
|
|
78
|
+
const mouse = new Mouse(props);
|
|
79
|
+
const gamepad = new Gamepad(props);
|
|
80
|
+
const input = new Input(props.dispatch, { keyboard, mouse, gamepad });
|
|
97
81
|
this.like = {
|
|
98
82
|
audio,
|
|
99
83
|
timer,
|
|
@@ -102,13 +86,14 @@ export class Engine {
|
|
|
102
86
|
mouse,
|
|
103
87
|
gamepad,
|
|
104
88
|
gfx,
|
|
105
|
-
canvas
|
|
89
|
+
canvas,
|
|
106
90
|
start: this.start.bind(this),
|
|
107
91
|
dispose: this.dispose.bind(this),
|
|
108
92
|
setScene: (scene) => {
|
|
109
93
|
if (scene) {
|
|
110
94
|
this.like.handleEvent = (event) => sceneDispatch(scene, this.like, event);
|
|
111
|
-
this.
|
|
95
|
+
if (this.isRunning)
|
|
96
|
+
this.dispatch("load", []);
|
|
112
97
|
}
|
|
113
98
|
else {
|
|
114
99
|
this.like.handleEvent = undefined;
|
|
@@ -121,8 +106,7 @@ export class Engine {
|
|
|
121
106
|
};
|
|
122
107
|
window.addEventListener('focus', () => this.dispatch('focus', ['tab']));
|
|
123
108
|
window.addEventListener('blur', () => this.dispatch('blur', ['tab']));
|
|
124
|
-
canvas.addEventListener('focus', () => this.dispatch('focus', ['canvas']));
|
|
125
|
-
canvas.addEventListener('focus', () => this.dispatch('focus', ['canvas']));
|
|
109
|
+
this.canvas.addEventListener('focus', () => this.dispatch('focus', ['canvas']));
|
|
126
110
|
}
|
|
127
111
|
dispatch(type, args) {
|
|
128
112
|
const event = { type, args, timestamp: this.like.timer.getTime() };
|
|
@@ -135,13 +119,6 @@ export class Engine {
|
|
|
135
119
|
}
|
|
136
120
|
/**
|
|
137
121
|
* Start the game loop.
|
|
138
|
-
*
|
|
139
|
-
* @remarks
|
|
140
|
-
* This method:
|
|
141
|
-
* 1. Dispatches the initial `load` event
|
|
142
|
-
* 2. Starts the requestAnimationFrame loop
|
|
143
|
-
*
|
|
144
|
-
* The engine runs until dispose() is called.
|
|
145
122
|
*/
|
|
146
123
|
async start() {
|
|
147
124
|
this.isRunning = true;
|
|
@@ -153,14 +130,12 @@ export class Engine {
|
|
|
153
130
|
const dt = (now - this.lastTime) / 1000;
|
|
154
131
|
this.lastTime = now;
|
|
155
132
|
if (!this.like.timer.isSleeping()) {
|
|
156
|
-
this.
|
|
157
|
-
const { pressed, released } = this.like.input._update();
|
|
158
|
-
pressed.forEach(action => this.dispatch('actionpressed', [action]));
|
|
159
|
-
released.forEach(action => this.dispatch('actionreleased', [action]));
|
|
133
|
+
this.canvas.dispatchEvent(new CustomEvent("update", { detail: { dt } }));
|
|
160
134
|
this.dispatch('update', [dt]);
|
|
161
135
|
}
|
|
136
|
+
this.canvas.dispatchEvent(new CustomEvent("like:preDraw"));
|
|
162
137
|
this.dispatch('draw', []);
|
|
163
|
-
this.canvas.
|
|
138
|
+
this.canvas.dispatchEvent(new CustomEvent("like:postDraw"));
|
|
164
139
|
requestAnimationFrame(loop);
|
|
165
140
|
};
|
|
166
141
|
this.dispatch('load', []);
|
|
@@ -168,26 +143,9 @@ export class Engine {
|
|
|
168
143
|
}
|
|
169
144
|
/**
|
|
170
145
|
* Clean up all resources and stop the engine.
|
|
171
|
-
*
|
|
172
|
-
* @remarks
|
|
173
|
-
* This method:
|
|
174
|
-
* - Stops the game loop
|
|
175
|
-
* - Removes all event listeners (keyboard, mouse, window, fullscreen)
|
|
176
|
-
* - Disposes canvas manager (removes resize observer)
|
|
177
|
-
* - Removes the canvas element from the DOM
|
|
178
|
-
*
|
|
179
|
-
* The engine cannot be restarted after disposal - create a new instance.
|
|
180
146
|
*/
|
|
181
147
|
dispose() {
|
|
182
|
-
const canvas = this.canvas._displayCanvas;
|
|
183
148
|
this.isRunning = false;
|
|
184
|
-
this.like.keyboard._dispose();
|
|
185
|
-
this.like.mouse._dispose();
|
|
186
|
-
this.like.gamepad._dispose();
|
|
187
|
-
this.canvas._dispose();
|
|
188
149
|
this.abort.abort();
|
|
189
|
-
if (canvas.parentNode === this.container) {
|
|
190
|
-
this.container.removeChild(canvas);
|
|
191
|
-
}
|
|
192
150
|
}
|
|
193
151
|
}
|
|
@@ -1,57 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module events
|
|
3
3
|
* @description All events that flow through the engine.
|
|
4
|
-
*
|
|
5
|
-
* ## Overview
|
|
6
|
-
*
|
|
7
|
-
* LIKE uses events at its core.
|
|
8
|
-
* These pass through the engine and down to your
|
|
9
|
-
* callbacks or scene.
|
|
10
|
-
*
|
|
11
|
-
* This module is the single source of truth for what
|
|
12
|
-
* events are possible.
|
|
13
|
-
*
|
|
14
|
-
* Use it as a reference.
|
|
15
|
-
*
|
|
16
|
-
* @see {@link EventMap} lists every event.
|
|
17
|
-
* @see {@link Scene} for implementing callbacks in a class
|
|
18
|
-
* @see {@link Like} for global callback assignment
|
|
19
|
-
* @see {@link Input} for action mapping
|
|
20
4
|
*/
|
|
21
|
-
import type { Vector2 } from '
|
|
22
|
-
import { LikeButton } from './
|
|
5
|
+
import type { Vector2 } from './math/vector2';
|
|
6
|
+
import type { LikeButton } from './input';
|
|
23
7
|
export type MouseButton = 'left' | 'middle' | 'right';
|
|
24
8
|
declare global {
|
|
25
9
|
interface HTMLElementEventMap {
|
|
26
10
|
['like:mousemoved']: CustomEvent<{
|
|
27
11
|
pos: Vector2;
|
|
28
12
|
delta: Vector2;
|
|
29
|
-
renderSize: Vector2;
|
|
30
13
|
}>;
|
|
31
14
|
['like:updateRenderTarget']: CustomEvent<{
|
|
32
15
|
target: HTMLCanvasElement;
|
|
33
16
|
}>;
|
|
17
|
+
['like:resizeCanvas']: CustomEvent<{
|
|
18
|
+
size: Vector2;
|
|
19
|
+
}>;
|
|
20
|
+
['like:preDraw']: CustomEvent<{}>;
|
|
21
|
+
['like:postDraw']: CustomEvent<{}>;
|
|
22
|
+
['like:update']: CustomEvent<{
|
|
23
|
+
dt: number;
|
|
24
|
+
}>;
|
|
34
25
|
}
|
|
35
26
|
}
|
|
36
27
|
/**
|
|
37
28
|
* The master type will all events on it.
|
|
38
|
-
*
|
|
39
|
-
* Each frame:
|
|
40
|
-
* 1. `update(dt)` - Game logic with delta time in seconds
|
|
41
|
-
* 2. `draw` - Render the frame
|
|
42
|
-
*
|
|
43
|
-
* Input events fire immediately when they occur:
|
|
44
|
-
* - `keypressed`/`keyreleased` - Keyboard input
|
|
45
|
-
* - `mousemoved`/`mousepressed`/`mousereleased` - Mouse input
|
|
46
|
-
* - `gamepadpressed`/`gamepadreleased` - Controller input
|
|
47
|
-
* - `actionpressed`/`actionreleased` - Mapped actions (see {@link Input})
|
|
48
|
-
*
|
|
49
|
-
* Window events:
|
|
50
|
-
* - `focus`/`blur` - Tab/window focus changes
|
|
51
|
-
* - `resize` - Canvas size changes
|
|
52
|
-
*
|
|
53
|
-
* Lifecycle:
|
|
54
|
-
* - `load` - Called once when the game starts
|
|
55
29
|
*/
|
|
56
30
|
export type EventMap = {
|
|
57
31
|
/** Game initialization. Called once before the first frame. */
|
|
@@ -76,28 +50,31 @@ export type EventMap = {
|
|
|
76
50
|
mousepressed: [pos: Vector2, button: MouseButton];
|
|
77
51
|
/** Mouse button released. */
|
|
78
52
|
mousereleased: [pos: Vector2, button: MouseButton];
|
|
79
|
-
/** Gamepad button pressed.
|
|
80
|
-
gamepadpressed: [source: number,
|
|
81
|
-
/** Gamepad button released. */
|
|
82
|
-
gamepadreleased: [source: number,
|
|
53
|
+
/** Gamepad button pressed. `source` is controller index, `name` is derived from a mapping on the raw `num` */
|
|
54
|
+
gamepadpressed: [source: number, name: LikeButton, num: number];
|
|
55
|
+
/** Gamepad button released. `source` is controller index, `name` is derived from a mapping on the raw `num` */
|
|
56
|
+
gamepadreleased: [source: number, name: LikeButton, num: number];
|
|
57
|
+
/**
|
|
58
|
+
* Fires when a gamepad is connected.
|
|
59
|
+
*/
|
|
60
|
+
gamepadconnected: [index: number];
|
|
61
|
+
/** Fires when a gamepad is disconnected. */
|
|
62
|
+
gamepaddisconnected: [index: number];
|
|
83
63
|
/** Mapped action triggered. See {@link Input} for action mapping. */
|
|
84
64
|
actionpressed: [action: string];
|
|
85
65
|
/** Mapped action released. */
|
|
86
66
|
actionreleased: [action: string];
|
|
87
67
|
};
|
|
88
68
|
export type EventType = keyof EventMap;
|
|
69
|
+
export type LikeMouseEvent = 'mousemoved' | 'mousepressed' | 'mousereleased';
|
|
70
|
+
export type LikeKeyboardEvent = 'keypressed' | 'keyreleased';
|
|
71
|
+
export type LikeGamepadEvent = 'gamepadpressed' | 'gamepadreleased' | 'gamepadconnected' | 'gamepaddisconnected';
|
|
72
|
+
/**
|
|
73
|
+
* Generic dispatcher - each module defines its own event subset
|
|
74
|
+
*/
|
|
75
|
+
export type Dispatcher<T extends EventType> = <K extends T>(type: K, args: EventMap[K]) => void;
|
|
89
76
|
/**
|
|
90
77
|
* Discriminated union of all event objects.
|
|
91
|
-
* Use this with `handleEvent` to receive all events generically.
|
|
92
|
-
*
|
|
93
|
-
* @example
|
|
94
|
-
* ```typescript
|
|
95
|
-
* handleEvent(like: Like, event: Like2DEvent) {
|
|
96
|
-
* if (event.type === 'update') {
|
|
97
|
-
* const dt = event.args[0];
|
|
98
|
-
* }
|
|
99
|
-
* }
|
|
100
|
-
* ```
|
|
101
78
|
*/
|
|
102
79
|
export type LikeEvent = {
|
|
103
80
|
[K in EventType]: {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
|