pages235/src/react/TouchControls.tsx
Vitaly 379484327e
refactor: Rework mobile controls! (#260)
Separate movement and interaction touch controls
Add new options for touch control types (modern/classic)
Refactor touch interaction handling and event management
Create a new GameInteractionOverlay component for touch interactions for less bugs in future
Update touch controls UI and positioning logic

Co-authored-by: qodo-merge-pro-for-open-source[bot] <189517486+qodo-merge-pro-for-open-source[bot]@users.noreply.github.com>
2025-02-01 02:51:56 +03:00

78 lines
2.1 KiB
TypeScript

import { LeftTouchArea, RightTouchArea, useInterfaceState } from '@dimaka/interface'
import { css } from '@emotion/css'
import { useSnapshot } from 'valtio'
import { contro } from '../controls'
import { miscUiState, activeModalStack } from '../globalState'
import { watchValue, options } from '../optionsStorage'
import { useUsingTouch } from './utilsApp'
// todo
useInterfaceState.setState({
isFlying: false,
uiCustomization: {
touchButtonSize: 40,
},
updateCoord ([coord, state]) {
const coordToAction = [
['z', -1, 'KeyW'],
['z', 1, 'KeyS'],
['x', -1, 'KeyA'],
['x', 1, 'KeyD'],
['y', 1, 'Space'], // todo jump
['y', -1, 'ShiftLeft'], // todo jump
]
// todo refactor
const actionAndState = state === 0 ? coordToAction.filter(([axis]) => axis === coord) : coordToAction.find(([axis, value]) => axis === coord && value === state)
if (!bot) return
if (state === 0) {
// @ts-expect-error
for (const action of actionAndState) {
contro.pressedKeyOrButtonChanged({ code: action[2] }, false)
}
} else {
//@ts-expect-error
contro.pressedKeyOrButtonChanged({ code: actionAndState[2] }, true)
}
}
})
watchValue(options, (o) => {
useInterfaceState.setState({
uiCustomization: {
touchButtonSize: o.touchButtonsSize,
},
})
})
export default () => {
// todo setting
const usingTouch = useUsingTouch()
const { usingGamepadInput } = useSnapshot(miscUiState)
const modals = useSnapshot(activeModalStack)
const { touchMovementType } = useSnapshot(options)
if (!usingTouch || usingGamepadInput || touchMovementType !== 'classic') return null
return (
<div
style={{ zIndex: modals.length ? 7 : 8 }}
className={css`
position: fixed;
bottom: 0;
/* height: 100%; */
display: flex;
width: 100%;
justify-content: space-between;
align-items: flex-end;
pointer-events: none;
touch-action: none;
& > div {
pointer-events: auto;
}
`}
>
<LeftTouchArea />
<div />
<RightTouchArea />
</div>
)
}