like2d 2.9.0 → 2.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +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/{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/controllerdb.json +1 -0
- package/dist/input/gamepad-mapping.d.ts +119 -0
- package/dist/input/gamepad-mapping.d.ts.map +1 -0
- package/dist/input/gamepad-mapping.js +114 -0
- package/dist/input/gamepad.d.ts +73 -0
- package/dist/input/gamepad.d.ts.map +1 -0
- package/dist/input/gamepad.js +291 -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 +163 -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 +30 -0
- package/dist/prefab-scenes/mapGamepad.d.ts.map +1 -0
- package/dist/prefab-scenes/mapGamepad.js +192 -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 +21 -12
- 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/dist/math/vector2.js
CHANGED
|
@@ -1,129 +1,111 @@
|
|
|
1
|
-
import { mod as mmod } from ".";
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
1
|
+
import { mod as mmod } from "./index.js";
|
|
2
|
+
/**
|
|
3
|
+
* According to benchmarks, constructing funcs with these helpers is just as fast as loose coords in v8.
|
|
4
|
+
* Why not, then?
|
|
5
|
+
* If you're writing hyper-optimized Vector2 code, just use loose math anyway
|
|
6
|
+
* -- it will likely logically optimize down further, if you do the algebra.
|
|
7
|
+
*/
|
|
8
|
+
/** @see {@link Vec2.map} */
|
|
9
|
+
function map2x1(op) {
|
|
10
|
+
return (a) => [op(a[0]), op(a[1])];
|
|
11
|
+
}
|
|
12
|
+
/** @see {@link Vec2.map2} */
|
|
13
|
+
function map2x2(op) {
|
|
14
|
+
return (a, b) => typeof b == "object" && b instanceof Array
|
|
15
|
+
? [op(a[0], b[0]), op(a[1], b[1])]
|
|
16
|
+
: [op(a[0], b), op(a[1], b)];
|
|
17
|
+
}
|
|
18
|
+
export const Vec2 = {
|
|
19
|
+
/**
|
|
20
|
+
* Turn a unary function into a pair-wise unary function.
|
|
21
|
+
* @param op A function that takes one arg and returns something.
|
|
22
|
+
* @returns A function that takes a pair such as `[number, number]` (Vector2) and transforms it with `op`.
|
|
23
|
+
*/
|
|
24
|
+
map: map2x1,
|
|
25
|
+
/**
|
|
26
|
+
* Turn a binary function into a pair-wise binary function, for example one that operates on two `Vector2`s.
|
|
27
|
+
* @param op A function that takes two values and calculates one.
|
|
28
|
+
* @returns A function that runs `op` pair-wise on both arguments, constructing a new pair.
|
|
29
|
+
*/
|
|
30
|
+
map2: map2x2,
|
|
31
|
+
add: map2x2((a, b) => a + b),
|
|
32
|
+
sub: map2x2((a, b) => a - b),
|
|
33
|
+
mul: map2x2((a, b) => a * b),
|
|
34
|
+
div: map2x2((a, b) => a / b),
|
|
35
|
+
/** Returns the maximum of two coordinates,
|
|
36
|
+
* i.e. the lower right corner of a bounding box containing them. */
|
|
37
|
+
max: map2x2(Math.max),
|
|
38
|
+
/** Returns the minimum of two coordinates,
|
|
39
|
+
* i.e. the upper left corner of a bounding box containing them. */
|
|
40
|
+
min: map2x2(Math.min),
|
|
41
|
+
/** Apply a true modulus (i.e. where -1 % 3 == 2) to a Vector2.
|
|
42
|
+
*
|
|
43
|
+
* For JS-style modulus (who wants that?) use `Vec2.map2((a,b) => a % b)` */
|
|
44
|
+
mod: map2x2(mmod),
|
|
45
|
+
/** Apply deep (not referential) equality to a pair of Vec2s.
|
|
46
|
+
* @param epsilon Tolerance factor for inexact matches.
|
|
47
|
+
*/
|
|
48
|
+
eq(v, other, epsilon) {
|
|
49
|
+
return epsilon == 0
|
|
50
|
+
? v[0] == other[0] && v[1] == other[1]
|
|
51
|
+
: Vec2.lengthSq(Vec2.sub(v, other)) < epsilon ** 2;
|
|
52
|
+
},
|
|
53
|
+
dot(a, b) {
|
|
39
54
|
return a[0] * b[0] + a[1] * b[1];
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function cross(a, b) {
|
|
55
|
+
},
|
|
56
|
+
cross(a, b) {
|
|
43
57
|
return a[0] * b[1] - a[1] * b[0];
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function lengthSq(v) {
|
|
58
|
+
},
|
|
59
|
+
lengthSq(v) {
|
|
47
60
|
return v[0] * v[0] + v[1] * v[1];
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const len = length(v);
|
|
61
|
+
},
|
|
62
|
+
length(v) {
|
|
63
|
+
return Math.sqrt(this.lengthSq(v));
|
|
64
|
+
},
|
|
65
|
+
/** Set the length of a Vector2 to 1.0 while preserving its angle. */
|
|
66
|
+
normalize(v) {
|
|
67
|
+
const len = this.length(v);
|
|
56
68
|
if (len === 0)
|
|
57
69
|
return [0, 0];
|
|
58
|
-
return div(v, len);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
Vec2.distance = distance;
|
|
65
|
-
function lerp(a, b, t) {
|
|
70
|
+
return this.div(v, len);
|
|
71
|
+
},
|
|
72
|
+
distance(a, b) {
|
|
73
|
+
return this.length(this.sub(a, b));
|
|
74
|
+
},
|
|
75
|
+
lerp(a, b, t) {
|
|
66
76
|
return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t];
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function toPolar(v) {
|
|
77
|
+
},
|
|
78
|
+
toPolar(v) {
|
|
70
79
|
return {
|
|
71
|
-
r:
|
|
72
|
-
angle:
|
|
80
|
+
r: this.length(v),
|
|
81
|
+
angle: this.angle(v),
|
|
73
82
|
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function fromPolar(r, angle) {
|
|
83
|
+
},
|
|
84
|
+
fromPolar(r, angle) {
|
|
77
85
|
return [r * Math.cos(angle), r * Math.sin(angle)];
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function angle(v) {
|
|
86
|
+
},
|
|
87
|
+
angle(v) {
|
|
81
88
|
return Math.atan2(v[1], v[0]);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function rotate(v, angle) {
|
|
89
|
+
},
|
|
90
|
+
rotate(v, angle) {
|
|
85
91
|
const cos = Math.cos(angle);
|
|
86
92
|
const sin = Math.sin(angle);
|
|
87
93
|
return [v[0] * cos - v[1] * sin, v[0] * sin + v[1] * cos];
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
function floor(v) {
|
|
95
|
-
return [Math.floor(v[0]), Math.floor(v[1])];
|
|
96
|
-
}
|
|
97
|
-
Vec2.floor = floor;
|
|
98
|
-
function ceil(v) {
|
|
99
|
-
return [Math.ceil(v[0]), Math.ceil(v[1])];
|
|
100
|
-
}
|
|
101
|
-
Vec2.ceil = ceil;
|
|
102
|
-
function round(v) {
|
|
103
|
-
return [Math.round(v[0]), Math.round(v[1])];
|
|
104
|
-
}
|
|
105
|
-
Vec2.round = round;
|
|
106
|
-
function min(a, b) {
|
|
107
|
-
return [Math.min(a[0], b[0]), Math.min(a[1], b[1])];
|
|
108
|
-
}
|
|
109
|
-
Vec2.min = min;
|
|
110
|
-
function max(a, b) {
|
|
111
|
-
return [Math.max(a[0], b[0]), Math.max(a[1], b[1])];
|
|
112
|
-
}
|
|
113
|
-
Vec2.max = max;
|
|
114
|
-
function clamp(v, min, max) {
|
|
94
|
+
},
|
|
95
|
+
negate: map2x1((a) => -a),
|
|
96
|
+
floor: map2x1(Math.floor),
|
|
97
|
+
ceil: map2x1(Math.ceil),
|
|
98
|
+
round: map2x1(Math.round),
|
|
99
|
+
clamp(v, min, max) {
|
|
115
100
|
return [
|
|
116
101
|
Math.max(min[0], Math.min(v[0], max[0])),
|
|
117
102
|
Math.max(min[1], Math.min(v[1], max[1])),
|
|
118
103
|
];
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function fromAngle(angle, len = 1) {
|
|
104
|
+
},
|
|
105
|
+
fromAngle(angle, len = 1) {
|
|
122
106
|
return [Math.cos(angle) * len, Math.sin(angle) * len];
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function zero() {
|
|
107
|
+
},
|
|
108
|
+
zero() {
|
|
126
109
|
return [0, 0];
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
})(Vec2 || (Vec2 = {}));
|
|
110
|
+
},
|
|
111
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prefab-scenes/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prefab-scenes/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Like } from "..";
|
|
2
|
+
import { type LikeButton } from "../input";
|
|
3
|
+
import { Scene } from "../scene";
|
|
4
|
+
export declare const buttonSetNES: Set<LikeButton>;
|
|
5
|
+
export declare const buttonSetGBA: Set<LikeButton>;
|
|
6
|
+
export declare const buttonSetSNES: Set<LikeButton>;
|
|
7
|
+
export declare const buttonSetPS1: Set<LikeButton>;
|
|
8
|
+
export declare const buttonSetAll: Set<LikeButton>;
|
|
9
|
+
export type MapMode = {
|
|
10
|
+
buttons: Set<LikeButton>;
|
|
11
|
+
stickCount: number;
|
|
12
|
+
};
|
|
13
|
+
export declare class MapGamepad implements Scene {
|
|
14
|
+
private mapMode;
|
|
15
|
+
private targetPad;
|
|
16
|
+
private next?;
|
|
17
|
+
private currentlyUnmapped;
|
|
18
|
+
private mapping;
|
|
19
|
+
private held?;
|
|
20
|
+
private alreadyMapped;
|
|
21
|
+
private frameWait;
|
|
22
|
+
constructor(mapMode: MapMode, targetPad: number, next?: Scene | undefined);
|
|
23
|
+
load(like: Like): void;
|
|
24
|
+
update(): void;
|
|
25
|
+
draw(like: Like): void;
|
|
26
|
+
gamepadpressed(like: Like, source: number, _name: LikeButton, num: number): void;
|
|
27
|
+
gamepadreleased(_like: Like, source: number, _name: LikeButton, num: number): void;
|
|
28
|
+
mousepressed(like: Like): void;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=mapGamepad.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapGamepad.d.ts","sourceRoot":"","sources":["../../src/prefab-scenes/mapGamepad.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,OAAO,EAAE,KAAK,UAAU,EAAkC,MAAM,UAAU,CAAC;AAE3E,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAyBjC,eAAO,MAAM,YAAY,iBAA4C,CAAC;AACtE,eAAO,MAAM,YAAY,iBAA6C,CAAC;AACvE,eAAO,MAAM,aAAa,iBAA6C,CAAC;AACxE,eAAO,MAAM,YAAY,iBAA6C,CAAC;AACvE,eAAO,MAAM,YAAY,iBAAgC,CAAC;AA6D1D,MAAM,MAAM,OAAO,GAAG;IACpB,OAAO,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,qBAAa,UAAW,YAAW,KAAK;IAQpC,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,IAAI,CAAC;IATf,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,IAAI,CAAC,CAAa;IAC1B,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,SAAS,CAAK;gBAGZ,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,KAAK,YAAA;IAGtB,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IActB,MAAM,IAAI,IAAI;IAId,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAqCtB,cAAc,CACZ,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,MAAM,GACV,IAAI;IAaP,eAAe,CACb,KAAK,EAAE,IAAI,EACX,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,MAAM,GACV,IAAI;IAOP,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;CAG/B"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { defaultMapping } from "../input";
|
|
2
|
+
const mapOrder = [
|
|
3
|
+
"BRight",
|
|
4
|
+
"BBottom",
|
|
5
|
+
"Up",
|
|
6
|
+
"Down",
|
|
7
|
+
"Left",
|
|
8
|
+
"Right",
|
|
9
|
+
"MenuLeft",
|
|
10
|
+
"MenuRight",
|
|
11
|
+
// 8: NES buttons
|
|
12
|
+
"L1",
|
|
13
|
+
"R1",
|
|
14
|
+
// 10: GBA buttons
|
|
15
|
+
"BLeft",
|
|
16
|
+
"BTop",
|
|
17
|
+
// 12: SNES buttons
|
|
18
|
+
"L2",
|
|
19
|
+
"R2",
|
|
20
|
+
// 14: PS1 buttons
|
|
21
|
+
"LeftStick",
|
|
22
|
+
"RightStick",
|
|
23
|
+
];
|
|
24
|
+
export const buttonSetNES = new Set(mapOrder.slice(0, 8));
|
|
25
|
+
export const buttonSetGBA = new Set(mapOrder.slice(0, 10));
|
|
26
|
+
export const buttonSetSNES = new Set(mapOrder.slice(0, 12));
|
|
27
|
+
export const buttonSetPS1 = new Set(mapOrder.slice(0, 14));
|
|
28
|
+
export const buttonSetAll = new Set(mapOrder);
|
|
29
|
+
const drawCircButt = (pos, size) => (like, color) => like.gfx.circle("fill", color, pos, size);
|
|
30
|
+
const drawDpadPart = (rot) => (like, color) => {
|
|
31
|
+
like.gfx.push();
|
|
32
|
+
like.gfx.translate([2.5, 6]);
|
|
33
|
+
like.gfx.rotate(rot);
|
|
34
|
+
like.gfx.rectangle("fill", color, [0.5, -0.5, 1.3, 1]);
|
|
35
|
+
like.gfx.pop();
|
|
36
|
+
};
|
|
37
|
+
const drawShoulder = (y, width, flip) => (like, color) => {
|
|
38
|
+
const r = 0.8;
|
|
39
|
+
const rectPos = [5 - width, y];
|
|
40
|
+
const circPos = [5 - width - r, y];
|
|
41
|
+
like.gfx.push();
|
|
42
|
+
if (flip) {
|
|
43
|
+
like.gfx.translate([16, 0]);
|
|
44
|
+
like.gfx.scale([-1, 1]);
|
|
45
|
+
}
|
|
46
|
+
like.gfx.circle("fill", color, circPos, r, { arc: [Math.PI, Math.PI * 3 / 2], center: false });
|
|
47
|
+
like.gfx.rectangle("fill", color, [...rectPos, width, r]);
|
|
48
|
+
like.gfx.pop();
|
|
49
|
+
};
|
|
50
|
+
// Buttons assume a centered resolution of 16x9px. Transforms exist for a reason lol.
|
|
51
|
+
// LLLLL . RRRRR
|
|
52
|
+
// LLLLLLLLL . RRRRRRRRR
|
|
53
|
+
// .
|
|
54
|
+
// DDD S . S B
|
|
55
|
+
// -.....DDD.....................................
|
|
56
|
+
// DDD DDD . B B
|
|
57
|
+
// DDD LS . RS
|
|
58
|
+
// DDD . B
|
|
59
|
+
// .
|
|
60
|
+
const buttonProps = {
|
|
61
|
+
BLeft: { draw: drawCircButt([12, 6], 0.8) },
|
|
62
|
+
BRight: { draw: drawCircButt([15, 6], 0.8) },
|
|
63
|
+
BTop: { draw: drawCircButt([13.5, 4.5], 0.8) },
|
|
64
|
+
BBottom: { draw: drawCircButt([13.5, 7.5], 0.8) },
|
|
65
|
+
MenuLeft: { draw: drawCircButt([6, 4], 0.5) },
|
|
66
|
+
MenuRight: { draw: drawCircButt([10, 4], 0.5) },
|
|
67
|
+
LeftStick: { draw: drawCircButt([6.5, 7], 1.4) },
|
|
68
|
+
RightStick: { draw: drawCircButt([9.5, 7], 1.4) },
|
|
69
|
+
L1: { draw: drawShoulder(2, 3, false) },
|
|
70
|
+
L2: { draw: drawShoulder(1, 2, false) },
|
|
71
|
+
R1: { draw: drawShoulder(2, 3, true) },
|
|
72
|
+
R2: { draw: drawShoulder(1, 2, true) },
|
|
73
|
+
Right: { draw: drawDpadPart(0) },
|
|
74
|
+
Up: { draw: drawDpadPart(-Math.PI / 2) },
|
|
75
|
+
Left: { draw: drawDpadPart(Math.PI) },
|
|
76
|
+
Down: { draw: drawDpadPart(Math.PI / 2) },
|
|
77
|
+
};
|
|
78
|
+
export class MapGamepad {
|
|
79
|
+
constructor(mapMode, targetPad, next) {
|
|
80
|
+
Object.defineProperty(this, "mapMode", {
|
|
81
|
+
enumerable: true,
|
|
82
|
+
configurable: true,
|
|
83
|
+
writable: true,
|
|
84
|
+
value: mapMode
|
|
85
|
+
});
|
|
86
|
+
Object.defineProperty(this, "targetPad", {
|
|
87
|
+
enumerable: true,
|
|
88
|
+
configurable: true,
|
|
89
|
+
writable: true,
|
|
90
|
+
value: targetPad
|
|
91
|
+
});
|
|
92
|
+
Object.defineProperty(this, "next", {
|
|
93
|
+
enumerable: true,
|
|
94
|
+
configurable: true,
|
|
95
|
+
writable: true,
|
|
96
|
+
value: next
|
|
97
|
+
});
|
|
98
|
+
Object.defineProperty(this, "currentlyUnmapped", {
|
|
99
|
+
enumerable: true,
|
|
100
|
+
configurable: true,
|
|
101
|
+
writable: true,
|
|
102
|
+
value: []
|
|
103
|
+
});
|
|
104
|
+
Object.defineProperty(this, "mapping", {
|
|
105
|
+
enumerable: true,
|
|
106
|
+
configurable: true,
|
|
107
|
+
writable: true,
|
|
108
|
+
value: void 0
|
|
109
|
+
});
|
|
110
|
+
Object.defineProperty(this, "held", {
|
|
111
|
+
enumerable: true,
|
|
112
|
+
configurable: true,
|
|
113
|
+
writable: true,
|
|
114
|
+
value: void 0
|
|
115
|
+
});
|
|
116
|
+
Object.defineProperty(this, "alreadyMapped", {
|
|
117
|
+
enumerable: true,
|
|
118
|
+
configurable: true,
|
|
119
|
+
writable: true,
|
|
120
|
+
value: new Set()
|
|
121
|
+
});
|
|
122
|
+
Object.defineProperty(this, "frameWait", {
|
|
123
|
+
enumerable: true,
|
|
124
|
+
configurable: true,
|
|
125
|
+
writable: true,
|
|
126
|
+
value: 0
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
load(like) {
|
|
130
|
+
this.frameWait = 10;
|
|
131
|
+
this.mapping = like.gamepad.getMapping(this.targetPad) ?? defaultMapping(2);
|
|
132
|
+
const alreadyMapped = new Set(Object.values(this.mapping.buttons));
|
|
133
|
+
for (const btn of mapOrder.reverse()) {
|
|
134
|
+
if (this.mapMode.buttons.has(btn) && !alreadyMapped.has(btn)) {
|
|
135
|
+
this.currentlyUnmapped.push(btn);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
like.canvas.setMode([320, 240]);
|
|
139
|
+
}
|
|
140
|
+
update() {
|
|
141
|
+
this.frameWait--;
|
|
142
|
+
}
|
|
143
|
+
draw(like) {
|
|
144
|
+
const centerText = {
|
|
145
|
+
font: "1px sans-serif",
|
|
146
|
+
align: "center",
|
|
147
|
+
width: 16,
|
|
148
|
+
};
|
|
149
|
+
const active = this.currentlyUnmapped.at(-1);
|
|
150
|
+
like.gfx.clear();
|
|
151
|
+
like.gfx.scale(20);
|
|
152
|
+
like.gfx.translate([0, 1]);
|
|
153
|
+
like.gfx.print("white", `Map gamepad ${this.targetPad}`, [8, 0.0], centerText);
|
|
154
|
+
for (const prop of this.mapMode.buttons.keys()) {
|
|
155
|
+
const color = this.held == prop
|
|
156
|
+
? "green"
|
|
157
|
+
: active == prop
|
|
158
|
+
? "red"
|
|
159
|
+
: this.mapMode.buttons.has(prop)
|
|
160
|
+
? "gray"
|
|
161
|
+
: "black";
|
|
162
|
+
buttonProps[prop].draw(like, color);
|
|
163
|
+
}
|
|
164
|
+
like.gfx.print("white", active
|
|
165
|
+
? `Press ${like.gamepad.fullButtonName(active)}!`
|
|
166
|
+
: "Press any button to resume.", [2, 10], { font: "1px sans-serif" });
|
|
167
|
+
}
|
|
168
|
+
gamepadpressed(like, source, _name, num) {
|
|
169
|
+
if (source !== this.targetPad || this.held || this.frameWait > 0)
|
|
170
|
+
return;
|
|
171
|
+
const active = this.currentlyUnmapped.pop();
|
|
172
|
+
if (active && !this.alreadyMapped.has(num)) {
|
|
173
|
+
this.alreadyMapped.add(num);
|
|
174
|
+
this.mapping.buttons[num] = active;
|
|
175
|
+
this.held = active;
|
|
176
|
+
}
|
|
177
|
+
else if (!active) {
|
|
178
|
+
like.gamepad.setMapping(this.targetPad, this.mapping);
|
|
179
|
+
setTimeout(() => like.setScene(this.next), 100);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
gamepadreleased(_like, source, _name, num) {
|
|
183
|
+
if (source !== this.targetPad)
|
|
184
|
+
return;
|
|
185
|
+
if (this.held == this.mapping.buttons[num]) {
|
|
186
|
+
this.held = undefined;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
mousepressed(like) {
|
|
190
|
+
like.setScene(this.next);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
@@ -31,8 +31,8 @@ import { Like } from '..';
|
|
|
31
31
|
*
|
|
32
32
|
* ```ts
|
|
33
33
|
* import { type Scene } from 'like/scene';
|
|
34
|
-
* import type { ImageHandle } from 'like/
|
|
35
|
-
* import { Vec2 } from 'like/math
|
|
34
|
+
* import type { ImageHandle } from 'like/graphics';
|
|
35
|
+
* import { Vec2 } from 'like/math';
|
|
36
36
|
* import { Like } from 'like';
|
|
37
37
|
* ```
|
|
38
38
|
*
|
|
@@ -31,8 +31,8 @@ const LOGO = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0i
|
|
|
31
31
|
*
|
|
32
32
|
* ```ts
|
|
33
33
|
* import { type Scene } from 'like/scene';
|
|
34
|
-
* import type { ImageHandle } from 'like/
|
|
35
|
-
* import { Vec2 } from 'like/math
|
|
34
|
+
* import type { ImageHandle } from 'like/graphics';
|
|
35
|
+
* import { Vec2 } from 'like/math';
|
|
36
36
|
* import { Like } from 'like';
|
|
37
37
|
* ```
|
|
38
38
|
*
|
package/dist/scene.d.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* @description A helpful callback / state management layer, plus utility scenes.
|
|
4
4
|
*
|
|
5
5
|
*/
|
|
6
|
-
import type { LikeEvent, EventMap } from './
|
|
7
|
-
import type { Like } from './
|
|
6
|
+
import type { LikeEvent, EventMap } from './events';
|
|
7
|
+
import type { Like } from './like';
|
|
8
8
|
/**
|
|
9
9
|
* An interface for creating scenes.
|
|
10
10
|
*
|
package/dist/scene.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkFG;AAEH,MAAM,MAAM,KAAK,GAAG;KACjB,CAAC,IAAI,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI;CACnE,GAAG;IACF,WAAW,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;CAClD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,SAAS,SAI3E,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,SAAS,SAMvE,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/timer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { EngineProps } from "../engine";
|
|
2
|
+
export declare class Timer {
|
|
3
|
+
private currentDelta;
|
|
4
|
+
private totalTime;
|
|
5
|
+
private frameCount;
|
|
6
|
+
private fps;
|
|
7
|
+
private fpsAccumulator;
|
|
8
|
+
private sleepUntil;
|
|
9
|
+
constructor(props: EngineProps<never>);
|
|
10
|
+
private update;
|
|
11
|
+
/** Get `dt` (from the update loop) anywhere.
|
|
12
|
+
* AKA the time since the last frame.
|
|
13
|
+
*/
|
|
14
|
+
getDelta(): number;
|
|
15
|
+
/** Get an estimated FPS based on one-second average. */
|
|
16
|
+
getFPS(): number;
|
|
17
|
+
/** Get the ingame time. */
|
|
18
|
+
getTime(): number;
|
|
19
|
+
/**
|
|
20
|
+
* Whether or not the game is (supposed to be) frozen.
|
|
21
|
+
* The only callback while sleeping is `draw`, and
|
|
22
|
+
* calling this outside of `draw` will always return
|
|
23
|
+
* false -- except if you have a custom runtime.
|
|
24
|
+
*/
|
|
25
|
+
isSleeping(): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Freeze the whole game for a time. Audio will keep playing,
|
|
28
|
+
* but update functions won't be called and events won't fire.
|
|
29
|
+
*/
|
|
30
|
+
sleep(duration: number): void;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=timer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timer.d.ts","sourceRoot":"","sources":["../../src/timer/timer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,qBAAa,KAAK;IAChB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,UAAU,CAAuB;gBAE7B,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC;IAIrC,OAAO,CAAC,MAAM;IAcd;;OAEG;IACH,QAAQ,IAAI,MAAM;IAIlB,wDAAwD;IACxD,MAAM,IAAI,MAAM;IAIhB,2BAA2B;IAC3B,OAAO,IAAI,MAAM;IAIjB;;;;;OAKG;IACH,UAAU,IAAI,OAAO;IAUrB;;;OAGG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;CAG9B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export class
|
|
2
|
-
constructor() {
|
|
1
|
+
export class Timer {
|
|
2
|
+
constructor(props) {
|
|
3
3
|
Object.defineProperty(this, "currentDelta", {
|
|
4
4
|
enumerable: true,
|
|
5
5
|
configurable: true,
|
|
@@ -36,8 +36,10 @@ export class TimerInternal {
|
|
|
36
36
|
writable: true,
|
|
37
37
|
value: null
|
|
38
38
|
});
|
|
39
|
+
props.canvas.addEventListener("like:update", this.update.bind(this), { signal: props.abort });
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
+
update(ev) {
|
|
42
|
+
const { dt } = ev.detail;
|
|
41
43
|
this.currentDelta = dt;
|
|
42
44
|
this.totalTime += dt;
|
|
43
45
|
this.frameCount++;
|
|
@@ -48,15 +50,26 @@ export class TimerInternal {
|
|
|
48
50
|
this.fpsAccumulator = 0;
|
|
49
51
|
}
|
|
50
52
|
}
|
|
53
|
+
/** Get `dt` (from the update loop) anywhere.
|
|
54
|
+
* AKA the time since the last frame.
|
|
55
|
+
*/
|
|
51
56
|
getDelta() {
|
|
52
57
|
return this.currentDelta;
|
|
53
58
|
}
|
|
59
|
+
/** Get an estimated FPS based on one-second average. */
|
|
54
60
|
getFPS() {
|
|
55
61
|
return this.fps;
|
|
56
62
|
}
|
|
63
|
+
/** Get the ingame time. */
|
|
57
64
|
getTime() {
|
|
58
65
|
return this.totalTime;
|
|
59
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Whether or not the game is (supposed to be) frozen.
|
|
69
|
+
* The only callback while sleeping is `draw`, and
|
|
70
|
+
* calling this outside of `draw` will always return
|
|
71
|
+
* false -- except if you have a custom runtime.
|
|
72
|
+
*/
|
|
60
73
|
isSleeping() {
|
|
61
74
|
if (this.sleepUntil === null)
|
|
62
75
|
return false;
|
|
@@ -67,6 +80,10 @@ export class TimerInternal {
|
|
|
67
80
|
this.sleepUntil = null;
|
|
68
81
|
return false;
|
|
69
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Freeze the whole game for a time. Audio will keep playing,
|
|
85
|
+
* but update functions won't be called and events won't fire.
|
|
86
|
+
*/
|
|
70
87
|
sleep(duration) {
|
|
71
88
|
this.sleepUntil = performance.now() + (duration * 1000);
|
|
72
89
|
}
|