aboutsummaryrefslogtreecommitdiff
path: root/src/components/player.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/player.jsx')
-rw-r--r--src/components/player.jsx78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/components/player.jsx b/src/components/player.jsx
new file mode 100644
index 0000000..bd8e392
--- /dev/null
+++ b/src/components/player.jsx
@@ -0,0 +1,78 @@
+import { Capsule, PerspectiveCamera, PointerLockControls } from "@react-three/drei";
+import { useFrame } from "@react-three/fiber";
+import { useContext, useEffect, useRef } from "react";
+import { AppContext } from "../App";
+import { CapsuleCollider, RapierCollider, RapierRigidBody, RigidBody, useRapier, vec3 } from "@react-three/rapier";
+import { quat } from "@react-three/rapier";
+import { Euler, Object3D, Vector3 } from "three";
+import { useBeforePhysicsStep } from "@react-three/rapier";
+
+const _movespeed = 3.0;
+
+export default function Player() {
+ const controlsRef = useRef();
+ const { keys } = useContext(AppContext);
+ const rapier = useRapier();
+ const controller = useRef();
+ const collider = useRef();
+ const rigidbody = useRef();
+ const camera = useRef();
+
+ const refState = useRef({
+ grounded: false,
+ jumping: false,
+ velocity: vec3(),
+ });
+
+ useEffect(() => {
+ const c = rapier.world.createCharacterController(0.1);
+ c.setApplyImpulsesToDynamicBodies(true);
+ c.setCharacterMass(0.2);
+ controller.current = c;
+ }, [rapier]);
+
+ useBeforePhysicsStep((world) => {
+ if (controller.current && rigidbody.current && collider.current) {
+ const move_axis_x = +(keys.includes('KeyD')) - +(keys.includes('KeyA'));
+ const move_axis_z = +(keys.includes('KeyW')) - +(keys.includes('KeyS'));
+
+ const { velocity } = refState.current;
+ const position = vec3(rigidbody.current.translation());
+ const movement = vec3();
+
+ const forward = new Vector3();
+ camera.current.getWorldDirection(forward);
+ const left = new Vector3().crossVectors(forward, camera.current.up);
+
+ movement.x += move_axis_z * world.timestep * _movespeed * forward.x;
+ movement.z += move_axis_z * world.timestep * _movespeed * forward.z;
+ movement.x += move_axis_x * world.timestep * _movespeed * left.x;
+ movement.z += move_axis_x * world.timestep * _movespeed * left.z;
+
+ if (refState.current.grounded) {
+ velocity.y = 0;
+ } else {
+ velocity.y -= 9.81 * world.timestep * world.timestep;
+ }
+
+ movement.add(velocity);
+
+ controller.current.computeColliderMovement(collider.current, movement);
+ refState.current.grounded = controller.current.computedGrounded();
+
+ let correctedMovement = controller.current.computedMovement();
+ position.add(vec3(correctedMovement));
+
+ rigidbody.current.setNextKinematicTranslation(position);
+ }
+ });
+
+ return (
+ <RigidBody type="kinematicPosition" colliders={false} ref={rigidbody} position={[0, 2, 0]}>
+ <PerspectiveCamera makeDefault position={[0, .9, 0]} fov={90} ref={camera} />
+ <PointerLockControls ref={controlsRef} />
+ <CapsuleCollider ref={collider} args={[1, 0.5]} />
+ </RigidBody>
+ );
+}
+