Skip to content

Commit

Permalink
working on touch ui feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
goldbuick committed Jan 1, 2025
1 parent cadf854 commit c07ddce
Show file tree
Hide file tree
Showing 10 changed files with 344 additions and 214 deletions.
4 changes: 4 additions & 0 deletions zss/device/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ export function tape_terminal_close(sender: string, player: string) {
hub.emit('tape:terminal:close', sender, undefined, player)
}

export function tape_terminal_toggle(sender: string, player: string) {
hub.emit('tape:terminal:toggle', sender, undefined, player)
}

export function tape_terminal_inclayout(
sender: string,
inc: boolean,
Expand Down
8 changes: 8 additions & 0 deletions zss/device/tape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ createdevice('tape', [], (message) => {
},
}))
break
case 'terminal:toggle':
useTape.setState((state) => ({
terminal: {
...state.terminal,
open: !state.terminal.open,
},
}))
break
case 'terminal:inclayout':
if (isboolean(message.data)) {
terminalinclayout(message.data)
Expand Down
6 changes: 0 additions & 6 deletions zss/gadget/console/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,6 @@ export function ConsoleInput({
}}
/>
<UserInput
CANCEL_BUTTON={() => {
tape_terminal_close('tape', player)
}}
MENU_BUTTON={() => {
tape_terminal_inclayout('tape', true, player)
}}
keydown={(event) => {
const { key } = event
const lkey = NAME(key)
Expand Down
1 change: 0 additions & 1 deletion zss/gadget/terminal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ export function Terminal() {
<>
<UserFocus>
<UserScreen
islowrez={islowrez}
islandscape={islandscape}
showtouchcontrols={showtouchcontrols}
>
Expand Down
229 changes: 24 additions & 205 deletions zss/gadget/touchui/component.tsx
Original file line number Diff line number Diff line change
@@ -1,173 +1,41 @@
/* eslint-disable react/no-unknown-property */
import { radToDeg } from 'maath/misc'
import { useState } from 'react'
import { Vector2, Vector3 } from 'three'
import { RUNTIME } from 'zss/config'
import {
tape_terminal_open,
userinput_down,
userinput_up,
vm_input,
} from 'zss/device/api'
import { registerreadplayer } from 'zss/device/register'
import { snap } from 'zss/mapping/number'
import {
WRITE_TEXT_CONTEXT,
createwritetextcontext,
textformatedges,
tokenizeandwritetextformat,
} from 'zss/words/textformat'
import { COLOR } from 'zss/words/types'

import { INPUT } from '../data/types'
import { ShadeBoxDither } from '../framed/dither'
import { useTiles } from '../hooks'
import { Rect } from '../rect'
import { useScreenSize } from '../userscreen'
import { TilesData, TilesRender } from '../usetiles'

const motion = new Vector2()
const corner = new Vector3()
import { Controls } from './controls'
import { Surface } from './surface'

export type TouchUIProps = {
width: number
height: number
islandscape: boolean
}

function ptwithin(
x: number,
y: number,
top: number,
right: number,
bottom: number,
left: number,
) {
return x >= left && x <= right && y >= top && y <= bottom
}

export function TouchUI({ width, height }: TouchUIProps) {
export function TouchUI({ width, height, islandscape }: TouchUIProps) {
const screensize = useScreenSize()
const player = registerreadplayer()
const [movestick] = useState({

const [drawstick, setdrawstick] = useState({
startx: -1,
starty: -1,
tipx: -1,
tipy: -1,
pointerId: -1 as any,
})
// const [drawstick, setdrawstick] = useState(-1)

function clearmovestick(cx: number, cy: number) {
if (movestick.tipx === -1) {
// check touch targets
if (ptwithin(cx, cy, 3, 6, 6, 1)) {
// top-left button
tape_terminal_open('touchui', player)
console.info('top-left')
}
if (ptwithin(cx, cy, 3, width - 2, 6, width - 6)) {
// top-right button
vm_input('touchui', INPUT.MENU_BUTTON, 0, player)
console.info('top-right')
}
if (ptwithin(cx, cy, height - 5, 6, height - 2, 1)) {
// bottom-left button
vm_input('touchui', INPUT.OK_BUTTON, 0, player)
console.info('bottom-left')
}
if (ptwithin(cx, cy, height - 5, width - 2, height - 2, width - 6)) {
// bottom-right button
vm_input('touchui', INPUT.CANCEL_BUTTON, 0, player)
console.info('bottom-right')
}
} else {
// reset input
userinput_up('touchui', INPUT.MOVE_UP, player)
userinput_up('touchui', INPUT.MOVE_DOWN, player)
userinput_up('touchui', INPUT.MOVE_LEFT, player)
userinput_up('touchui', INPUT.MOVE_RIGHT, player)
}
// reset
movestick.startx = -1
movestick.starty = -1
movestick.tipx = -1
movestick.tipy = -1
movestick.pointerId = -1
}

function handlestickdir(snapdir: number) {
switch (snapdir) {
case 0:
// left
userinput_down('touchui', INPUT.MOVE_LEFT, player)
userinput_up('touchui', INPUT.MOVE_RIGHT, player)
userinput_up('touchui', INPUT.MOVE_UP, player)
userinput_up('touchui', INPUT.MOVE_DOWN, player)
break
case 45:
// left up
userinput_down('touchui', INPUT.MOVE_UP, player)
userinput_down('touchui', INPUT.MOVE_LEFT, player)
userinput_up('touchui', INPUT.MOVE_RIGHT, player)
userinput_up('touchui', INPUT.MOVE_DOWN, player)
break
case 90:
// up
userinput_down('touchui', INPUT.MOVE_UP, player)
userinput_up('touchui', INPUT.MOVE_DOWN, player)
userinput_up('touchui', INPUT.MOVE_LEFT, player)
userinput_up('touchui', INPUT.MOVE_RIGHT, player)
break
case 135:
// up right
userinput_down('touchui', INPUT.MOVE_UP, player)
userinput_down('touchui', INPUT.MOVE_RIGHT, player)
userinput_up('touchui', INPUT.MOVE_LEFT, player)
userinput_up('touchui', INPUT.MOVE_DOWN, player)
break
case 180:
// right
userinput_down('touchui', INPUT.MOVE_RIGHT, player)
userinput_up('touchui', INPUT.MOVE_LEFT, player)
userinput_up('touchui', INPUT.MOVE_UP, player)
userinput_up('touchui', INPUT.MOVE_DOWN, player)
break
case 225:
// right down
userinput_down('touchui', INPUT.MOVE_DOWN, player)
userinput_down('touchui', INPUT.MOVE_RIGHT, player)
userinput_up('touchui', INPUT.MOVE_LEFT, player)
userinput_up('touchui', INPUT.MOVE_DOWN, player)
break
case 270:
// down
userinput_down('touchui', INPUT.MOVE_DOWN, player)
userinput_up('touchui', INPUT.MOVE_UP, player)
userinput_up('touchui', INPUT.MOVE_LEFT, player)
userinput_up('touchui', INPUT.MOVE_RIGHT, player)
break
case 315:
// down left
userinput_down('touchui', INPUT.MOVE_DOWN, player)
userinput_down('touchui', INPUT.MOVE_LEFT, player)
userinput_up('touchui', INPUT.MOVE_RIGHT, player)
userinput_up('touchui', INPUT.MOVE_UP, player)
break
case 360:
// left
userinput_down('touchui', INPUT.MOVE_LEFT, player)
userinput_up('touchui', INPUT.MOVE_RIGHT, player)
userinput_up('touchui', INPUT.MOVE_UP, player)
userinput_up('touchui', INPUT.MOVE_DOWN, player)
break
}
}

const FG = COLOR.PURPLE
const BG = COLOR.ONCLEAR
const store = useTiles(width, height, 0, FG, BG)
// setup text writing
const store = useTiles(width, height, 0, COLOR.WHITE, COLOR.ONCLEAR)
const context: WRITE_TEXT_CONTEXT = {
...createwritetextcontext(width, height, FG, BG),
...createwritetextcontext(width, height, COLOR.WHITE, COLOR.ONCLEAR),
...store.getState(),
}

Expand All @@ -179,88 +47,39 @@ export function TouchUI({ width, height }: TouchUIProps) {
// render ui
textformatedges(1, 1, width - 2, height - 2, context)

// draw action button targets
context.y = 3
for (let i = 0; i < 3; ++i) {
context.x = context.active.leftedge = 1
tokenizeandwritetextformat(`$BLUE$177$177$177$177$177`, context, false)
context.x = context.active.leftedge = width - 7
tokenizeandwritetextformat(`$PURPLE$177$177$177$177$177\n`, context, false)
}
context.y = height - 5
for (let i = 0; i < 3; ++i) {
context.x = context.active.leftedge = 1
tokenizeandwritetextformat(`$GREEN$177$177$177$177$177`, context, false)
context.x = context.active.leftedge = width - 7
tokenizeandwritetextformat(`$RED$177$177$177$177$177\n`, context, false)
}

return (
<TilesData store={store}>
<group position={[0, 0, 999]}>
<Rect
blocking
<Controls
context={context}
width={width}
height={height}
visible={false}
onPointerDown={(e) => {
if (movestick.startx === -1) {
movestick.startx = e.x
movestick.starty = e.y
movestick.tipx = -1
movestick.tipy = -1
movestick.pointerId = e.pointerId
} else {
// flag as shooting now
userinput_down('touchui', INPUT.SHIFT, player)
}
}}
onPointerMove={(e) => {
if (e.pointerId === movestick.pointerId) {
// calc angle
motion.set(movestick.startx - e.x, movestick.starty - e.y)
if (motion.length() > 42) {
const snapdir = snap(radToDeg(motion.angle()), 45)
// track for visuals
movestick.tipx = e.x
movestick.tipy = e.y
// invoke input directions
handlestickdir(snapdir)
}
}
}}
onPointerUp={(e) => {
if (e.pointerId === movestick.pointerId) {
corner.copy(e.intersections[0].point)
e.intersections[0].object.worldToLocal(corner)
const dx =
Math.floor(width * 0.5) +
Math.floor(corner.x / RUNTIME.DRAW_CHAR_WIDTH())
const dy =
Math.floor(height * 0.5) +
Math.floor(corner.y / RUNTIME.DRAW_CHAR_HEIGHT())
clearmovestick(dx, dy)
} else {
// flag off shift
userinput_up('touchui', INPUT.SHIFT, player)
}
}}
islandscape={islandscape}
drawstick={drawstick}
/>
<Surface
width={width}
height={height}
player={player}
onDrawStick={(startx, starty, tipx, tipy) =>
setdrawstick({ startx, starty, tipx, tipy })
}
/>
<ShadeBoxDither
width={width}
height={height}
top={3}
top={5}
left={0}
right={5}
bottom={height - 2}
bottom={height - 6}
/>
<ShadeBoxDither
width={width}
height={height}
top={5}
left={width - 6}
right={width - 1}
bottom={height - 2}
bottom={height - 6}
/>
<TilesRender width={width} height={height} />
</group>
Expand Down
Loading

0 comments on commit c07ddce

Please sign in to comment.