|
|
|
@ -12,7 +12,11 @@ const keys: Record<string, string> = {
|
|
|
|
|
KeyS: 'backward',
|
|
|
|
|
KeyA: 'left',
|
|
|
|
|
KeyD: 'right',
|
|
|
|
|
ShiftLeft: 'running',
|
|
|
|
|
ArrowUp: 'forward',
|
|
|
|
|
ArrowDown: 'backward',
|
|
|
|
|
ArrowLeft: 'left',
|
|
|
|
|
ArrowRight: 'right',
|
|
|
|
|
ShiftLeft: 'run',
|
|
|
|
|
Space: 'jump',
|
|
|
|
|
}
|
|
|
|
|
const moveFieldByKey = (key: string) => keys[key]
|
|
|
|
@ -26,15 +30,16 @@ const usePlayerControls = () => {
|
|
|
|
|
backward: false,
|
|
|
|
|
left: false,
|
|
|
|
|
right: false,
|
|
|
|
|
running: false,
|
|
|
|
|
run: false,
|
|
|
|
|
jump: false,
|
|
|
|
|
})
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const handleKeyDown = (e: Event) => {
|
|
|
|
|
setMovement((m) => ({ ...m, [moveFieldByKey(e.code)]: true }))
|
|
|
|
|
}
|
|
|
|
|
const handleKeyUp = (e: Event) =>
|
|
|
|
|
const handleKeyUp = (e: Event) => {
|
|
|
|
|
setMovement((m) => ({ ...m, [moveFieldByKey(e.code)]: false }))
|
|
|
|
|
}
|
|
|
|
|
document.addEventListener('keydown', handleKeyDown)
|
|
|
|
|
document.addEventListener('keyup', handleKeyUp)
|
|
|
|
|
return () => {
|
|
|
|
@ -48,30 +53,32 @@ const usePlayerControls = () => {
|
|
|
|
|
// TODO Improve physics in player
|
|
|
|
|
const Player = (props: SphereProps) => {
|
|
|
|
|
const socket = useStore((state) => state.socket)
|
|
|
|
|
const { forward, backward, left, right, running } = usePlayerControls()
|
|
|
|
|
const pointerLocked = useStore((state) => state.pointerLocked)
|
|
|
|
|
const { forward, backward, left, right, run } = usePlayerControls()
|
|
|
|
|
const { camera } = useThree()
|
|
|
|
|
const [ref, api] = useSphere(() => ({
|
|
|
|
|
type: 'Dynamic',
|
|
|
|
|
fixedRotation: true,
|
|
|
|
|
position: [0, 1.5, 0],
|
|
|
|
|
args: 0.2,
|
|
|
|
|
mass: 9,
|
|
|
|
|
position: [0, 2, 0],
|
|
|
|
|
args: 1,
|
|
|
|
|
mass: 5,
|
|
|
|
|
linearDamping: 0,
|
|
|
|
|
angularDamping: 0,
|
|
|
|
|
material: { friction: 0, restitution: 0 },
|
|
|
|
|
material: { friction: 10, restitution: 0 },
|
|
|
|
|
...props,
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const socketEmitTransformInterval = setInterval(() => {
|
|
|
|
|
if (socket && ref.current && camera) {
|
|
|
|
|
const cameraRotation = camera.rotation.toArray()
|
|
|
|
|
socket.emit('transform', {
|
|
|
|
|
position: [
|
|
|
|
|
ref.current.position.x,
|
|
|
|
|
ref.current.position.y,
|
|
|
|
|
ref.current.position.z,
|
|
|
|
|
],
|
|
|
|
|
rotation: [camera.rotation.x, camera.rotation.y, camera.rotation.z],
|
|
|
|
|
rotation: [cameraRotation[0], cameraRotation[1], cameraRotation[2]],
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}, 16)
|
|
|
|
@ -87,7 +94,7 @@ const Player = (props: SphereProps) => {
|
|
|
|
|
if (!ref.current) return
|
|
|
|
|
camera.position.set(
|
|
|
|
|
ref.current.position.x,
|
|
|
|
|
ref.current.position.y + 1,
|
|
|
|
|
ref.current.position.y + 0.4,
|
|
|
|
|
ref.current.position.z,
|
|
|
|
|
)
|
|
|
|
|
frontVector.set(0, 0, Number(backward) - Number(forward))
|
|
|
|
@ -95,10 +102,10 @@ const Player = (props: SphereProps) => {
|
|
|
|
|
direction
|
|
|
|
|
.subVectors(frontVector, sideVector)
|
|
|
|
|
.normalize()
|
|
|
|
|
.multiplyScalar(running ? SPEED * 2 : SPEED)
|
|
|
|
|
.multiplyScalar(run ? SPEED * 2 : SPEED)
|
|
|
|
|
.applyEuler(camera.rotation)
|
|
|
|
|
|
|
|
|
|
if (forward || backward || left || right) {
|
|
|
|
|
if (pointerLocked && (forward || backward || left || right)) {
|
|
|
|
|
api.velocity.set(direction.x, -SPEED / 2, direction.z)
|
|
|
|
|
} else {
|
|
|
|
|
api.velocity.set(0, 0, 0)
|
|
|
|
|