@benev/tact 0.4.0-8 → 0.4.0-9
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 +18 -14
- package/package.json +4 -4
- package/s/lib/index.ts +1 -1
- package/s/lib/ui/deck/players.ts +73 -0
- package/x/demo/main.bundle.min.js +35 -35
- package/x/demo/main.bundle.min.js.map +4 -4
- package/x/gamepad/index.html +1 -1
- package/x/index.html +2 -2
- package/x/lib/index.d.ts +1 -1
- package/x/lib/index.js +1 -1
- package/x/lib/index.js.map +1 -1
- package/x/lib/ui/deck/players.d.ts +16 -0
- package/x/lib/ui/deck/players.js +56 -0
- package/x/lib/ui/deck/players.js.map +1 -0
- package/s/lib/ui/deck/collector.ts +0 -52
- package/x/lib/ui/deck/collector.d.ts +0 -13
- package/x/lib/ui/deck/collector.js +0 -35
- package/x/lib/ui/deck/collector.js.map +0 -1
package/README.md
CHANGED
|
@@ -72,13 +72,14 @@ i care about the little things. all input types are boiled down to simple number
|
|
|
72
72
|
- 💡 *you can call `tact.dispose()` to release resources.*
|
|
73
73
|
- 🍏 **encoding, decoding, and your game logic.**
|
|
74
74
|
```ts
|
|
75
|
-
import {
|
|
75
|
+
import {Players} from "@benev/tact"
|
|
76
76
|
|
|
77
|
-
const
|
|
77
|
+
const players = new Players(bindings)
|
|
78
78
|
|
|
79
79
|
setInterval(() => {
|
|
80
80
|
const buffer = tact.encodeAll()
|
|
81
|
-
|
|
81
|
+
players.decodeAll(buffer)
|
|
82
|
+
for (const [playerId, inputs] of players) {
|
|
82
83
|
|
|
83
84
|
// your game logic can read these handy input values.
|
|
84
85
|
inputs.jump.value // button-like values are numbers 0 to 1.
|
|
@@ -90,8 +91,8 @@ i care about the little things. all input types are boiled down to simple number
|
|
|
90
91
|
}
|
|
91
92
|
}, 16.67)
|
|
92
93
|
```
|
|
93
|
-
- 💡 *you
|
|
94
|
-
- 💡 *you
|
|
94
|
+
- 💡 *maybe you'd like to stream the buffers over a network with [renraku](https://github.com/e280/renraku).*
|
|
95
|
+
- 💡 *maybe you'd like the tact deck on the clientside and the players on the serverside.*
|
|
95
96
|
- 🍏 **put the `<tact-deck>` element in your html page.**
|
|
96
97
|
```html
|
|
97
98
|
<tact-deck></tact-deck>
|
|
@@ -165,14 +166,14 @@ i care about the little things. all input types are boiled down to simple number
|
|
|
165
166
|
```
|
|
166
167
|
```ts
|
|
167
168
|
asBindings({
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
169
|
+
special: {
|
|
170
|
+
magic: {
|
|
171
|
+
castSpell: ["*", ["mod", "shift", "alt"], "KeyR"],
|
|
171
172
|
}
|
|
172
173
|
}
|
|
173
174
|
})
|
|
174
175
|
|
|
175
|
-
inputs.
|
|
176
|
+
inputs.special.magic.castSpell.value // 1
|
|
176
177
|
```
|
|
177
178
|
- 🧬 **you can differentiate taps versus holds on the same key.**
|
|
178
179
|
```ts
|
|
@@ -191,21 +192,24 @@ i care about the little things. all input types are boiled down to simple number
|
|
|
191
192
|
lookX: ["accumulate", "pointer.x"],
|
|
192
193
|
})
|
|
193
194
|
|
|
194
|
-
inputs.lookX.sum // use sum instead of value
|
|
195
|
+
inputs.lookX.sum // use sum instead of value.
|
|
195
196
|
```
|
|
196
197
|
- 🧬 **gamepads thumbstick inputs are best done with some math.**
|
|
197
198
|
```ts
|
|
198
199
|
asBindings({
|
|
199
200
|
forward: ["*",
|
|
200
201
|
|
|
201
|
-
// user-customizable sensitivity,
|
|
202
|
+
// user-customizable sensitivity,
|
|
203
|
+
// equivalent with pointer-pixels-per-second.
|
|
202
204
|
1234,
|
|
203
205
|
|
|
204
|
-
// delta time factor,
|
|
206
|
+
// delta time factor,
|
|
207
|
+
// to ensure sensitivity is framerate-independent.
|
|
205
208
|
["dt"],
|
|
206
209
|
|
|
207
|
-
// remapping the ranges
|
|
208
|
-
|
|
210
|
+
// remapping the ranges,
|
|
211
|
+
// because different gamepads represent the values differently.
|
|
212
|
+
["remap", 0, -1, 0, 1, "gamepad.axis.1"],
|
|
209
213
|
],
|
|
210
214
|
})
|
|
211
215
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@benev/tact",
|
|
3
|
-
"version": "0.4.0-
|
|
3
|
+
"version": "0.4.0-9",
|
|
4
4
|
"description": "🎮 from keypress to couch co-op",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Chase Moskal <chasemoskal@gmail.com>",
|
|
@@ -21,16 +21,16 @@
|
|
|
21
21
|
"count": "find s -path '*/_archive' -prune -o -name '*.ts' -exec wc -l {} +"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
|
-
"@e280/sly": "^0.4.
|
|
24
|
+
"@e280/sly": "^0.4.12",
|
|
25
25
|
"@e280/strata": "^0.5.6",
|
|
26
26
|
"lit": "^3.3.3"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@awasm/noble": "^0.1.4",
|
|
30
30
|
"@benev/math": "0.4.0-9",
|
|
31
|
-
"@e280/kv": "^0.2.
|
|
31
|
+
"@e280/kv": "^0.2.6",
|
|
32
32
|
"@e280/shiny": "^0.1.1",
|
|
33
|
-
"@e280/stz": "^0.4.
|
|
33
|
+
"@e280/stz": "^0.4.15"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@e280/hottie": "^0.1.7",
|
package/s/lib/index.ts
CHANGED
|
@@ -19,7 +19,7 @@ export * from "./ui/deck/controls/types.js"
|
|
|
19
19
|
export * from "./ui/deck/setup/deck.js"
|
|
20
20
|
export * from "./ui/deck/setup/tact.js"
|
|
21
21
|
export * from "./ui/deck/auto-gamepads.js"
|
|
22
|
-
export * from "./ui/deck/
|
|
22
|
+
export * from "./ui/deck/players.js"
|
|
23
23
|
export * from "./ui/deck/hub.js"
|
|
24
24
|
export * from "./ui/deck/types.js"
|
|
25
25
|
export * from "./ui/views/customize/view.js"
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
|
|
2
|
+
import {RMap} from "@e280/strata"
|
|
3
|
+
import {guarantee} from "@e280/stz"
|
|
4
|
+
|
|
5
|
+
import {PlayerId} from "./types.js"
|
|
6
|
+
import {Bindings} from "../../input/types.js"
|
|
7
|
+
import {Decoder} from "../../input/decoder.js"
|
|
8
|
+
import {decodeParcels} from "../../input/data/parcel/decode.js"
|
|
9
|
+
|
|
10
|
+
export class Players<B extends Bindings> {
|
|
11
|
+
#bindings: B
|
|
12
|
+
#decoders = new RMap<PlayerId, Decoder<B>>()
|
|
13
|
+
|
|
14
|
+
constructor(bindings: B) {
|
|
15
|
+
this.#bindings = bindings
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
decodeAll(...buffers: ArrayBuffer[]) {
|
|
19
|
+
const added: PlayerId[] = []
|
|
20
|
+
const removed: PlayerId[] = []
|
|
21
|
+
const grouped = new Map<PlayerId, ArrayBuffer[]>()
|
|
22
|
+
|
|
23
|
+
for (const buffer of buffers)
|
|
24
|
+
for (const {playerId, intents} of decodeParcels(buffer))
|
|
25
|
+
guarantee(grouped, playerId, () => []).push(intents)
|
|
26
|
+
|
|
27
|
+
for (const [playerId, intents] of grouped) {
|
|
28
|
+
let decoder = this.#decoders.get(playerId)
|
|
29
|
+
if (!decoder) {
|
|
30
|
+
decoder = new Decoder(this.#bindings)
|
|
31
|
+
this.#decoders.set(playerId, decoder)
|
|
32
|
+
added.push(playerId)
|
|
33
|
+
}
|
|
34
|
+
decoder.decode(...intents)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
for (const playerId of this.#decoders.keys()) {
|
|
38
|
+
if (!grouped.has(playerId)) {
|
|
39
|
+
this.#decoders.delete(playerId)
|
|
40
|
+
removed.push(playerId)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return {added, removed}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
has(playerId: PlayerId) {
|
|
48
|
+
return this.#decoders.has(playerId)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
get(playerId: PlayerId) {
|
|
52
|
+
return this.#decoders.get(playerId)?.inputs
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
keys() {
|
|
56
|
+
return this.#decoders.keys()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
*values() {
|
|
60
|
+
for (const {inputs} of this.#decoders.values())
|
|
61
|
+
yield inputs
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
*entries() {
|
|
65
|
+
for (const [playerId, {inputs}] of this.#decoders)
|
|
66
|
+
yield [playerId, inputs] as const
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
[Symbol.iterator]() {
|
|
70
|
+
return this.entries()
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|