like2d 1.0.0 → 2.0.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/LICENSE +22 -0
- package/README.md +74 -42
- package/assets/logo-banner.svg +188 -0
- package/assets/logo-icon.svg +88 -0
- package/assets/logo.svg +188 -0
- package/dist/adapters/callback/index.d.ts +43 -0
- package/dist/adapters/callback/index.d.ts.map +1 -0
- package/dist/adapters/callback/index.js +80 -0
- package/dist/adapters/scene/index.d.ts +42 -0
- package/dist/adapters/scene/index.d.ts.map +1 -0
- package/dist/adapters/scene/index.js +112 -0
- package/dist/adapters/scene/scene.d.ts +18 -0
- package/dist/adapters/scene/scene.d.ts.map +1 -0
- package/dist/adapters/scene/startup-scene.d.ts +17 -0
- package/dist/adapters/scene/startup-scene.d.ts.map +1 -0
- package/dist/adapters/scene/startup-scene.js +41 -0
- package/dist/core/audio.d.ts +61 -0
- package/dist/core/audio.d.ts.map +1 -0
- package/dist/core/audio.js +226 -0
- package/dist/core/canvas-config.d.ts +22 -0
- package/dist/core/canvas-config.d.ts.map +1 -0
- package/dist/core/canvas-config.js +14 -0
- package/dist/core/canvas-manager.d.ts +26 -0
- package/dist/core/canvas-manager.d.ts.map +1 -0
- package/dist/core/canvas-manager.js +197 -0
- package/dist/core/events.d.ts +52 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/gamepad-button-map.d.ts.map +1 -0
- package/dist/core/gamepad-buttons.d.ts +23 -0
- package/dist/core/gamepad-buttons.d.ts.map +1 -0
- package/dist/core/gamepad-buttons.js +36 -0
- package/dist/core/gamepad-db.d.ts.map +1 -0
- package/dist/{gamepad-mapping.d.ts → core/gamepad-mapping.d.ts} +3 -15
- package/dist/core/gamepad-mapping.d.ts.map +1 -0
- package/dist/core/gamepad-mapping.js +223 -0
- package/dist/{gamepad.d.ts → core/gamepad.d.ts} +22 -17
- package/dist/core/gamepad.d.ts.map +1 -0
- package/dist/{gamepad.js → core/gamepad.js} +91 -70
- package/dist/{graphics.d.ts → core/graphics.d.ts} +2 -8
- package/dist/core/graphics.d.ts.map +1 -0
- package/dist/{graphics.js → core/graphics.js} +4 -41
- package/dist/core/input-state.d.ts.map +1 -0
- package/dist/{input.d.ts → core/input.d.ts} +11 -14
- package/dist/core/input.d.ts.map +1 -0
- package/dist/{input.js → core/input.js} +31 -41
- package/dist/core/keyboard.d.ts +15 -0
- package/dist/core/keyboard.d.ts.map +1 -0
- package/dist/core/keyboard.js +70 -0
- package/dist/core/mouse.d.ts +29 -0
- package/dist/core/mouse.d.ts.map +1 -0
- package/dist/core/mouse.js +130 -0
- package/dist/{rect.d.ts → core/rect.d.ts} +1 -2
- package/dist/core/rect.d.ts.map +1 -0
- package/dist/{rect.js → core/rect.js} +24 -28
- package/dist/{timer.d.ts → core/timer.d.ts} +0 -1
- package/dist/core/timer.d.ts.map +1 -0
- package/dist/{timer.js → core/timer.js} +0 -1
- package/dist/{vector2.d.ts → core/vector2.d.ts} +4 -10
- package/dist/core/vector2.d.ts.map +1 -0
- package/dist/{vector2.js → core/vector2.js} +40 -40
- package/dist/engine.d.ts +42 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +154 -0
- package/dist/index.d.ts +38 -44
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -250
- package/package.json +9 -23
- package/dist/audio.d.ts +0 -52
- package/dist/audio.d.ts.map +0 -1
- package/dist/audio.js +0 -250
- package/dist/events.d.ts +0 -36
- package/dist/events.d.ts.map +0 -1
- package/dist/gamepad-button-map.d.ts.map +0 -1
- package/dist/gamepad-db.d.ts.map +0 -1
- package/dist/gamepad-mapping.d.ts.map +0 -1
- package/dist/gamepad-mapping.js +0 -191
- package/dist/gamepad.d.ts.map +0 -1
- package/dist/graphics.d.ts.map +0 -1
- package/dist/input-state.d.ts.map +0 -1
- package/dist/input.d.ts.map +0 -1
- package/dist/keyboard.d.ts +0 -9
- package/dist/keyboard.d.ts.map +0 -1
- package/dist/keyboard.js +0 -33
- package/dist/mouse.d.ts +0 -20
- package/dist/mouse.d.ts.map +0 -1
- package/dist/mouse.js +0 -84
- package/dist/rect.d.ts.map +0 -1
- package/dist/scene.d.ts +0 -10
- package/dist/scene.d.ts.map +0 -1
- package/dist/timer.d.ts.map +0 -1
- package/dist/vector2.d.ts.map +0 -1
- /package/dist/{scene.js → adapters/scene/scene.js} +0 -0
- /package/dist/{events.js → core/events.js} +0 -0
- /package/dist/{gamepad-button-map.d.ts → core/gamepad-button-map.d.ts} +0 -0
- /package/dist/{gamepad-button-map.js → core/gamepad-button-map.js} +0 -0
- /package/dist/{gamepad-db.d.ts → core/gamepad-db.d.ts} +0 -0
- /package/dist/{gamepad-db.js → core/gamepad-db.js} +0 -0
- /package/dist/{input-state.d.ts → core/input-state.d.ts} +0 -0
- /package/dist/{input-state.js → core/input-state.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/callback/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,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,eAAO,IAAI,QAAQ,EAAE,QAAQ,CAAC;AAC9B,eAAO,MAAM,KAAK,OAAc,CAAC;AACjC,eAAO,MAAM,KAAK,OAAc,CAAC;AACjC,eAAO,IAAI,QAAQ,EAAE,QAAQ,CAAC;AAC9B,eAAO,IAAI,KAAK,EAAE,KAAK,CAAC;AACxB,eAAO,IAAI,OAAO,EAAE,OAAO,CAAC;AAC5B,eAAO,IAAI,KAAK,EAAE,KAAK,CAAC;AAIxB,eAAO,MAAM,IAAI;UACI,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;YACtB,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS;UACpC,CAAC,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC,GAAG,SAAS;YAC/C,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS;gBAC1E,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS;iBACxD,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS;kBACxD,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS;mBAC3D,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS;oBAC3D,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS;qBACtD,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS;mBACzD,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS;oBACrC,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS;iBACzC,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,SAAS;wBAEhD,IAAI;uBAIL,YAAY,GAAG,IAAI;oBAIhB,WAAW;eAyBtB,IAAI;CAkBhB,CAAC;AAEF,OAAO,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
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 { 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
|
+
toggleFullscreen() {
|
|
37
|
+
engine?.toggleFullscreen();
|
|
38
|
+
},
|
|
39
|
+
setScaling(config) {
|
|
40
|
+
engine?.setScaling(config);
|
|
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 };
|
|
@@ -0,0 +1,42 @@
|
|
|
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 { Scene } from './scene';
|
|
9
|
+
import type { CanvasConfig } from '../../core/canvas-config';
|
|
10
|
+
import { StartupScene } from './startup-scene';
|
|
11
|
+
export { Graphics, ImageHandle } from '../../core/graphics';
|
|
12
|
+
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 { CanvasConfig } from '../../core/canvas-config';
|
|
25
|
+
export { calcFixedScale } from '../../core/canvas-config';
|
|
26
|
+
export declare class SceneRunner {
|
|
27
|
+
private engine;
|
|
28
|
+
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
|
+
constructor(container: HTMLElement);
|
|
37
|
+
setScaling(config: CanvasConfig): void;
|
|
38
|
+
setScene(scene: Scene): void;
|
|
39
|
+
start(scene: Scene): Promise<void>;
|
|
40
|
+
dispose(): void;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,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,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,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,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAItC,QAAQ,CAAC,KAAK,EAAE,KAAK;IAKf,KAAK,CAAC,KAAK,EAAE,KAAK;IAiBxB,OAAO,IAAI,IAAI;CAKhB"}
|
|
@@ -0,0 +1,112 @@
|
|
|
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 { Engine } from '../../engine';
|
|
9
|
+
import { StartupScene } from './startup-scene';
|
|
10
|
+
export { Graphics, ImageHandle } from '../../core/graphics';
|
|
11
|
+
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';
|
|
21
|
+
export class SceneRunner {
|
|
22
|
+
constructor(container) {
|
|
23
|
+
Object.defineProperty(this, "engine", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
writable: true,
|
|
27
|
+
value: void 0
|
|
28
|
+
});
|
|
29
|
+
Object.defineProperty(this, "scene", {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
configurable: true,
|
|
32
|
+
writable: true,
|
|
33
|
+
value: null
|
|
34
|
+
});
|
|
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", {
|
|
72
|
+
enumerable: true,
|
|
73
|
+
configurable: true,
|
|
74
|
+
writable: true,
|
|
75
|
+
value: void 0
|
|
76
|
+
});
|
|
77
|
+
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
|
+
setScaling(config) {
|
|
87
|
+
this.engine.setScaling(config);
|
|
88
|
+
}
|
|
89
|
+
setScene(scene) {
|
|
90
|
+
this.scene = scene;
|
|
91
|
+
this.scene.load?.();
|
|
92
|
+
}
|
|
93
|
+
async start(scene) {
|
|
94
|
+
this.setScene(scene);
|
|
95
|
+
this.engine.setDeps({ graphics: this.graphics, input: this.input, timer: this.timer, audio: this.audio, keyboard: this.keyboard, mouse: this.mouse, gamepad: this.gamepad });
|
|
96
|
+
await this.gamepad.init();
|
|
97
|
+
this.engine.start((event) => {
|
|
98
|
+
// 1. handleEvent runs first
|
|
99
|
+
this.scene?.handleEvent?.(event);
|
|
100
|
+
// 2. Direct handlers
|
|
101
|
+
const handler = this.scene?.[event.type];
|
|
102
|
+
if (handler) {
|
|
103
|
+
handler.apply(this.scene, event.args);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
dispose() {
|
|
108
|
+
this.engine.stop();
|
|
109
|
+
this.engine.dispose();
|
|
110
|
+
this.scene = null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Vector2 } from '../../core/vector2';
|
|
2
|
+
import type { Like2DEvent } from '../../core/events';
|
|
3
|
+
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;
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=scene.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Like2DEvent } from '../../core/events';
|
|
2
|
+
import type { Scene } from './scene';
|
|
3
|
+
import type { Graphics } from '../../core/graphics';
|
|
4
|
+
export type StartupSceneConfig = {
|
|
5
|
+
nextScene: Scene;
|
|
6
|
+
draw?: (g: Graphics, canvas: HTMLCanvasElement) => void;
|
|
7
|
+
};
|
|
8
|
+
export declare class StartupScene implements Scene {
|
|
9
|
+
private graphics;
|
|
10
|
+
private config;
|
|
11
|
+
private onStart;
|
|
12
|
+
private started;
|
|
13
|
+
constructor(graphics: Graphics, config: StartupSceneConfig, onStart: () => void);
|
|
14
|
+
draw(canvas: HTMLCanvasElement): void;
|
|
15
|
+
handleEvent(event: Like2DEvent): void;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=startup-scene.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"startup-scene.d.ts","sourceRoot":"","sources":["../../../src/adapters/scene/startup-scene.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,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;CACzD,CAAC;AAMF,qBAAa,YAAa,YAAW,KAAK;IAItC,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,OAAO;IALjB,OAAO,CAAC,OAAO,CAAS;gBAGd,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,MAAM,IAAI;IAK7B,IAAI,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAIrC,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;CAMtC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
function defaultDraw(g, canvas) {
|
|
2
|
+
g.print('white', 'Click to Start', [canvas.width / 2, canvas.height / 2], { align: 'center' });
|
|
3
|
+
}
|
|
4
|
+
export class StartupScene {
|
|
5
|
+
constructor(graphics, config, onStart) {
|
|
6
|
+
Object.defineProperty(this, "graphics", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
configurable: true,
|
|
9
|
+
writable: true,
|
|
10
|
+
value: graphics
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(this, "config", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
configurable: true,
|
|
15
|
+
writable: true,
|
|
16
|
+
value: config
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(this, "onStart", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
configurable: true,
|
|
21
|
+
writable: true,
|
|
22
|
+
value: onStart
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(this, "started", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
configurable: true,
|
|
27
|
+
writable: true,
|
|
28
|
+
value: false
|
|
29
|
+
});
|
|
30
|
+
this.graphics.setBackgroundColor('black');
|
|
31
|
+
}
|
|
32
|
+
draw(canvas) {
|
|
33
|
+
(this.config.draw ?? defaultDraw)(this.graphics, canvas);
|
|
34
|
+
}
|
|
35
|
+
handleEvent(event) {
|
|
36
|
+
if (event.type === 'mousepressed' && !this.started) {
|
|
37
|
+
this.started = true;
|
|
38
|
+
this.onStart();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** The audio module performs a few things:
|
|
2
|
+
*
|
|
3
|
+
* ## Make audio resources behave as if synchronous
|
|
4
|
+
* Functions like playback and seeking are deferred until the sound is loaded.
|
|
5
|
+
*
|
|
6
|
+
* ## Track and give global control to all audio objects
|
|
7
|
+
* Start, stop, or set global volume for every currently playing sound.
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
export type SourceOptions = {
|
|
11
|
+
volume?: number;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Handle to a loaded audio resource.
|
|
15
|
+
* Use `play()`, `stop()`, `pause()`, `resume()` for playback control.
|
|
16
|
+
* Access the underlying HTMLAudioElement via `source.audio` for looping,
|
|
17
|
+
* pitch, etc. Note: Use `source.setVolume()` instead of setting
|
|
18
|
+
* `source.audio.volume` directly to ensure global volume scaling works correctly.
|
|
19
|
+
*/
|
|
20
|
+
export declare class Source {
|
|
21
|
+
readonly path: string;
|
|
22
|
+
/** Underlying HTMLAudioElement. Modify directly for looping, pitch, etc. Use methods for playback control. Avoid setting volume directly. */
|
|
23
|
+
readonly audio: HTMLAudioElement;
|
|
24
|
+
readonly options: Required<SourceOptions>;
|
|
25
|
+
/** Resolves when the audio is loaded and ready to play. */
|
|
26
|
+
readonly ready: Promise<void>;
|
|
27
|
+
private loadState;
|
|
28
|
+
private audioRef;
|
|
29
|
+
constructor(path: string, audioRef: Audio, options?: SourceOptions);
|
|
30
|
+
isReady(): boolean;
|
|
31
|
+
play(): void;
|
|
32
|
+
stop(): void;
|
|
33
|
+
pause(): void;
|
|
34
|
+
resume(): void;
|
|
35
|
+
seek(position: number): void;
|
|
36
|
+
tell(): number;
|
|
37
|
+
isPlaying(): boolean;
|
|
38
|
+
isPaused(): boolean;
|
|
39
|
+
isStopped(): boolean;
|
|
40
|
+
/** Set volume (0-1). Applies global volume scaling. Prefer this over `source.audio.volume`. */
|
|
41
|
+
setVolume(volume: number): void;
|
|
42
|
+
getVolume(): number;
|
|
43
|
+
getDuration(): number;
|
|
44
|
+
}
|
|
45
|
+
export declare class Audio {
|
|
46
|
+
private sources;
|
|
47
|
+
private globalVolume;
|
|
48
|
+
newSource(path: string, options?: SourceOptions): Source;
|
|
49
|
+
/** Get all audio sources -- note that sources are tracked
|
|
50
|
+
* using weak references, and storing this list can cause
|
|
51
|
+
* a memory leak.
|
|
52
|
+
*/
|
|
53
|
+
private getAllSources;
|
|
54
|
+
stopAll(): void;
|
|
55
|
+
pauseAll(): void;
|
|
56
|
+
resumeAll(): void;
|
|
57
|
+
setVolume(volume: number): void;
|
|
58
|
+
getVolume(): number;
|
|
59
|
+
clone(source: Source): Source;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=audio.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../../src/core/audio.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAA;AAMD;;;;;;GAMG;AACH,qBAAa,MAAM;IACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6IAA6I;IAC7I,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC1C,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,aAAkB;IAmCtE,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,qBAAa,KAAK;IAChB,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,YAAY,CAAK;IAEzB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM;IAMxD;;;QAGI;IACJ,OAAO,CAAC,aAAa;IASrB,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,MAAM,GAAG,MAAM;CAG9B"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/** The audio module performs a few things:
|
|
2
|
+
*
|
|
3
|
+
* ## Make audio resources behave as if synchronous
|
|
4
|
+
* Functions like playback and seeking are deferred until the sound is loaded.
|
|
5
|
+
*
|
|
6
|
+
* ## Track and give global control to all audio objects
|
|
7
|
+
* Start, stop, or set global volume for every currently playing sound.
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Handle to a loaded audio resource.
|
|
12
|
+
* Use `play()`, `stop()`, `pause()`, `resume()` for playback control.
|
|
13
|
+
* Access the underlying HTMLAudioElement via `source.audio` for looping,
|
|
14
|
+
* pitch, etc. Note: Use `source.setVolume()` instead of setting
|
|
15
|
+
* `source.audio.volume` directly to ensure global volume scaling works correctly.
|
|
16
|
+
*/
|
|
17
|
+
export class Source {
|
|
18
|
+
constructor(path, audioRef, options = {}) {
|
|
19
|
+
Object.defineProperty(this, "path", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
configurable: true,
|
|
22
|
+
writable: true,
|
|
23
|
+
value: void 0
|
|
24
|
+
});
|
|
25
|
+
/** Underlying HTMLAudioElement. Modify directly for looping, pitch, etc. Use methods for playback control. Avoid setting volume directly. */
|
|
26
|
+
Object.defineProperty(this, "audio", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
configurable: true,
|
|
29
|
+
writable: true,
|
|
30
|
+
value: void 0
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(this, "options", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
writable: true,
|
|
36
|
+
value: void 0
|
|
37
|
+
});
|
|
38
|
+
/** Resolves when the audio is loaded and ready to play. */
|
|
39
|
+
Object.defineProperty(this, "ready", {
|
|
40
|
+
enumerable: true,
|
|
41
|
+
configurable: true,
|
|
42
|
+
writable: true,
|
|
43
|
+
value: void 0
|
|
44
|
+
});
|
|
45
|
+
Object.defineProperty(this, "loadState", {
|
|
46
|
+
enumerable: true,
|
|
47
|
+
configurable: true,
|
|
48
|
+
writable: true,
|
|
49
|
+
value: { loaded: false, pendingPlay: false, pendingSeek: 0 }
|
|
50
|
+
});
|
|
51
|
+
Object.defineProperty(this, "audioRef", {
|
|
52
|
+
enumerable: true,
|
|
53
|
+
configurable: true,
|
|
54
|
+
writable: true,
|
|
55
|
+
value: void 0
|
|
56
|
+
});
|
|
57
|
+
this.path = path;
|
|
58
|
+
this.audioRef = audioRef;
|
|
59
|
+
this.audio = document.createElement('audio');
|
|
60
|
+
this.audio.src = path;
|
|
61
|
+
this.options = {
|
|
62
|
+
volume: Math.max(0, Math.min(1, options.volume ?? 1))
|
|
63
|
+
};
|
|
64
|
+
this.audio.volume = this.options.volume * audioRef.getVolume();
|
|
65
|
+
this.ready = new Promise((resolve, reject) => {
|
|
66
|
+
this.audio.oncanplaythrough = () => {
|
|
67
|
+
if (this.loadState.loaded)
|
|
68
|
+
return;
|
|
69
|
+
const { pendingPlay, pendingSeek } = this.loadState;
|
|
70
|
+
this.loadState = { loaded: true };
|
|
71
|
+
this.audio.currentTime = pendingSeek;
|
|
72
|
+
if (pendingPlay) {
|
|
73
|
+
this.audio.play()?.catch(() => {
|
|
74
|
+
// Play failed (autoplay policy) - reset so user can retry
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
resolve();
|
|
78
|
+
};
|
|
79
|
+
this.audio.onerror = () => reject(new Error(`Failed to load audio: ${path}`));
|
|
80
|
+
// Handle audio that is already loaded (cached) when we attach the listener
|
|
81
|
+
if (this.audio.readyState >= 3) {
|
|
82
|
+
this.loadState = { loaded: true };
|
|
83
|
+
resolve();
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
isReady() {
|
|
88
|
+
return this.loadState.loaded;
|
|
89
|
+
}
|
|
90
|
+
play() {
|
|
91
|
+
if (this.loadState.loaded) {
|
|
92
|
+
this.audio.play()?.catch(() => {
|
|
93
|
+
// Play failed (autoplay policy) - ignore
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
this.loadState.pendingPlay = true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
stop() {
|
|
101
|
+
if (this.loadState.loaded) {
|
|
102
|
+
this.audio.pause();
|
|
103
|
+
this.audio.currentTime = 0;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
this.loadState.pendingPlay = false;
|
|
107
|
+
this.loadState.pendingSeek = 0;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
pause() {
|
|
111
|
+
if (this.loadState.loaded) {
|
|
112
|
+
this.audio.pause();
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
this.loadState.pendingPlay = false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
resume() {
|
|
119
|
+
if (this.loadState.loaded) {
|
|
120
|
+
if (this.audio.paused) {
|
|
121
|
+
this.audio.play()?.catch(() => {
|
|
122
|
+
// Play failed (autoplay policy, etc.) - ignore
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
this.loadState.pendingPlay = true;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
seek(position) {
|
|
131
|
+
if (this.loadState.loaded) {
|
|
132
|
+
this.audio.currentTime = position;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
this.loadState.pendingSeek = position;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
tell() {
|
|
139
|
+
if (this.loadState.loaded)
|
|
140
|
+
return this.audio.currentTime;
|
|
141
|
+
return this.loadState.pendingSeek;
|
|
142
|
+
}
|
|
143
|
+
isPlaying() {
|
|
144
|
+
if (this.loadState.loaded)
|
|
145
|
+
return !this.audio.paused && !this.audio.ended;
|
|
146
|
+
return this.loadState.pendingPlay;
|
|
147
|
+
}
|
|
148
|
+
isPaused() {
|
|
149
|
+
if (this.loadState.loaded)
|
|
150
|
+
return this.audio.paused;
|
|
151
|
+
return !this.loadState.pendingPlay;
|
|
152
|
+
}
|
|
153
|
+
isStopped() {
|
|
154
|
+
if (this.loadState.loaded)
|
|
155
|
+
return this.audio.paused && this.audio.currentTime === 0;
|
|
156
|
+
return !this.loadState.pendingPlay && this.loadState.pendingSeek === 0;
|
|
157
|
+
}
|
|
158
|
+
/** Set volume (0-1). Applies global volume scaling. Prefer this over `source.audio.volume`. */
|
|
159
|
+
setVolume(volume) {
|
|
160
|
+
this.options.volume = Math.max(0, Math.min(1, volume));
|
|
161
|
+
this.audio.volume = this.options.volume * this.audioRef.getVolume();
|
|
162
|
+
}
|
|
163
|
+
getVolume() {
|
|
164
|
+
return this.options.volume;
|
|
165
|
+
}
|
|
166
|
+
getDuration() {
|
|
167
|
+
if (this.loadState.loaded)
|
|
168
|
+
return this.audio.duration;
|
|
169
|
+
return 0;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
export class Audio {
|
|
173
|
+
constructor() {
|
|
174
|
+
Object.defineProperty(this, "sources", {
|
|
175
|
+
enumerable: true,
|
|
176
|
+
configurable: true,
|
|
177
|
+
writable: true,
|
|
178
|
+
value: []
|
|
179
|
+
});
|
|
180
|
+
Object.defineProperty(this, "globalVolume", {
|
|
181
|
+
enumerable: true,
|
|
182
|
+
configurable: true,
|
|
183
|
+
writable: true,
|
|
184
|
+
value: 1
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
newSource(path, options) {
|
|
188
|
+
const source = new Source(path, this, options);
|
|
189
|
+
this.sources.push(new WeakRef(source));
|
|
190
|
+
return source;
|
|
191
|
+
}
|
|
192
|
+
/** Get all audio sources -- note that sources are tracked
|
|
193
|
+
* using weak references, and storing this list can cause
|
|
194
|
+
* a memory leak.
|
|
195
|
+
*/
|
|
196
|
+
getAllSources() {
|
|
197
|
+
const active = [];
|
|
198
|
+
for (const sourceRef of this.sources) {
|
|
199
|
+
const source = sourceRef.deref();
|
|
200
|
+
if (source)
|
|
201
|
+
active.push(source);
|
|
202
|
+
}
|
|
203
|
+
return active;
|
|
204
|
+
}
|
|
205
|
+
stopAll() {
|
|
206
|
+
this.getAllSources().forEach(s => s.stop());
|
|
207
|
+
}
|
|
208
|
+
pauseAll() {
|
|
209
|
+
this.getAllSources().forEach(s => s.pause());
|
|
210
|
+
}
|
|
211
|
+
resumeAll() {
|
|
212
|
+
this.getAllSources().forEach(s => s.resume());
|
|
213
|
+
}
|
|
214
|
+
setVolume(volume) {
|
|
215
|
+
this.globalVolume = Math.max(0, Math.min(1, volume));
|
|
216
|
+
this.getAllSources().forEach(s => {
|
|
217
|
+
s.audio.volume = s.options.volume * this.globalVolume;
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
getVolume() {
|
|
221
|
+
return this.globalVolume;
|
|
222
|
+
}
|
|
223
|
+
clone(source) {
|
|
224
|
+
return this.newSource(source.path, { ...source.options });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Vector2 } from './vector2';
|
|
2
|
+
export type CanvasMode = 'fixed' | 'native';
|
|
3
|
+
export type CanvasConfig = {
|
|
4
|
+
mode: 'fixed';
|
|
5
|
+
size: Vector2;
|
|
6
|
+
pixelArt?: boolean;
|
|
7
|
+
} | {
|
|
8
|
+
mode: 'native';
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Calculate the scale and offset for rendering fixed-size content to a target canvas.
|
|
12
|
+
* This is useful when you want to render in "native" mode but maintain a fixed game resolution.
|
|
13
|
+
*
|
|
14
|
+
* @param canvasSize - The actual canvas size in pixels
|
|
15
|
+
* @param gameSize - The desired game resolution (fixed size)
|
|
16
|
+
* @returns Object containing the scale factor and offset for centering
|
|
17
|
+
*/
|
|
18
|
+
export declare function calcFixedScale(canvasSize: Vector2, gameSize: Vector2): {
|
|
19
|
+
scale: number;
|
|
20
|
+
offset: Vector2;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=canvas-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-config.d.ts","sourceRoot":"","sources":["../../src/core/canvas-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE5C,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEvB;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAKzG"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calculate the scale and offset for rendering fixed-size content to a target canvas.
|
|
3
|
+
* This is useful when you want to render in "native" mode but maintain a fixed game resolution.
|
|
4
|
+
*
|
|
5
|
+
* @param canvasSize - The actual canvas size in pixels
|
|
6
|
+
* @param gameSize - The desired game resolution (fixed size)
|
|
7
|
+
* @returns Object containing the scale factor and offset for centering
|
|
8
|
+
*/
|
|
9
|
+
export function calcFixedScale(canvasSize, gameSize) {
|
|
10
|
+
const scale = Math.min(canvasSize[0] / gameSize[0], canvasSize[1] / gameSize[1]);
|
|
11
|
+
const scaledGame = [gameSize[0] * scale, gameSize[1] * scale];
|
|
12
|
+
const offset = [(canvasSize[0] - scaledGame[0]) * 0.5, (canvasSize[1] - scaledGame[1]) * 0.5];
|
|
13
|
+
return { scale, offset };
|
|
14
|
+
}
|