diff --git a/src/components/Experience.jsx b/src/components/Experience.jsx index 121c190..3e8af61 100644 --- a/src/components/Experience.jsx +++ b/src/components/Experience.jsx @@ -16,8 +16,7 @@ export const Experience = () => { { if (driftLeft.current || driftRight.current) { const oscillation = Math.sin(time * 1000) * 0.1 + const vibration = oscillation+ 0.9 if (turboColor === 0xffffff) { setScale(vibration * 0.8) @@ -258,11 +259,12 @@ export const PlayerController = () => { onCollisionEnter={(event) => { isOnFloor.current = true }} + onCollisionExit={(event) => { + isOnFloor.current = false + }} + /> - {/* onCollisionEnter= - {(event) => { - isOnFloor.current = false - }} */} + { useFrame((_, delta) => { if (turboColor === 0xffffff) return; - if (size < 3) { - setSize((size) => size + 0.5 * delta * 144); + if (size < 5) { + setSize((size) => Math.min(size + 0.3 * delta * 144, 5)); } else if (opacity > 0) { - setOpacity((opacity) => opacity - 0.05 * delta * 144); - setSize((size) => size + 0.2 * delta * 144); + setOpacity((opacity) => Math.max(opacity - 0.2 * delta * 144, 0)); + setSize((size) => Math.max(size - 0.2 * delta * 144, 0)); } }); diff --git a/src/components/Skid.jsx b/src/components/Skid.jsx new file mode 100644 index 0000000..c2f6d7b --- /dev/null +++ b/src/components/Skid.jsx @@ -0,0 +1,51 @@ +import { Euler, Object3D, Vector3, Matrix4 } from 'three'; +import { useRef, useLayoutEffect } from 'react'; +import { useFrame } from '@react-three/fiber'; + +import { getState, mutation, useStore } from '../store'; + +const e = new Euler(); +const m = new Matrix4(); +const o = new Object3D(); +const v = new Vector3(); + +export function Skid({ count = 500, opacity = 0.5, size = 0.4 }) { + const ref = useRef(null); + const [chassisBody, wheels] = useStore((state) => [state.chassisBody, state.wheels]); + + let brake; + let index = 0; + useFrame(() => { + brake = getState().controls.brake; + if (chassisBody.current && wheels[2].current && wheels[3].current && brake && mutation.speed > 10) { + e.setFromRotationMatrix(m.extractRotation(chassisBody.current.matrix)); + setItemAt(ref.current, e, wheels[2].current, index++); + if (index === count) index = 0; + } + }); + + useLayoutEffect(() => { + if (ref.current) { + ref.current.geometry.rotateX(-Math.PI / 2); + return () => { + ref.current.geometry.rotateX(Math.PI / 2); + }; + } + }); + + return ( + + + + + ); +} + +function setItemAt(instances, rotation, wheel, index) { + o.position.copy(wheel.getWorldPosition(v)); + o.rotation.copy(rotation); + o.scale.setScalar(1); + o.updateMatrix(); + instances.setMatrixAt(index, o.matrix); + instances.instanceMatrix.needsUpdate = true; +} diff --git a/src/components/store.jsx b/src/components/store.jsx index bb1e5be..c6f089e 100644 --- a/src/components/store.jsx +++ b/src/components/store.jsx @@ -4,6 +4,8 @@ export const useStore = create((set, get) => ({ return : { particles1: [], particles2: [], + bodyPosition: [0, 0, 0], + bodyRotation: [0, 0, 0], actions : { addParticle1: (particle) => { set((state) => ({