@benev/tact 0.1.1 → 0.2.0-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 +30 -16
- package/package.json +13 -12
- package/s/deck/deck.ts +1 -14
- package/s/deck/index.ts +1 -2
- package/s/deck/parts/db.ts +2 -3
- package/s/deck/views/bindings/view.ts +95 -0
- package/s/deck/views/overlay/view.ts +46 -0
- package/s/demo/game/parts/renderer.ts +4 -5
- package/s/demo/game/parts/state.ts +1 -2
- package/s/demo/main.bundle.ts +1 -4
- package/s/demo/ui/theater/styles.css.ts +1 -2
- package/s/demo/ui/theater/view.ts +47 -52
- package/s/demo/ui/theater/virtual/view.ts +10 -12
- package/s/index.html.ts +53 -44
- package/s/nubs/index.ts +3 -4
- package/s/nubs/lookpad/{component.ts → view.ts} +10 -16
- package/s/nubs/stick/{component.ts → view.ts} +27 -34
- package/s/nubs/vpad/{component.ts → view.ts} +25 -33
- package/s/utils/circular-clamp.ts +1 -2
- package/s/utils/gamepads.ts +2 -2
- package/x/core/devices/standard/stick.d.ts +2 -2
- package/x/deck/deck.d.ts +0 -7
- package/x/deck/deck.js +1 -9
- package/x/deck/deck.js.map +1 -1
- package/x/deck/index.d.ts +1 -2
- package/x/deck/index.js +1 -2
- package/x/deck/index.js.map +1 -1
- package/x/deck/parts/db.d.ts +3 -3
- package/x/deck/parts/db.js.map +1 -1
- package/x/deck/parts/overlay-visibility.d.ts +3 -3
- package/x/deck/views/bindings/style.css.js.map +1 -0
- package/x/deck/views/bindings/view.d.ts +2 -0
- package/x/deck/views/bindings/view.js +80 -0
- package/x/deck/views/bindings/view.js.map +1 -0
- package/x/deck/views/overlay/style.css.js.map +1 -0
- package/x/deck/views/overlay/view.d.ts +2 -0
- package/x/deck/views/overlay/view.js +40 -0
- package/x/deck/views/overlay/view.js.map +1 -0
- package/x/demo/game/parts/renderer.js +4 -4
- package/x/demo/game/parts/renderer.js.map +1 -1
- package/x/demo/game/parts/state.js +1 -1
- package/x/demo/game/parts/state.js.map +1 -1
- package/x/demo/main.bundle.js +1 -5
- package/x/demo/main.bundle.js.map +1 -1
- package/x/demo/main.bundle.min.js +235 -237
- package/x/demo/main.bundle.min.js.map +4 -4
- package/x/demo/ui/theater/styles.css.js +1 -1
- package/x/demo/ui/theater/view.d.ts +1 -367
- package/x/demo/ui/theater/view.js +27 -32
- package/x/demo/ui/theater/view.js.map +1 -1
- package/x/demo/ui/theater/virtual/view.d.ts +1 -1
- package/x/demo/ui/theater/virtual/view.js +6 -6
- package/x/demo/ui/theater/virtual/view.js.map +1 -1
- package/x/index.html +41 -125
- package/x/index.html.js +50 -39
- package/x/index.html.js.map +1 -1
- package/x/nubs/index.d.ts +3 -4
- package/x/nubs/index.js +3 -4
- package/x/nubs/index.js.map +1 -1
- package/x/nubs/lookpad/view.d.ts +1 -0
- package/x/nubs/lookpad/{component.js → view.js} +11 -14
- package/x/nubs/lookpad/view.js.map +1 -0
- package/x/nubs/stick/view.d.ts +2 -0
- package/x/nubs/stick/{component.js → view.js} +28 -34
- package/x/nubs/stick/view.js.map +1 -0
- package/x/nubs/vpad/view.d.ts +2 -0
- package/x/nubs/vpad/{component.js → view.js} +26 -32
- package/x/nubs/vpad/view.js.map +1 -0
- package/x/utils/circular-clamp.js +1 -1
- package/x/utils/circular-clamp.js.map +1 -1
- package/x/utils/gamepads.js +2 -2
- package/s/deck/components/components.ts +0 -22
- package/s/deck/components/deck-bindings/component.ts +0 -99
- package/s/deck/components/deck-overlay/component.ts +0 -51
- package/s/deck/components/framework.ts +0 -17
- package/s/nubs/components.ts +0 -14
- package/s/utils/types.ts +0 -19
- package/x/deck/components/components.d.ts +0 -14
- package/x/deck/components/components.js +0 -9
- package/x/deck/components/components.js.map +0 -1
- package/x/deck/components/deck-bindings/component.d.ts +0 -6
- package/x/deck/components/deck-bindings/component.js +0 -83
- package/x/deck/components/deck-bindings/component.js.map +0 -1
- package/x/deck/components/deck-bindings/style.css.js.map +0 -1
- package/x/deck/components/deck-overlay/component.d.ts +0 -6
- package/x/deck/components/deck-overlay/component.js +0 -44
- package/x/deck/components/deck-overlay/component.js.map +0 -1
- package/x/deck/components/deck-overlay/style.css.js.map +0 -1
- package/x/deck/components/framework.d.ts +0 -7
- package/x/deck/components/framework.js +0 -13
- package/x/deck/components/framework.js.map +0 -1
- package/x/nubs/components.d.ts +0 -9
- package/x/nubs/components.js +0 -11
- package/x/nubs/components.js.map +0 -1
- package/x/nubs/lookpad/component.d.ts +0 -4
- package/x/nubs/lookpad/component.js.map +0 -1
- package/x/nubs/stick/component.d.ts +0 -368
- package/x/nubs/stick/component.js.map +0 -1
- package/x/nubs/vpad/component.d.ts +0 -368
- package/x/nubs/vpad/component.js.map +0 -1
- package/x/utils/types.d.ts +0 -3
- package/x/utils/types.js +0 -3
- package/x/utils/types.js.map +0 -1
- /package/s/deck/{components/deck-bindings → views/bindings}/style.css.ts +0 -0
- /package/s/deck/{components/deck-overlay → views/overlay}/style.css.ts +0 -0
- /package/x/deck/{components/deck-bindings → views/bindings}/style.css.d.ts +0 -0
- /package/x/deck/{components/deck-bindings → views/bindings}/style.css.js +0 -0
- /package/x/deck/{components/deck-overlay → views/overlay}/style.css.d.ts +0 -0
- /package/x/deck/{components/deck-overlay → views/overlay}/style.css.js +0 -0
package/README.md
CHANGED
|
@@ -23,7 +23,9 @@ it's good at user-customizable keybindings, multiple gamepad support, and mobile
|
|
|
23
23
|
## 🍋 tact deck
|
|
24
24
|
> *full setup with ui, batteries included*
|
|
25
25
|
|
|
26
|
-
the deck ties together all the important pieces of tact into a single user experience, complete with ui
|
|
26
|
+
the deck ties together all the important pieces of tact into a single user experience, complete with ui views.
|
|
27
|
+
|
|
28
|
+
tact's ui is built with [`@e280/sly` shadow views](https://github.com/e280/sly).
|
|
27
29
|
|
|
28
30
|
### 🛹 deck setup
|
|
29
31
|
- **import stuff from tact**
|
|
@@ -77,13 +79,18 @@ the deck ties together all the important pieces of tact into a single user exper
|
|
|
77
79
|
```
|
|
78
80
|
|
|
79
81
|
### 🛹 deck ui: the overlay
|
|
80
|
-
- **
|
|
82
|
+
- **render the deck overlay with sly**
|
|
81
83
|
```ts
|
|
82
|
-
|
|
84
|
+
import {dom} from "@e280/sly"
|
|
85
|
+
|
|
86
|
+
dom.render(
|
|
87
|
+
dom("#game-ui"),
|
|
88
|
+
tact.DeckOverlay(deck),
|
|
89
|
+
)
|
|
83
90
|
```
|
|
84
91
|
- **place the ui on top of your game canvas**
|
|
85
92
|
```html
|
|
86
|
-
<
|
|
93
|
+
<div id="game-ui"></div>
|
|
87
94
|
```
|
|
88
95
|
|
|
89
96
|
|
|
@@ -390,25 +397,33 @@ the hub embraces that analogy, helping you coordinate the plugging and unpluggin
|
|
|
390
397
|
> *mobile ui like virtual thumbsticks and buttons*
|
|
391
398
|
|
|
392
399
|
### 📱 nubs setup
|
|
393
|
-
- **
|
|
400
|
+
- **render nub views with sly**
|
|
394
401
|
```ts
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
402
|
+
import {dom} from "@e280/sly"
|
|
403
|
+
|
|
404
|
+
const stick = new tact.StickDevice()
|
|
405
|
+
|
|
406
|
+
dom.render(
|
|
407
|
+
dom("#controls"),
|
|
408
|
+
tact.NubStick(stick),
|
|
409
|
+
)
|
|
400
410
|
```
|
|
401
411
|
|
|
402
412
|
### 📱 nub stick
|
|
403
|
-
- **place a
|
|
413
|
+
- **place a mount point onto your page**
|
|
404
414
|
```html
|
|
405
|
-
<
|
|
415
|
+
<div id="controls"></div>
|
|
406
416
|
```
|
|
407
|
-
- **
|
|
417
|
+
- **make the stick device yourself, then plug it into your hub or whatever**
|
|
408
418
|
```ts
|
|
409
|
-
const
|
|
419
|
+
const stick = new tact.StickDevice()
|
|
410
420
|
|
|
411
|
-
|
|
421
|
+
dom.render(
|
|
422
|
+
dom("#controls"),
|
|
423
|
+
tact.NubStick(stick),
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
deck.hub.plug(stick)
|
|
412
427
|
```
|
|
413
428
|
|
|
414
429
|
|
|
@@ -418,4 +433,3 @@ the hub embraces that analogy, helping you coordinate the plugging and unpluggin
|
|
|
418
433
|
|
|
419
434
|
## 🍋 tact is by https://benevolent.games/
|
|
420
435
|
> *building the future of web games*
|
|
421
|
-
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@benev/tact",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-0",
|
|
4
4
|
"description": "keybindings and gamepad support for web games",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Chase Moskal <chasemoskal@gmail.com>",
|
|
@@ -16,34 +16,35 @@
|
|
|
16
16
|
"s"
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
|
-
"build": "
|
|
19
|
+
"build": "octo-s --npm-run _clean _tsc _ln _scute",
|
|
20
|
+
"dev": "octo 'scute -vw' 'tsc -w' 'node --watch x/tests.test.js' 'hottie x'",
|
|
20
21
|
"_clean": "rm -rf x",
|
|
21
22
|
"_tsc": "tsc",
|
|
22
23
|
"_scute": "scute -v",
|
|
23
|
-
"start": "octo 'scute -vw' 'tsc -w' 'node --watch x/tests.test.js' 'http-server x -c-1'",
|
|
24
24
|
"_ln": "run-s _ln-s _ln-assets",
|
|
25
25
|
"_ln-s": "ln -s \"$(realpath s)\" x/s",
|
|
26
26
|
"_ln-assets": "ln -s \"$(realpath assets)\" x/assets",
|
|
27
27
|
"test": "node x/tests.test.js",
|
|
28
|
-
"test-debug": "node inspect x/tests.test.js",
|
|
29
28
|
"count": "find s -path '*/_archive' -prune -o -name '*.ts' -exec wc -l {} +"
|
|
30
29
|
},
|
|
31
30
|
"peerDependencies": {
|
|
32
31
|
"lit": "^3.3.2"
|
|
33
32
|
},
|
|
34
33
|
"dependencies": {
|
|
35
|
-
"@benev/math": "^0.
|
|
36
|
-
"@e280/kv": "^0.1.
|
|
37
|
-
"@e280/sly": "^0.
|
|
38
|
-
"@e280/strata": "^0.
|
|
39
|
-
"@e280/stz": "^0.2.
|
|
34
|
+
"@benev/math": "^0.3.0-5",
|
|
35
|
+
"@e280/kv": "^0.1.2",
|
|
36
|
+
"@e280/sly": "^0.3.1",
|
|
37
|
+
"@e280/strata": "^0.3.1",
|
|
38
|
+
"@e280/stz": "^0.2.27"
|
|
40
39
|
},
|
|
41
40
|
"devDependencies": {
|
|
42
|
-
"@e280/
|
|
43
|
-
"@e280/
|
|
41
|
+
"@e280/hottie": "^0.1.0",
|
|
42
|
+
"@e280/octo": "^0.1.0",
|
|
43
|
+
"@e280/science": "^0.1.9",
|
|
44
|
+
"@e280/scute": "^0.3.1",
|
|
44
45
|
"http-server": "^14.1.1",
|
|
45
46
|
"npm-run-all": "^4.1.5",
|
|
46
|
-
"typescript": "^
|
|
47
|
+
"typescript": "^6.0.2"
|
|
47
48
|
},
|
|
48
49
|
"repository": {
|
|
49
50
|
"type": "git",
|
package/s/deck/deck.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import {Kv} from "@e280/kv"
|
|
3
|
-
import {
|
|
4
|
-
import {disposer, ob, range} from "@e280/stz"
|
|
3
|
+
import {disposer, range} from "@e280/stz"
|
|
5
4
|
|
|
6
5
|
import {Db} from "./parts/db.js"
|
|
7
6
|
import {Hub} from "../core/hub/hub.js"
|
|
@@ -13,7 +12,6 @@ import {makeMetaBindings} from "../core/hub/meta-bindings.js"
|
|
|
13
12
|
import {DeviceSkins} from "./parts/device-skins/device-skin.js"
|
|
14
13
|
import {OverlayVisibility} from "./parts/overlay-visibility.js"
|
|
15
14
|
import {PrimaryDevice} from "../core/devices/standard/primary.js"
|
|
16
|
-
import {deckComponents, DeckViews} from "./components/components.js"
|
|
17
15
|
|
|
18
16
|
export type DeckOptions<B extends Bindings, MB extends MetaBindings = any> = {
|
|
19
17
|
kv: Kv
|
|
@@ -46,17 +44,6 @@ export class Deck<B extends Bindings, MB extends MetaBindings = any> {
|
|
|
46
44
|
primaryDevice = new PrimaryDevice()
|
|
47
45
|
overlayVisibility: OverlayVisibility
|
|
48
46
|
|
|
49
|
-
components = deckComponents(this)
|
|
50
|
-
|
|
51
|
-
views = (
|
|
52
|
-
ob(this.components as any)
|
|
53
|
-
.map(c => (...a: any[]) => c.view(this, ...a))
|
|
54
|
-
) as DeckViews
|
|
55
|
-
|
|
56
|
-
registerComponents() {
|
|
57
|
-
dom.register(this.components)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
47
|
constructor(
|
|
61
48
|
public baseBindings: B,
|
|
62
49
|
public baseMetaBindings: MB,
|
package/s/deck/index.ts
CHANGED
|
@@ -7,8 +7,7 @@ export * from "./parts/local-storage-kv.js"
|
|
|
7
7
|
export * from "./parts/merge-bindings.js"
|
|
8
8
|
export * from "./parts/overlay-visibility.js"
|
|
9
9
|
|
|
10
|
-
export * from "./
|
|
11
|
-
export * from "./components/deck-overlay/style.css.js"
|
|
10
|
+
export * from "./views/overlay/view.js"
|
|
12
11
|
|
|
13
12
|
export * from "./deck.js"
|
|
14
13
|
|
package/s/deck/parts/db.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import {disposer, Hex} from "@e280/stz"
|
|
3
|
-
import {signal,
|
|
3
|
+
import {signal, Signal} from "@e280/strata"
|
|
4
4
|
import {StorageDriver, Store} from "@e280/kv"
|
|
5
5
|
|
|
6
6
|
import {Bindings} from "../../core/bindings/types.js"
|
|
@@ -16,7 +16,7 @@ export class Db {
|
|
|
16
16
|
|
|
17
17
|
constructor(
|
|
18
18
|
private store: Store<CatalogData>,
|
|
19
|
-
public $catalog:
|
|
19
|
+
public $catalog: Signal<Catalog>,
|
|
20
20
|
) {
|
|
21
21
|
|
|
22
22
|
this.dispose.schedule(
|
|
@@ -63,4 +63,3 @@ export class Db {
|
|
|
63
63
|
})
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
|
|
2
|
+
import {html} from "lit"
|
|
3
|
+
import {bytename} from "@e280/stz"
|
|
4
|
+
import {cssReset, shadow, useCss, useName, useSignal} from "@e280/sly"
|
|
5
|
+
|
|
6
|
+
import {Deck} from "../../deck.js"
|
|
7
|
+
import styleCss from "./style.css.js"
|
|
8
|
+
import {Port} from "../../../core/hub/port.js"
|
|
9
|
+
import {Profile} from "../../parts/catalog.js"
|
|
10
|
+
import {Atom, Bindings, Bracket} from "../../../core/bindings/types.js"
|
|
11
|
+
|
|
12
|
+
export const DeckBindings = shadow((deck: Deck<any>) => {
|
|
13
|
+
useCss(cssReset, styleCss)
|
|
14
|
+
useName("deck-bindings")
|
|
15
|
+
const {db, hub} = deck
|
|
16
|
+
|
|
17
|
+
const catalog = db.$catalog()
|
|
18
|
+
const defaultProfile: Profile = {id: "default", label: "default", bindings: deck.baseBindings}
|
|
19
|
+
const allProfiles = [defaultProfile, ...catalog.profiles.values()]
|
|
20
|
+
const $selectedProfileId = useSignal("default")
|
|
21
|
+
const profile = db.$catalog().getProfile($selectedProfileId()) ?? defaultProfile
|
|
22
|
+
|
|
23
|
+
function renderPort(_port: Port<Bindings>, index: number) {
|
|
24
|
+
const portProfile = catalog.getProfileForPort(index) ?? defaultProfile
|
|
25
|
+
return html`
|
|
26
|
+
<div class=port>
|
|
27
|
+
<span>port ${index + 1}</span>
|
|
28
|
+
<select>
|
|
29
|
+
${allProfiles.map(profile => html`
|
|
30
|
+
<option
|
|
31
|
+
data-id="${profile.id}"
|
|
32
|
+
?selected="${profile.id === portProfile.id}">
|
|
33
|
+
${profile.label}
|
|
34
|
+
</option>
|
|
35
|
+
`)}
|
|
36
|
+
</select>
|
|
37
|
+
</div>
|
|
38
|
+
`
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function renderBindingBracket(entry: [string, unknown]) {
|
|
42
|
+
const [mode, bracket] = entry as [string, Bracket]
|
|
43
|
+
return html`
|
|
44
|
+
<div class=bracket>
|
|
45
|
+
<strong class=mode>${mode}</strong>
|
|
46
|
+
<div>${Object.entries(bracket).map(renderBinds)}</div>
|
|
47
|
+
</div>
|
|
48
|
+
`
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function renderBinds([action, _atom]: [action: string, atom: Atom]) {
|
|
52
|
+
return html`
|
|
53
|
+
<div class=bind>
|
|
54
|
+
<span class=action>${action}</span>
|
|
55
|
+
</div>
|
|
56
|
+
`
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const clickClone = async() => {
|
|
60
|
+
const {bindings} = profile
|
|
61
|
+
const label = bytename.random(4)
|
|
62
|
+
const p = await db.createProfile(label, bindings)
|
|
63
|
+
$selectedProfileId(p.id)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const deleteProfile = (id: string) => async() => {
|
|
67
|
+
await db.deleteProfile(id)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const onSelected = (event: InputEvent) => {
|
|
71
|
+
const select = event.target as HTMLSelectElement
|
|
72
|
+
const id = select.value
|
|
73
|
+
$selectedProfileId(id)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return html`
|
|
77
|
+
<div class=portlist>
|
|
78
|
+
${hub.ports.map(renderPort)}
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<div class=bindable>
|
|
82
|
+
<select @input="${onSelected}">
|
|
83
|
+
${allProfiles.map(p => html`
|
|
84
|
+
<option value="${p.id}" ?selected="${p.id === profile.id}">${p.label}</option>
|
|
85
|
+
`)}
|
|
86
|
+
</select>
|
|
87
|
+
<button @click="${clickClone}">clone</button>
|
|
88
|
+
<button ?disabled="${profile.id === defaultProfile.id}" @click="${deleteProfile(profile.id)}">delete</button>
|
|
89
|
+
<div class=bindings>
|
|
90
|
+
${Object.entries(profile.bindings).map(renderBindingBracket)}
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
`
|
|
94
|
+
})
|
|
95
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
|
|
2
|
+
import {html} from "lit"
|
|
3
|
+
import {cssReset, shadow, useCss, useName} from "@e280/sly"
|
|
4
|
+
import {Deck} from "../../deck.js"
|
|
5
|
+
import styleCss from "./style.css.js"
|
|
6
|
+
import {Device} from "../../../core/devices/device.js"
|
|
7
|
+
|
|
8
|
+
export const DeckOverlay = shadow((deck: Deck<any>) => {
|
|
9
|
+
useCss(cssReset, styleCss)
|
|
10
|
+
useName("deck-overlay")
|
|
11
|
+
const {hub, deviceSkins, overlayVisibility: {$visible, $showLabels}} = deck
|
|
12
|
+
|
|
13
|
+
function renderDevice(device: Device) {
|
|
14
|
+
const skin = deviceSkins.get(device)
|
|
15
|
+
const style = `--color: ${skin.color};`
|
|
16
|
+
const next = () => hub.shimmy(device, 1)
|
|
17
|
+
const previous = () => hub.shimmy(device, -1)
|
|
18
|
+
return html`
|
|
19
|
+
<div class=device style="${style}">
|
|
20
|
+
<div class="primary row">
|
|
21
|
+
<button @click="${previous}"><</button>
|
|
22
|
+
<div class=icon>${skin.icon}</div>
|
|
23
|
+
<button @click="${next}">></button>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
${$showLabels() ? html`
|
|
27
|
+
<div class="secondary row">
|
|
28
|
+
<div class=label>${skin.label}</div>
|
|
29
|
+
</div>
|
|
30
|
+
` : null}
|
|
31
|
+
</div>
|
|
32
|
+
`
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return html`
|
|
36
|
+
<div class=portlist ?data-active="${$visible()}">
|
|
37
|
+
${hub.ports.map((port, index) => html`
|
|
38
|
+
<div class=port>
|
|
39
|
+
<header>P${index + 1}</header>
|
|
40
|
+
${port.devices.array().map(renderDevice)}
|
|
41
|
+
</div>
|
|
42
|
+
`)}
|
|
43
|
+
</div>
|
|
44
|
+
`
|
|
45
|
+
})
|
|
46
|
+
|
|
@@ -22,16 +22,16 @@ export class Renderer {
|
|
|
22
22
|
|
|
23
23
|
/** take a game-state position and resolve it into canvas coordinates */
|
|
24
24
|
resolve(position: Vec2) {
|
|
25
|
-
return position.
|
|
25
|
+
return position.dup()
|
|
26
26
|
|
|
27
27
|
// 0-1 relative to arena scale
|
|
28
|
-
.
|
|
28
|
+
.div(this.state.arenaSize)
|
|
29
29
|
|
|
30
30
|
// flip y axis
|
|
31
|
-
.morph(v => {v.y = 1 - v.y})
|
|
31
|
+
.morph((v: Vec2) => {v.y = 1 - v.y})
|
|
32
32
|
|
|
33
33
|
// stretch to the size of the canvas
|
|
34
|
-
.
|
|
34
|
+
.mul_(this.canvas.width, this.canvas.height)
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
render() {
|
|
@@ -110,4 +110,3 @@ export class Renderer {
|
|
|
110
110
|
ctx.fillText(agent.label, x, y)
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
|
-
|
package/s/demo/main.bundle.ts
CHANGED
|
@@ -1,60 +1,55 @@
|
|
|
1
1
|
|
|
2
2
|
import {html} from "lit"
|
|
3
3
|
import {repeat} from "lit/directives/repeat.js"
|
|
4
|
-
import {
|
|
4
|
+
import {cssReset, shadow, useCss, useMount, useRender} from "@e280/sly"
|
|
5
5
|
|
|
6
6
|
import {styles} from "./styles.css.js"
|
|
7
7
|
import {Game} from "../../game/game.js"
|
|
8
8
|
import {VirtualDeviceView} from "./virtual/view.js"
|
|
9
9
|
import {VirtualDevice} from "../../game/parts/virtual-device.js"
|
|
10
|
-
import {DeckBindings} from "../../../deck/
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
})
|
|
57
|
-
.component(class extends BaseElement { game!: Game })
|
|
58
|
-
.props(el => [el.game])
|
|
59
|
-
) {}
|
|
60
|
-
|
|
10
|
+
import {DeckBindings} from "../../../deck/views/bindings/view.js"
|
|
11
|
+
import { DeckOverlay } from "../../../deck/views/overlay/view.js"
|
|
12
|
+
|
|
13
|
+
export const DemoTheater = shadow((game: Game) => {
|
|
14
|
+
useCss(cssReset, styles)
|
|
15
|
+
useMount(() => game.loop(60))
|
|
16
|
+
const render = useRender()
|
|
17
|
+
useMount(() => game.deck.hub.on(render))
|
|
18
|
+
|
|
19
|
+
const addVirtual = () => game.plug(new VirtualDevice(game.deck.hub))
|
|
20
|
+
const revealOverlay = () => game.deck.overlayVisibility.bump()
|
|
21
|
+
|
|
22
|
+
const virtualDevices = game.deck.hub.ports
|
|
23
|
+
.flatMap(port => port.devices.array())
|
|
24
|
+
.filter(device => device instanceof VirtualDevice)
|
|
25
|
+
.map(device => ({device, skin: game.deck.deviceSkins.get(device)}))
|
|
26
|
+
.sort((a, b) => a.skin.label < b.skin.label ? -1 : 1)
|
|
27
|
+
|
|
28
|
+
return html`
|
|
29
|
+
<div class=surface>
|
|
30
|
+
${game.renderer.canvas}
|
|
31
|
+
${DeckOverlay(game.deck)}
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<div class=dlist>
|
|
35
|
+
${repeat(
|
|
36
|
+
virtualDevices,
|
|
37
|
+
d => d.skin.label,
|
|
38
|
+
({device, skin}) => VirtualDeviceView.with({
|
|
39
|
+
props: [game.deck.hub, device, skin],
|
|
40
|
+
attrs: {style: `--color: ${skin.color};`},
|
|
41
|
+
}),
|
|
42
|
+
)}
|
|
43
|
+
|
|
44
|
+
<button @click="${addVirtual}">
|
|
45
|
+
✨
|
|
46
|
+
</button>
|
|
47
|
+
|
|
48
|
+
<button @click="${revealOverlay}">
|
|
49
|
+
👁️
|
|
50
|
+
</button>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
${DeckBindings(game.deck)}
|
|
54
|
+
`
|
|
55
|
+
})
|
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
|
|
2
2
|
import {html} from "lit"
|
|
3
|
-
import {cssReset,
|
|
3
|
+
import {cssReset, shadow, useCss, useName} from "@e280/sly"
|
|
4
4
|
import styleCss from "./style.css.js"
|
|
5
5
|
import {Hub} from "../../../../core/hub/hub.js"
|
|
6
|
-
import {NubStick} from "../../../../nubs/stick/
|
|
6
|
+
import {NubStick} from "../../../../nubs/stick/view.js"
|
|
7
7
|
import {VirtualDevice} from "../../../game/parts/virtual-device.js"
|
|
8
8
|
import {DeviceSkin} from "../../../../deck/parts/device-skins/device-skin.js"
|
|
9
9
|
|
|
10
|
-
export const VirtualDeviceView =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
use.attrs.strings.device = "virtual"
|
|
10
|
+
export const VirtualDeviceView = shadow((
|
|
11
|
+
hub: Hub<any>,
|
|
12
|
+
device: VirtualDevice,
|
|
13
|
+
_deviceSkin: DeviceSkin,
|
|
14
|
+
) => {
|
|
15
|
+
useCss(cssReset, styleCss)
|
|
16
|
+
useName("virtual-device")
|
|
18
17
|
|
|
19
18
|
const unplug = () => hub.unplug(device)
|
|
20
19
|
|
|
21
20
|
return html`
|
|
22
21
|
<div class=box>
|
|
23
|
-
${NubStick
|
|
22
|
+
${NubStick(device)}
|
|
24
23
|
|
|
25
24
|
<button @click="${device.shimmyPrevious}">👈</button>
|
|
26
25
|
<button @click="${unplug}">💀</button>
|
|
@@ -28,4 +27,3 @@ export const VirtualDeviceView = view(use => (
|
|
|
28
27
|
</div>
|
|
29
28
|
`
|
|
30
29
|
})
|
|
31
|
-
|