like2d 2.8.0 → 2.9.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 +34 -35
- package/dist/core/audio.d.ts +12 -9
- package/dist/core/audio.d.ts.map +1 -1
- package/dist/core/audio.js +7 -4
- package/dist/core/canvas.d.ts +58 -0
- package/dist/core/canvas.d.ts.map +1 -0
- package/dist/core/canvas.js +209 -0
- package/dist/core/events.d.ts +91 -13
- package/dist/core/events.d.ts.map +1 -1
- package/dist/core/events.js +20 -0
- package/dist/core/gamepad-mapping.d.ts +57 -18
- package/dist/core/gamepad-mapping.d.ts.map +1 -1
- package/dist/core/gamepad-mapping.js +23 -223
- package/dist/core/gamepad.d.ts +34 -58
- package/dist/core/gamepad.d.ts.map +1 -1
- package/dist/core/gamepad.js +79 -213
- package/dist/core/graphics.d.ts +175 -65
- package/dist/core/graphics.d.ts.map +1 -1
- package/dist/core/graphics.js +294 -202
- package/dist/core/input-state.d.ts +2 -2
- package/dist/core/input-state.d.ts.map +1 -1
- package/dist/core/input.d.ts +22 -15
- package/dist/core/input.d.ts.map +1 -1
- package/dist/core/input.js +25 -37
- package/dist/core/keyboard.d.ts +6 -7
- package/dist/core/keyboard.d.ts.map +1 -1
- package/dist/core/keyboard.js +15 -35
- package/dist/core/like.d.ts +98 -44
- package/dist/core/like.d.ts.map +1 -1
- package/dist/core/like.js +8 -0
- package/dist/core/mouse.d.ts +31 -24
- package/dist/core/mouse.d.ts.map +1 -1
- package/dist/core/mouse.js +59 -99
- package/dist/core/timer.d.ts +2 -5
- package/dist/core/timer.d.ts.map +1 -1
- package/dist/core/timer.js +2 -14
- package/dist/engine.d.ts +61 -16
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +121 -160
- package/dist/index.d.ts +42 -21
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -14
- package/dist/math/index.d.ts +2 -0
- package/dist/math/index.d.ts.map +1 -0
- package/dist/math/index.js +1 -0
- package/dist/math/rect.d.ts +71 -0
- package/dist/math/rect.d.ts.map +1 -0
- package/dist/{core → math}/rect.js +8 -0
- package/dist/math/vector2.d.ts +78 -0
- package/dist/math/vector2.d.ts.map +1 -0
- package/dist/{core → math}/vector2.js +24 -0
- package/dist/prefab-scenes/index.d.ts +7 -0
- package/dist/prefab-scenes/index.d.ts.map +1 -0
- package/dist/prefab-scenes/index.js +6 -0
- package/dist/prefab-scenes/startScreen.d.ts +59 -0
- package/dist/prefab-scenes/startScreen.d.ts.map +1 -0
- package/dist/{scenes/startup.js → prefab-scenes/startScreen.js} +48 -8
- package/dist/scene.d.ts +103 -5
- package/dist/scene.d.ts.map +1 -1
- package/dist/scene.js +28 -1
- package/package.json +18 -2
- package/dist/core/canvas-config.d.ts +0 -22
- package/dist/core/canvas-config.d.ts.map +0 -1
- package/dist/core/canvas-config.js +0 -14
- package/dist/core/canvas-manager.d.ts +0 -32
- package/dist/core/canvas-manager.d.ts.map +0 -1
- package/dist/core/canvas-manager.js +0 -179
- package/dist/core/gamepad-buttons.d.ts +0 -23
- package/dist/core/gamepad-buttons.d.ts.map +0 -1
- package/dist/core/gamepad-buttons.js +0 -36
- package/dist/core/rect.d.ts +0 -26
- package/dist/core/rect.d.ts.map +0 -1
- package/dist/core/vector2.d.ts +0 -26
- package/dist/core/vector2.d.ts.map +0 -1
- package/dist/gamecontrollerdb.txt +0 -2221
- package/dist/scenes/startup.d.ts +0 -18
- package/dist/scenes/startup.d.ts.map +0 -1
package/dist/engine.js
CHANGED
|
@@ -1,116 +1,99 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @module engine
|
|
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
|
+
*/
|
|
21
|
+
import { AudioInternal } from './core/audio';
|
|
22
|
+
import { InputInternal } from './core/input';
|
|
23
|
+
import { TimerInternal } from './core/timer';
|
|
24
|
+
import { KeyboardInternal } from './core/keyboard';
|
|
25
|
+
import { MouseInternal } from './core/mouse';
|
|
26
|
+
import { GamepadInternal } from './core/gamepad';
|
|
27
|
+
import { bindGraphics } from './core/graphics';
|
|
28
|
+
import { CanvasInternal } from './core/canvas';
|
|
29
|
+
import { sceneDispatch } from './scene';
|
|
30
|
+
/**
|
|
31
|
+
* 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
|
+
*/
|
|
9
39
|
export class Engine {
|
|
10
40
|
constructor(container) {
|
|
11
|
-
Object.defineProperty(this, "canvas", {
|
|
12
|
-
enumerable: true,
|
|
13
|
-
configurable: true,
|
|
14
|
-
writable: true,
|
|
15
|
-
value: void 0
|
|
16
|
-
});
|
|
17
|
-
Object.defineProperty(this, "isRunning", {
|
|
18
|
-
enumerable: true,
|
|
19
|
-
configurable: true,
|
|
20
|
-
writable: true,
|
|
21
|
-
value: false
|
|
22
|
-
});
|
|
23
|
-
Object.defineProperty(this, "lastTime", {
|
|
24
|
-
enumerable: true,
|
|
25
|
-
configurable: true,
|
|
26
|
-
writable: true,
|
|
27
|
-
value: 0
|
|
28
|
-
});
|
|
29
41
|
Object.defineProperty(this, "container", {
|
|
30
42
|
enumerable: true,
|
|
31
43
|
configurable: true,
|
|
32
44
|
writable: true,
|
|
33
|
-
value:
|
|
34
|
-
});
|
|
35
|
-
Object.defineProperty(this, "canvasManager", {
|
|
36
|
-
enumerable: true,
|
|
37
|
-
configurable: true,
|
|
38
|
-
writable: true,
|
|
39
|
-
value: void 0
|
|
40
|
-
});
|
|
41
|
-
Object.defineProperty(this, "handleEvent", {
|
|
42
|
-
enumerable: true,
|
|
43
|
-
configurable: true,
|
|
44
|
-
writable: true,
|
|
45
|
-
value: null
|
|
45
|
+
value: container
|
|
46
46
|
});
|
|
47
|
-
Object.defineProperty(this, "
|
|
48
|
-
enumerable: true,
|
|
49
|
-
configurable: true,
|
|
50
|
-
writable: true,
|
|
51
|
-
value: null
|
|
52
|
-
});
|
|
53
|
-
Object.defineProperty(this, "gfxState", {
|
|
47
|
+
Object.defineProperty(this, "canvas", {
|
|
54
48
|
enumerable: true,
|
|
55
49
|
configurable: true,
|
|
56
50
|
writable: true,
|
|
57
51
|
value: void 0
|
|
58
52
|
});
|
|
59
|
-
|
|
60
|
-
Object.defineProperty(this, "windowFocusHandler", {
|
|
61
|
-
enumerable: true,
|
|
62
|
-
configurable: true,
|
|
63
|
-
writable: true,
|
|
64
|
-
value: null
|
|
65
|
-
});
|
|
66
|
-
Object.defineProperty(this, "windowBlurHandler", {
|
|
67
|
-
enumerable: true,
|
|
68
|
-
configurable: true,
|
|
69
|
-
writable: true,
|
|
70
|
-
value: null
|
|
71
|
-
});
|
|
72
|
-
Object.defineProperty(this, "canvasFocusHandler", {
|
|
53
|
+
Object.defineProperty(this, "isRunning", {
|
|
73
54
|
enumerable: true,
|
|
74
55
|
configurable: true,
|
|
75
56
|
writable: true,
|
|
76
|
-
value:
|
|
57
|
+
value: false
|
|
77
58
|
});
|
|
78
|
-
Object.defineProperty(this, "
|
|
59
|
+
Object.defineProperty(this, "lastTime", {
|
|
79
60
|
enumerable: true,
|
|
80
61
|
configurable: true,
|
|
81
62
|
writable: true,
|
|
82
|
-
value:
|
|
63
|
+
value: 0
|
|
83
64
|
});
|
|
84
|
-
Object.defineProperty(this, "
|
|
65
|
+
Object.defineProperty(this, "abort", {
|
|
85
66
|
enumerable: true,
|
|
86
67
|
configurable: true,
|
|
87
68
|
writable: true,
|
|
88
|
-
value:
|
|
69
|
+
value: new AbortController()
|
|
89
70
|
});
|
|
71
|
+
/**
|
|
72
|
+
* The Like interface providing access to all engine subsystems.
|
|
73
|
+
* This object is passed to all scene callbacks and game code.
|
|
74
|
+
*/
|
|
90
75
|
Object.defineProperty(this, "like", {
|
|
91
76
|
enumerable: true,
|
|
92
77
|
configurable: true,
|
|
93
78
|
writable: true,
|
|
94
79
|
value: void 0
|
|
95
80
|
});
|
|
96
|
-
this.canvas =
|
|
97
|
-
this.canvas.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
this.container.appendChild(
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
const
|
|
112
|
-
const gamepad = new Gamepad();
|
|
113
|
-
const input = new Input({ keyboard, mouse, gamepad });
|
|
81
|
+
this.canvas = new CanvasInternal(this.dispatch.bind(this));
|
|
82
|
+
const canvas = this.canvas._displayCanvas;
|
|
83
|
+
canvas.addEventListener("like:updateRenderTarget", (event) => {
|
|
84
|
+
if (!(event instanceof CustomEvent))
|
|
85
|
+
return;
|
|
86
|
+
this.like.gfx = bindGraphics(event.detail.target.getContext('2d'));
|
|
87
|
+
});
|
|
88
|
+
this.container.appendChild(canvas);
|
|
89
|
+
let gfx = bindGraphics(canvas.getContext('2d'));
|
|
90
|
+
const dispatch = this.dispatch.bind(this);
|
|
91
|
+
const audio = new AudioInternal();
|
|
92
|
+
const timer = new TimerInternal();
|
|
93
|
+
const keyboard = new KeyboardInternal(canvas, dispatch);
|
|
94
|
+
const mouse = new MouseInternal(canvas, dispatch);
|
|
95
|
+
const gamepad = new GamepadInternal(dispatch);
|
|
96
|
+
const input = new InputInternal({ keyboard, mouse, gamepad });
|
|
114
97
|
this.like = {
|
|
115
98
|
audio,
|
|
116
99
|
timer,
|
|
@@ -119,76 +102,50 @@ export class Engine {
|
|
|
119
102
|
mouse,
|
|
120
103
|
gamepad,
|
|
121
104
|
gfx,
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
105
|
+
canvas: this.canvas,
|
|
106
|
+
start: this.start.bind(this),
|
|
107
|
+
dispose: this.dispose.bind(this),
|
|
125
108
|
setScene: (scene) => {
|
|
126
|
-
|
|
127
|
-
|
|
109
|
+
if (scene) {
|
|
110
|
+
this.like.handleEvent = (event) => sceneDispatch(scene, this.like, event);
|
|
111
|
+
this.dispatch("load", []);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
this.like.handleEvent = undefined;
|
|
115
|
+
}
|
|
128
116
|
},
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
this.gfxState = newState(target.ctx);
|
|
133
|
-
this.like.gfx = bindGraphics(this.gfxState);
|
|
134
|
-
};
|
|
135
|
-
keyboard.onKeyEvent = (scancode, keycode, type) => {
|
|
136
|
-
this.dispatch(type === 'keydown' ? 'keypressed' : 'keyreleased', [scancode, keycode]);
|
|
137
|
-
};
|
|
138
|
-
mouse.onMouseMove = (pos, relative) => {
|
|
139
|
-
this.dispatch('mousemoved', [pos, relative]);
|
|
140
|
-
};
|
|
141
|
-
mouse.onMouseDown = (pos, button) => {
|
|
142
|
-
this.dispatch('mousepressed', [pos, button]);
|
|
143
|
-
};
|
|
144
|
-
mouse.onMouseUp = (pos, button) => {
|
|
145
|
-
this.dispatch('mousereleased', [pos, button]);
|
|
146
|
-
};
|
|
147
|
-
gamepad.onButtonEvent = (gpIndex, buttonIndex, buttonName, pressed) => {
|
|
148
|
-
this.dispatch(pressed ? 'gamepadpressed' : 'gamepadreleased', [gpIndex, buttonIndex, buttonName]);
|
|
149
|
-
};
|
|
150
|
-
this.windowFocusHandler = () => this.dispatch('focus', []);
|
|
151
|
-
this.windowBlurHandler = () => this.dispatch('blur', []);
|
|
152
|
-
this.canvasFocusHandler = () => this.dispatch('focus', []);
|
|
153
|
-
this.canvasBlurHandler = () => this.dispatch('blur', []);
|
|
154
|
-
this.fullscreenChangeHandler = () => {
|
|
155
|
-
const mode = this.canvasManager.getMode();
|
|
156
|
-
const isFullscreen = !!document.fullscreenElement;
|
|
157
|
-
if (mode.fullscreen !== isFullscreen) {
|
|
158
|
-
this.canvasManager.setMode({ ...mode, fullscreen: isFullscreen });
|
|
117
|
+
callOwnHandlers: (event) => {
|
|
118
|
+
if (event.type in this.like)
|
|
119
|
+
this.like[event.type](...event.args);
|
|
159
120
|
}
|
|
160
121
|
};
|
|
161
|
-
window.addEventListener('focus', this.
|
|
162
|
-
window.addEventListener('blur', this.
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
document.addEventListener('fullscreenchange', this.fullscreenChangeHandler);
|
|
122
|
+
window.addEventListener('focus', () => this.dispatch('focus', ['tab']));
|
|
123
|
+
window.addEventListener('blur', () => this.dispatch('blur', ['tab']));
|
|
124
|
+
canvas.addEventListener('focus', () => this.dispatch('focus', ['canvas']));
|
|
125
|
+
canvas.addEventListener('focus', () => this.dispatch('focus', ['canvas']));
|
|
166
126
|
}
|
|
167
127
|
dispatch(type, args) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if (this.currentScene) {
|
|
172
|
-
this.currentScene.handleEvent?.(this.like, event);
|
|
173
|
-
const method = this.currentScene[event.type];
|
|
174
|
-
method?.call(this.currentScene, this.like, ...args);
|
|
128
|
+
const event = { type, args, timestamp: this.like.timer.getTime() };
|
|
129
|
+
if (this.like.handleEvent) {
|
|
130
|
+
this.like.handleEvent(event);
|
|
175
131
|
}
|
|
176
132
|
else {
|
|
177
|
-
this.
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
setMode(mode) {
|
|
181
|
-
const currentMode = this.canvasManager.getMode();
|
|
182
|
-
if ('fullscreen' in mode && mode.fullscreen !== currentMode.fullscreen) {
|
|
183
|
-
mode.fullscreen ? this.container.requestFullscreen().catch(console.error) : document.exitFullscreen();
|
|
133
|
+
this.like.callOwnHandlers(event);
|
|
184
134
|
}
|
|
185
|
-
this.canvasManager.setMode({ ...currentMode, ...mode });
|
|
186
135
|
}
|
|
187
|
-
|
|
188
|
-
|
|
136
|
+
/**
|
|
137
|
+
* 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
|
+
*/
|
|
146
|
+
async start() {
|
|
189
147
|
this.isRunning = true;
|
|
190
148
|
this.lastTime = performance.now();
|
|
191
|
-
await this.like.gamepad.init();
|
|
192
149
|
const loop = () => {
|
|
193
150
|
if (!this.isRunning)
|
|
194
151
|
return;
|
|
@@ -196,37 +153,41 @@ export class Engine {
|
|
|
196
153
|
const dt = (now - this.lastTime) / 1000;
|
|
197
154
|
this.lastTime = now;
|
|
198
155
|
if (!this.like.timer.isSleeping()) {
|
|
199
|
-
this.like.timer.
|
|
200
|
-
const { pressed, released } = this.like.input.
|
|
156
|
+
this.like.timer._update(dt);
|
|
157
|
+
const { pressed, released } = this.like.input._update();
|
|
201
158
|
pressed.forEach(action => this.dispatch('actionpressed', [action]));
|
|
202
159
|
released.forEach(action => this.dispatch('actionreleased', [action]));
|
|
203
160
|
this.dispatch('update', [dt]);
|
|
204
161
|
}
|
|
205
162
|
this.dispatch('draw', []);
|
|
206
|
-
this.
|
|
163
|
+
this.canvas._present();
|
|
207
164
|
requestAnimationFrame(loop);
|
|
208
165
|
};
|
|
209
166
|
this.dispatch('load', []);
|
|
210
167
|
requestAnimationFrame(loop);
|
|
211
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* 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
|
+
*/
|
|
212
181
|
dispose() {
|
|
182
|
+
const canvas = this.canvas._displayCanvas;
|
|
213
183
|
this.isRunning = false;
|
|
214
|
-
this.like.keyboard.
|
|
215
|
-
this.like.mouse.
|
|
216
|
-
this.like.gamepad.
|
|
217
|
-
this.
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
window.removeEventListener('blur', this.windowBlurHandler);
|
|
222
|
-
if (this.canvasFocusHandler)
|
|
223
|
-
this.canvas.removeEventListener('focus', this.canvasFocusHandler);
|
|
224
|
-
if (this.canvasBlurHandler)
|
|
225
|
-
this.canvas.removeEventListener('blur', this.canvasBlurHandler);
|
|
226
|
-
if (this.fullscreenChangeHandler)
|
|
227
|
-
document.removeEventListener('fullscreenchange', this.fullscreenChangeHandler);
|
|
228
|
-
if (this.canvas.parentNode === this.container) {
|
|
229
|
-
this.container.removeChild(this.canvas);
|
|
184
|
+
this.like.keyboard._dispose();
|
|
185
|
+
this.like.mouse._dispose();
|
|
186
|
+
this.like.gamepad._dispose();
|
|
187
|
+
this.canvas._dispose();
|
|
188
|
+
this.abort.abort();
|
|
189
|
+
if (canvas.parentNode === this.container) {
|
|
190
|
+
this.container.removeChild(canvas);
|
|
230
191
|
}
|
|
231
192
|
}
|
|
232
193
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,25 +1,46 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @module like2d
|
|
3
|
+
* @description A cozy web-native 2D game framework.
|
|
4
|
+
*
|
|
5
|
+
* See main like/README.md file an for overview of Like2D.
|
|
6
|
+
*/
|
|
7
|
+
import type { LikeEvent } from './core/events';
|
|
2
8
|
import type { Like } from './core/like';
|
|
3
9
|
export type { Like } from './core/like';
|
|
4
|
-
export type {
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
7
|
-
export type { Like2DEvent, EventType, EventMap } from './core/events';
|
|
8
|
-
export type { CanvasMode, PartialCanvasMode } from './core/canvas-config';
|
|
9
|
-
export type { Color, Quad, ShapeProps, DrawProps, PrintProps } from './core/graphics';
|
|
10
|
+
export type { LikeEvent, EventType, EventMap } from './core/events';
|
|
11
|
+
export type { CanvasSize, CanvasModeOptions as CanvasModeFlags } from './core/canvas';
|
|
12
|
+
export type { Color, ShapeProps, DrawProps, PrintProps } from './core/graphics';
|
|
10
13
|
export { ImageHandle } from './core/graphics';
|
|
11
|
-
export type {
|
|
12
|
-
export type
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
export
|
|
14
|
+
export type { AudioSource, AudioSourceOptions } from './core/audio';
|
|
15
|
+
export { type LikeButton } from './core/gamepad';
|
|
16
|
+
export type TopLevelEventHandler = (event: LikeEvent) => void;
|
|
17
|
+
/**
|
|
18
|
+
* Create a new Like2D game instance attached to a DOM container.
|
|
19
|
+
*
|
|
20
|
+
* This is the entry point for all Like2D games. It creates a canvas element,
|
|
21
|
+
* initializes all subsystems (graphics, audio, input), and returns an object
|
|
22
|
+
* where you can assign game callbacks.
|
|
23
|
+
*
|
|
24
|
+
* ### How to bind callbacks
|
|
25
|
+
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* export const like = createLike();
|
|
28
|
+
*
|
|
29
|
+
* like.start();
|
|
30
|
+
*
|
|
31
|
+
* like.draw = () => { like.gfx.clear('yellow') }
|
|
32
|
+
*
|
|
33
|
+
* like.update = function (dt: number) {
|
|
34
|
+
* if (dt === Math.random()) {
|
|
35
|
+
* console.log("You just won the Powerball!")
|
|
36
|
+
* }
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @param container - The HTML element to attach the game canvas to.
|
|
41
|
+
* Must be in the DOM.
|
|
42
|
+
* @returns A {@link Like} instance ready for callback assignment
|
|
43
|
+
*
|
|
44
|
+
*/
|
|
45
|
+
export declare function createLike(container: HTMLElement): Like;
|
|
25
46
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC,YAAY,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpE,YAAY,EAAE,UAAU,EAAE,iBAAiB,IAAI,eAAe,EAAE,MAAM,eAAe,CAAC;AACtF,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI,CAGvD"}
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module like2d
|
|
3
|
+
* @description A cozy web-native 2D game framework.
|
|
4
|
+
*
|
|
5
|
+
* See main like/README.md file an for overview of Like2D.
|
|
6
|
+
*/
|
|
1
7
|
import { Engine } from './engine';
|
|
2
|
-
export { Vec2 } from './core/vector2';
|
|
3
|
-
export { Rect } from './core/rect';
|
|
4
8
|
export { ImageHandle } from './core/graphics';
|
|
5
|
-
|
|
6
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Create a new Like2D game instance attached to a DOM container.
|
|
11
|
+
*
|
|
12
|
+
* This is the entry point for all Like2D games. It creates a canvas element,
|
|
13
|
+
* initializes all subsystems (graphics, audio, input), and returns an object
|
|
14
|
+
* where you can assign game callbacks.
|
|
15
|
+
*
|
|
16
|
+
* ### How to bind callbacks
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* export const like = createLike();
|
|
20
|
+
*
|
|
21
|
+
* like.start();
|
|
22
|
+
*
|
|
23
|
+
* like.draw = () => { like.gfx.clear('yellow') }
|
|
24
|
+
*
|
|
25
|
+
* like.update = function (dt: number) {
|
|
26
|
+
* if (dt === Math.random()) {
|
|
27
|
+
* console.log("You just won the Powerball!")
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @param container - The HTML element to attach the game canvas to.
|
|
33
|
+
* Must be in the DOM.
|
|
34
|
+
* @returns A {@link Like} instance ready for callback assignment
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
7
37
|
export function createLike(container) {
|
|
8
38
|
const engine = new Engine(container);
|
|
9
|
-
|
|
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
|
-
});
|
|
39
|
+
return engine.like;
|
|
19
40
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/math/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,GAAG,GAAI,GAAG,MAAM,EAAE,GAAG,MAAM,WAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const mod = (a, b) => ((a % b) + b) % b;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { type Vector2 } from '../math/vector2';
|
|
2
|
+
/**
|
|
3
|
+
* A four-coordinate type `[x, y, width, height]`.
|
|
4
|
+
* Full reference {@link Rect}.
|
|
5
|
+
*
|
|
6
|
+
* ## Examples
|
|
7
|
+
*
|
|
8
|
+
* ### Construct a rectangle
|
|
9
|
+
* ```ts
|
|
10
|
+
* const beastPen: Rectangle = [20, 25, 40, 50];
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* ### Construct around a center point and size
|
|
14
|
+
* ```ts
|
|
15
|
+
* const beastPen: Rectangle = Rect.setCenter(
|
|
16
|
+
* [0, 0, ...penSize],
|
|
17
|
+
* beastPos
|
|
18
|
+
* );
|
|
19
|
+
* ```
|
|
20
|
+
* ### Deconstruct a rect
|
|
21
|
+
* ```ts
|
|
22
|
+
* [x, y, w, h] = beastPen;
|
|
23
|
+
* ```
|
|
24
|
+
* ### Deconstruct into points
|
|
25
|
+
* ```ts
|
|
26
|
+
* const penPos = Rect.position(beastPen);
|
|
27
|
+
* const penSize = Rect.size(beastPen);
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* ### Check if beast is in his pen
|
|
31
|
+
* ```ts
|
|
32
|
+
* const isInPen = Rect.containsPoint(
|
|
33
|
+
* beastPen,
|
|
34
|
+
* beast.pos,
|
|
35
|
+
* )
|
|
36
|
+
* ```
|
|
37
|
+
* ### Put the beast back in his pen
|
|
38
|
+
* ```ts
|
|
39
|
+
* beast.pos = Rect.clampPoint(beast.pos, beastPen)
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* */
|
|
43
|
+
export type Rectangle = [number, number, number, number];
|
|
44
|
+
/**
|
|
45
|
+
* A set of
|
|
46
|
+
*/
|
|
47
|
+
export declare namespace Rect {
|
|
48
|
+
function fromPoints(a: Vector2, b: Vector2): Rectangle;
|
|
49
|
+
function fromCenter(center: Vector2, size: Vector2): Rectangle;
|
|
50
|
+
function position(r: Rectangle): Vector2;
|
|
51
|
+
function size(r: Rectangle): Vector2;
|
|
52
|
+
function center(r: Rectangle): Vector2;
|
|
53
|
+
function topLeft(r: Rectangle): Vector2;
|
|
54
|
+
function topRight(r: Rectangle): Vector2;
|
|
55
|
+
function bottomLeft(r: Rectangle): Vector2;
|
|
56
|
+
function bottomRight(r: Rectangle): Vector2;
|
|
57
|
+
function area(r: Rectangle): number;
|
|
58
|
+
function isEmpty(r: Rectangle): boolean;
|
|
59
|
+
function clampPoint(r: Rectangle, point: Vector2): Vector2;
|
|
60
|
+
function containsPoint(r: Rectangle, point: Vector2): boolean;
|
|
61
|
+
function containsRect(r: Rectangle, other: Rectangle): boolean;
|
|
62
|
+
function intersects(r: Rectangle, other: Rectangle): boolean;
|
|
63
|
+
function intersection(r: Rectangle, other: Rectangle): Rectangle;
|
|
64
|
+
function union(r: Rectangle, other: Rectangle): Rectangle;
|
|
65
|
+
function inflate(r: Rectangle, amount: number): Rectangle;
|
|
66
|
+
function offset(r: Rectangle, delta: Vector2): Rectangle;
|
|
67
|
+
function setPosition(r: Rectangle, pos: Vector2): Rectangle;
|
|
68
|
+
function setSize(r: Rectangle, size: Vector2): Rectangle;
|
|
69
|
+
function setCenter(r: Rectangle, center: Vector2): Rectangle;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=rect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rect.d.ts","sourceRoot":"","sources":["../../src/math/rect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAwCK;AACL,MAAM,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAEzD;;GAEG;AACH,yBAAiB,IAAI,CAAC;IACpB,SAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,SAAS,CAM5D;IAED,SAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS,CAOpE;IAED,SAAgB,QAAQ,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAE9C;IAED,SAAgB,IAAI,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAE1C;IAED,SAAgB,MAAM,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAE5C;IAED,SAAgB,OAAO,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAE7C;IAED,SAAgB,QAAQ,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAE9C;IAED,SAAgB,UAAU,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAEhD;IAED,SAAgB,WAAW,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAEjD;IAED,SAAgB,IAAI,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAEzC;IAED,SAAgB,OAAO,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAE7C;IAED,SAAgB,UAAU,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAEhE;IAED,SAAgB,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAOnE;IAED,SAAgB,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAOpE;IAED,SAAgB,UAAU,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAOlE;IAED,SAAgB,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,GAAG,SAAS,CAWtE;IAED,SAAgB,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,GAAG,SAAS,CAM/D;IAED,SAAgB,OAAO,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAO/D;IAED,SAAgB,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,SAAS,CAE9D;IAED,SAAgB,WAAW,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,GAAG,SAAS,CAEjE;IAED,SAAgB,OAAO,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS,CAE9D;IAED,SAAgB,SAAS,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,SAAS,CAOlE;CACF"}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { Vec2 } from '../math/vector2';
|
|
2
|
+
/**
|
|
3
|
+
* A set of
|
|
4
|
+
*/
|
|
1
5
|
export var Rect;
|
|
2
6
|
(function (Rect) {
|
|
3
7
|
function fromPoints(a, b) {
|
|
@@ -53,6 +57,10 @@ export var Rect;
|
|
|
53
57
|
return r[2] <= 0 || r[3] <= 0;
|
|
54
58
|
}
|
|
55
59
|
Rect.isEmpty = isEmpty;
|
|
60
|
+
function clampPoint(r, point) {
|
|
61
|
+
return Vec2.clamp(point, Rect.position(r), Rect.bottomRight(r));
|
|
62
|
+
}
|
|
63
|
+
Rect.clampPoint = clampPoint;
|
|
56
64
|
function containsPoint(r, point) {
|
|
57
65
|
return (point[0] >= r[0] &&
|
|
58
66
|
point[0] <= r[0] + r[2] &&
|