@umicat/three-sdk 0.12.0 → 0.13.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/dist/Input3D.d.ts +20 -2
- package/dist/Input3D.js +36 -17
- package/package.json +1 -1
package/dist/Input3D.d.ts
CHANGED
|
@@ -27,9 +27,10 @@ export interface Input3DOptions {
|
|
|
27
27
|
/** Where key events are read from. */
|
|
28
28
|
target?: Window;
|
|
29
29
|
/**
|
|
30
|
-
* On-screen thumbstick
|
|
30
|
+
* On-screen thumbstick and buttons. `'auto'` (the default) adds them when
|
|
31
31
|
* the device reports coarse pointers and no fine one — i.e. a phone, not a
|
|
32
|
-
* laptop with a touchscreen.
|
|
32
|
+
* laptop with a touchscreen. What the cluster CONTAINS is a separate
|
|
33
|
+
* question — see `jump` and `actions`.
|
|
33
34
|
*/
|
|
34
35
|
touch?: boolean | 'auto';
|
|
35
36
|
/**
|
|
@@ -52,6 +53,21 @@ export interface Input3DOptions {
|
|
|
52
53
|
/** A shape for the JUMP button, in place of its `▲`. Same reasoning as
|
|
53
54
|
* `Input3DAction.icon`, for the one button the platform owns outright. */
|
|
54
55
|
jumpIcon?: string;
|
|
56
|
+
/**
|
|
57
|
+
* Whether this game HAS a jump. Default `true`.
|
|
58
|
+
*
|
|
59
|
+
* Jumping is not universal — a game played by walking around a board does
|
|
60
|
+
* not want a jump button, and it was getting one anyway because the button
|
|
61
|
+
* came bundled with the thumbstick under `touch`. Turning `touch` off to be
|
|
62
|
+
* rid of it takes the stick with it, which is not a trade anyone would make.
|
|
63
|
+
*
|
|
64
|
+
* `false` removes the on-screen button AND makes `jump` permanently false,
|
|
65
|
+
* which also hands **`Space` back to the game**. Those two belong together:
|
|
66
|
+
* Space is read here as jump, so a game with no jump that binds Space to
|
|
67
|
+
* something of its own would otherwise have the hero hop every time the
|
|
68
|
+
* player used it.
|
|
69
|
+
*/
|
|
70
|
+
jump?: boolean;
|
|
55
71
|
/**
|
|
56
72
|
* How the thumbstick behaves on touch.
|
|
57
73
|
*
|
|
@@ -111,6 +127,8 @@ export declare class Input3D {
|
|
|
111
127
|
private touchJump;
|
|
112
128
|
private actions;
|
|
113
129
|
private jumpIcon?;
|
|
130
|
+
/** Whether this game has a jump at all — see `Input3DOptions.jump`. */
|
|
131
|
+
private readonly hasJump;
|
|
114
132
|
/** The glyph inside each on-screen button, by action id (`'jump'` for the
|
|
115
133
|
* platform's own). Kept so an icon can be CHANGED while the game runs —
|
|
116
134
|
* which is the point of it for anything the player switches: an attack
|
package/dist/Input3D.js
CHANGED
|
@@ -71,7 +71,7 @@ export class Input3D {
|
|
|
71
71
|
this.onDown = (e) => {
|
|
72
72
|
this.keysDown.add(e.code);
|
|
73
73
|
if (!e.repeat) {
|
|
74
|
-
if (e.code === 'Space')
|
|
74
|
+
if (e.code === 'Space' && this.hasJump)
|
|
75
75
|
this.beginPress('jump');
|
|
76
76
|
for (const a of this.actions)
|
|
77
77
|
if (a.keys?.includes(e.code))
|
|
@@ -120,6 +120,7 @@ export class Input3D {
|
|
|
120
120
|
this.target.addEventListener('blur', this.onBlur);
|
|
121
121
|
this.actions = opts.actions ?? [];
|
|
122
122
|
this.jumpIcon = opts.jumpIcon;
|
|
123
|
+
this.hasJump = opts.jump ?? true;
|
|
123
124
|
this.stickMode = opts.stick ?? 'floating';
|
|
124
125
|
this.wantLook = opts.look ?? true;
|
|
125
126
|
this.topInset = opts.controlsTopInset ?? 'max(64px, 12%)';
|
|
@@ -206,6 +207,8 @@ export class Input3D {
|
|
|
206
207
|
/** Whether the jump control is held right now. Pass it to the controller —
|
|
207
208
|
* coyote time and buffering live there, not here. */
|
|
208
209
|
get jump() {
|
|
210
|
+
if (!this.hasJump)
|
|
211
|
+
return false;
|
|
209
212
|
return this.enabled && this.held_('jump', this.touchJump || this.isDown('Space'));
|
|
210
213
|
}
|
|
211
214
|
/**
|
|
@@ -278,7 +281,7 @@ export class Input3D {
|
|
|
278
281
|
if (this.keysDown.has(code))
|
|
279
282
|
return; // held, not re-pressed
|
|
280
283
|
this.keysDown.add(code);
|
|
281
|
-
if (code === 'Space')
|
|
284
|
+
if (code === 'Space' && this.hasJump)
|
|
282
285
|
this.beginPress('jump');
|
|
283
286
|
for (const a of this.actions)
|
|
284
287
|
if (a.keys?.includes(code))
|
|
@@ -465,16 +468,29 @@ export class Input3D {
|
|
|
465
468
|
return el;
|
|
466
469
|
};
|
|
467
470
|
this.glyphs.clear();
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
471
|
+
// ONE LIST, and the game decides what is in it.
|
|
472
|
+
//
|
|
473
|
+
// Jump used to be built here on its own, before the loop, which is what
|
|
474
|
+
// made it the one button a game could not decline — it arrived with the
|
|
475
|
+
// thumbstick whether the game had a jump or not. It is an entry in the
|
|
476
|
+
// list now, present unless `jump: false`, and everything after it is
|
|
477
|
+
// whatever the game declared. What this class owns is PLACING them.
|
|
478
|
+
const buttons = [
|
|
479
|
+
...(this.hasJump ? [{ id: 'jump', label: '▲', icon: this.jumpIcon }] : []),
|
|
480
|
+
...this.actions.map((a) => ({ id: a.id, label: a.label ?? a.id.slice(0, 1).toUpperCase(), icon: a.icon })),
|
|
481
|
+
];
|
|
482
|
+
let jumpBtn = null;
|
|
483
|
+
for (const b of buttons) {
|
|
484
|
+
const el = makeButton(b.label, b.icon);
|
|
474
485
|
if (glyph)
|
|
475
|
-
this.glyphs.set(
|
|
486
|
+
this.glyphs.set(b.id, glyph);
|
|
476
487
|
cluster.append(el);
|
|
477
|
-
|
|
488
|
+
// Jump is the platform's own: its press is read through `get jump()`
|
|
489
|
+
// rather than through the action latch, so it is wired below instead.
|
|
490
|
+
if (b.id === 'jump')
|
|
491
|
+
jumpBtn = el;
|
|
492
|
+
else
|
|
493
|
+
this.wireButton(el, b.id);
|
|
478
494
|
}
|
|
479
495
|
root.append(zone, lookZone, pad, cluster);
|
|
480
496
|
container.appendChild(root);
|
|
@@ -613,13 +629,16 @@ export class Input3D {
|
|
|
613
629
|
on(grip, ev, (e) => { if (e.pointerId === stickId)
|
|
614
630
|
reset(); });
|
|
615
631
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
632
|
+
if (jumpBtn) {
|
|
633
|
+
const jb = jumpBtn;
|
|
634
|
+
on(jb, 'pointerdown', (e) => {
|
|
635
|
+
jb.setPointerCapture(e.pointerId);
|
|
636
|
+
this.touchJump = true;
|
|
637
|
+
this.beginPress('jump');
|
|
638
|
+
});
|
|
639
|
+
for (const ev of ['pointerup', 'pointercancel', 'lostpointercapture']) {
|
|
640
|
+
on(jb, ev, () => { this.touchJump = false; });
|
|
641
|
+
}
|
|
623
642
|
}
|
|
624
643
|
}
|
|
625
644
|
wireButton(el, id) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umicat/three-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Three.js runtime for Umicat games: the scene3d design format, its loader with physics, a kinematic character controller, and the Umicat platform via @umicat/platform-sdk.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|