'use client' import { useCallback, useRef, useEffect, useState } from 'react' import { usePlayerStore } from '@/stores/playerStore' export function MobileControls() { const [moveActive, setMoveActive] = useState(false) const [lookActive, setLookActive] = useState(false) const moveRef = useRef<{ x: number; z: number }>({ x: 0, z: 0 }) const lookRef = useRef<{ lastX: number; lastY: number }>({ lastX: 0, lastY: 0 }) const moveTouchId = useRef(null) const lookTouchId = useRef(null) // Move joystick const handleMoveStart = useCallback((e: React.TouchEvent) => { e.preventDefault() const touch = e.changedTouches[0] moveTouchId.current = touch.identifier lookRef.current.lastX = touch.clientX lookRef.current.lastY = touch.clientY setMoveActive(true) }, []) const handleMoveMove = useCallback((e: React.TouchEvent) => { e.preventDefault() for (let i = 0; i < e.changedTouches.length; i++) { const touch = e.changedTouches[i] if (touch.identifier === moveTouchId.current) { const dx = (touch.clientX - lookRef.current.lastX) / 40 const dz = (touch.clientY - lookRef.current.lastY) / 40 moveRef.current = { x: Math.max(-1, Math.min(1, dx)), z: Math.max(-1, Math.min(1, dz)), } ;(window as any).__MC_MOBILE_MOVE = moveRef.current } } }, []) const handleMoveEnd = useCallback(() => { moveTouchId.current = null moveRef.current = { x: 0, z: 0 } ;(window as any).__MC_MOBILE_MOVE = null setMoveActive(false) }, []) // Look joystick const handleLookStart = useCallback((e: React.TouchEvent) => { e.preventDefault() const touch = e.changedTouches[0] lookTouchId.current = touch.identifier lookRef.current = { lastX: touch.clientX, lastY: touch.clientY } setLookActive(true) }, []) const handleLookMove = useCallback((e: React.TouchEvent) => { e.preventDefault() for (let i = 0; i < e.changedTouches.length; i++) { const touch = e.changedTouches[i] if (touch.identifier === lookTouchId.current) { const dx = touch.clientX - lookRef.current.lastX const dy = touch.clientY - lookRef.current.lastY lookRef.current = { lastX: touch.clientX, lastY: touch.clientY } const player = usePlayerStore.getState().player if (player) { const sensitivity = 0.004 const yaw = player.rotation[0] - dx * sensitivity const pitch = Math.max(-Math.PI / 2 + 0.01, Math.min(Math.PI / 2 - 0.01, player.rotation[1] - dy * sensitivity)) usePlayerStore.getState().updateRotation([yaw, pitch]) } } } }, []) const handleLookEnd = useCallback(() => { lookTouchId.current = null setLookActive(false) }, []) const handleJump = useCallback(() => { ;(window as any).__MC_MOBILE_JUMP = true setTimeout(() => { (window as any).__MC_MOBILE_JUMP = false }, 100) }, []) const handleBreak = useCallback(() => { ;(window as any).__MC_MOBILE_BREAK = true }, []) const handlePlace = useCallback(() => { ;(window as any).__MC_MOBILE_PLACE = true }, []) return (
{/* Move joystick - left side */}
{moveActive ? '●' : 'Move'}
{/* Look area - right side */}
{lookActive ? '●' : 'Look'}
{/* Action buttons */}
{/* Jump */}
{/* Break/Place buttons */}
{/* Fly toggle */} {/* Inventory */}
) }