@@ -69,9 +77,9 @@ export default function Character({ pos }) {
{
+ // 플레이어 상태
+
+ const rigidbody = useRef()
+ const isOnFloor = useRef(true)
+ const character = useRef()
+
+ useEffect(() => {
+ if (!rigidbody.current) return
+ rigidbody.current.setTranslation(vec3({ x: pos.x, y: pos.y, z: pos.z }))
+ rigidbody.current.setLinvel(vec3({ x: pos.x, y: pos.y, z: pos.z }))
+ // 캐릭터가 이동할 때마다 좌표 받아오기
+ // console.log('rigidbody.current', rigidbody.current.linvel())
+ }, [pos])
+
+ useFrame((state, delta) => {
+ if (!rigidbody.current) return
+
+ // vec3({ x: pos.x, y: pos.y, z: pos.z })
+
+ const impulse = { x: 0, y: 0, z: 0 }
+ if (moveState === playerMoveStateEnum.JUMP && isOnFloor.current) {
+ impulse.y += JUMP_FORCE
+ isOnFloor.current = false
+ }
+
+ const linvel = rigidbody.current.linvel()
+ let changeRotation = false
+ if (direction === 'right') {
+ if (moveState === playerMoveStateEnum.RUN && linvel.x < MAX_VEL) impulse.x += MOVEMENT_SPEED
+ changeRotation = true
+ }
+ if (direction === 'left') {
+ if (moveState === playerMoveStateEnum.RUN && linvel.x > -MAX_VEL) impulse.x -= MOVEMENT_SPEED
+ changeRotation = true
+ }
+ if (direction === 'back') {
+ if (moveState === playerMoveStateEnum.RUN && linvel.z < MAX_VEL) impulse.z += MOVEMENT_SPEED
+ changeRotation = true
+ }
+ if (direction === 'forward') {
+ if (moveState === playerMoveStateEnum.RUN && linvel.z > -MAX_VEL) impulse.z -= MOVEMENT_SPEED
+ changeRotation = true
+ }
+
+ rigidbody.current.applyImpulse(impulse, true)
+
+ // if (Math.abs(linvel.x) > RUN_VEL || Math.abs(linvel.z) > RUN_VEL) {
+ // if (isOnFloor.current && moveState !== playerMoveStateEnum.RUN) {
+ // setPlayerMoveState(playerMoveStateEnum.RUN)
+ // }
+ // } else {
+ // if (isOnFloor.current && moveState !== playerMoveStateEnum.IDLE) {
+ // setPlayerMoveState(playerMoveStateEnum.IDLE)
+ // }
+ // }
+
+ if (changeRotation) {
+ const angle = Math.atan2(linvel.x, linvel.z)
+ character.current.rotation.y = angle
+ }
+ })
+
+ const resetPosition = () => {
+ rigidbody.current.setTranslation(vec3({ x: 0, y: 0, z: 0 }))
+ rigidbody.current.setLinvel(vec3({ x: 0, y: 0, z: 0 }))
+ }
+ return (
+
+ {
+ isOnFloor.current = true
+ }}
+ onIntersectionEnter={({ other }) => {
+ if (other.rigidBodyObject.name === 'void') {
+ resetPosition()
+ }
+ }}
+ >
+
+
+
+
+
+
+ )
+}
+
+export default OtherController
diff --git a/frontend/app/(page)/(needProtection)/game/component/OtherPlayers.tsx b/frontend/app/(page)/(needProtection)/game/component/OtherPlayers.tsx
new file mode 100644
index 0000000..aaa69b8
--- /dev/null
+++ b/frontend/app/(page)/(needProtection)/game/component/OtherPlayers.tsx
@@ -0,0 +1,50 @@
+import React from 'react'
+import { useMainSocketStore } from '../../channel/lib/store'
+import { playerMoveStateEnum } from '../lib/store'
+import OtherController from './OtherController'
+
+// forward: 'forward',
+// back: 'back',
+// left: 'left',
+// right: 'right',
+// jump: 'jump',
+// RED, BLUE, NONE
+
+export interface IOtherStatus {
+ pos: { x: number; y: number; z: number }
+ moveState: string
+ characterType: number
+ direction: string
+ nickname: string
+ team: string
+}
+
+const samplePlayers: IOtherStatus[] = [
+ {
+ pos: { x: 0, y: 0, z: 3 },
+ moveState: playerMoveStateEnum.IDLE,
+ characterType: 2,
+ direction: 'right',
+ nickname: '??dsad',
+ team: 'red',
+ },
+ // {
+ // pos: { x: 4, y: 0, z: 0 },
+ // moveState: playerMoveStateEnum.RUN,
+ // characterType: 1,
+ // direction: 'right',
+ // nickname: '!!!옆에대단한사람이있어요',
+ // team: 'blue',
+ // },
+]
+
+export default function OtherPlayers() {
+ const { socket } = useMainSocketStore()
+ return (
+ <>
+ {samplePlayers.map((player, index) => {
+ return
+ })}
+ >
+ )
+}