player camera and controls during game
This commit is contained in:
@@ -3,11 +3,11 @@ import type { Character } from "../types";
|
||||
|
||||
export const CharacterView = observer(function ({ character }: { character: Character }) {
|
||||
|
||||
const pos = character.position;
|
||||
const pos = character.transform.position;
|
||||
|
||||
return <mesh
|
||||
position={[pos[0] + 0.5, pos[1] + 0.5, pos[2] + 0.5]}
|
||||
rotation={character.look}
|
||||
rotation={character.transform.look}
|
||||
>
|
||||
<boxGeometry args={[0.8, 0.8, 0.8]} />
|
||||
<meshStandardMaterial color="yellow" />
|
||||
|
||||
@@ -1,10 +1,46 @@
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { SceneView } from "./SceneView";
|
||||
import { state } from "../state";
|
||||
import { useFrame } from "@react-three/fiber";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { PointerLockControls, useKeyboardControls } from "@react-three/drei";
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
function PlayerMovement() {
|
||||
const [, get] = useKeyboardControls();
|
||||
const dirty = useRef(false);
|
||||
|
||||
useFrame(({ camera }, dt) => {
|
||||
const { forward, backward, left, right } = get();
|
||||
const speed = 5 * dt;
|
||||
if (forward) { camera.translateZ(-speed); dirty.current = true; }
|
||||
if (backward) { camera.translateZ( speed); dirty.current = true; }
|
||||
if (left) { camera.translateX(-speed); dirty.current = true; }
|
||||
if (right) { camera.translateX( speed); dirty.current = true; }
|
||||
|
||||
if (!dirty.current) return;
|
||||
dirty.current = false;
|
||||
|
||||
const [rx, ry, rz] = camera.rotation.toArray();
|
||||
state.game?.setCharacterTransform({
|
||||
position: camera.position.toArray(),
|
||||
look: [rx, ry, rz],
|
||||
});
|
||||
});
|
||||
|
||||
return <PointerLockControls onChange={() => { dirty.current = true; }} />;
|
||||
}
|
||||
|
||||
export const GameView = observer(function () {
|
||||
const game = state.game;
|
||||
const { camera } = useThree();
|
||||
|
||||
useEffect(() => {
|
||||
if (!game)
|
||||
return;
|
||||
const { position, look } = game.camera;
|
||||
camera.position.set(position[0], position[1], position[2]);
|
||||
camera.rotation.set(look[0], look[1], look[2]);
|
||||
}, []);
|
||||
|
||||
useFrame((_, delta) => {
|
||||
state.game?.tick(delta);
|
||||
@@ -13,5 +49,8 @@ export const GameView = observer(function () {
|
||||
if (!game)
|
||||
return null;
|
||||
|
||||
return <SceneView scene={game.scene} />;
|
||||
return (<>
|
||||
<PlayerMovement />
|
||||
<SceneView scene={game.scene} />
|
||||
</>);
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Canvas, useFrame, useThree } from '@react-three/fiber';
|
||||
import { Stats } from '@react-three/drei';
|
||||
import { KeyboardControls, Stats } from '@react-three/drei';
|
||||
import { useRef } from 'react';
|
||||
|
||||
function RenderInfoUpdater({ domRef }: { domRef: React.RefObject<HTMLDivElement | null> }) {
|
||||
@@ -30,6 +30,12 @@ export const ThreeView = observer(function () {
|
||||
const isGame = state.isGamePlaying;
|
||||
const infoRef = useRef<HTMLDivElement>(null);
|
||||
return (
|
||||
<KeyboardControls map={[
|
||||
{ name: 'forward', keys: ['ArrowUp', 'w', 'W'] },
|
||||
{ name: 'backward', keys: ['ArrowDown', 's', 'S'] },
|
||||
{ name: 'left', keys: ['ArrowLeft', 'a', 'A'] },
|
||||
{ name: 'right', keys: ['ArrowRight', 'd', 'D'] },
|
||||
]}>
|
||||
<div style={{ position: 'relative', width: '800px', height: '600px', border: '1px solid #333', borderRadius: '8px', overflow: 'hidden' }}>
|
||||
<Canvas
|
||||
// camera={state.world.character.camera}
|
||||
@@ -60,5 +66,6 @@ export const ThreeView = observer(function () {
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</KeyboardControls>
|
||||
)
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user