diff --git a/public/fire_01.png b/public/fire_01.png new file mode 100644 index 0000000..f5c9219 Binary files /dev/null and b/public/fire_01.png differ diff --git a/public/fire_02.png b/public/fire_02.png new file mode 100644 index 0000000..f291571 Binary files /dev/null and b/public/fire_02.png differ diff --git a/src/components/Experience.jsx b/src/components/Experience.jsx index e7597ea..9b6a6c1 100644 --- a/src/components/Experience.jsx +++ b/src/components/Experience.jsx @@ -39,7 +39,7 @@ export const Experience = () => { > - {/* */} + { + const texture = useLoader(THREE.TextureLoader, png); + const pointsRef = useRef(); + const [size, setSize] = useState(1); + const [opacity, setOpacity] = useState(1); + const [initialized, setInitialized] = useState(false); + + useEffect(() => { + const timer = setTimeout(() => { + setInitialized(true); + }, delay); + return () => clearTimeout(timer); + }, [delay]); + + const points = React.useMemo(() => { + const geom = new THREE.BufferGeometry(); + geom.setAttribute( + "position", + new THREE.Float32BufferAttribute(position, 3) + ); + return geom; + }, [position]); + + useFrame(() => { + if (!initialized) return; + + pointsRef.current.position.y += 0.03; + pointsRef.current.position.z += 0.06; + if(pointsRef.current.position.y > 0.4) { + pointsRef.current.position.y = 0; + pointsRef.current.position.z = 0; + setOpacity(1); + } + if(opacity > 0) { + setOpacity((opacity) => opacity - 0.05); + } + }); + + return ( + + + + ); +}; diff --git a/src/components/FlameParticles.jsx b/src/components/FlameParticles.jsx new file mode 100644 index 0000000..df48398 --- /dev/null +++ b/src/components/FlameParticles.jsx @@ -0,0 +1,168 @@ +import { FlameParticle } from "./FlameParticle"; + +export const FlameParticles = ({ isBoosting }) => { + + if (!isBoosting) { + return null; + } + return ( + + {/* bottom left */} + + + + + + + + + + {/* bottom right */} + + + + + + + + + {/* top left */} + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/components/PlayerController.jsx b/src/components/PlayerController.jsx index 87e6059..8609609 100644 --- a/src/components/PlayerController.jsx +++ b/src/components/PlayerController.jsx @@ -21,6 +21,8 @@ import { DriftParticlesLeft } from "./DriftParticlesLeft"; import { DriftParticlesRight } from "./DriftParticlesRight"; import FakeGlowMaterial from "./FakeGlow/FakeGlowMaterial"; import { PointParticle } from "./PointParticle"; +import { FlameParticle } from "./FlameParticle"; +import { FlameParticles } from "./FlameParticles"; export const PlayerController = () => { const upPressed = useKeyboardControls((state) => state[Controls.up]); @@ -41,7 +43,7 @@ export const PlayerController = () => { const MaxSteeringSpeed = 0.01; const [currentSteeringSpeed, setCurrentSteeringSpeed] = useState(0); const [currentSpeed, setCurrentSpeed] = useState(initialSpeed); - const camMaxOffset = 0.5; + const camMaxOffset = 1; let steeringAngle = 0; const isOnFloor = useRef(false); const jumpForce = useRef(0); @@ -57,7 +59,7 @@ export const PlayerController = () => { const purpleTurboThreshold = 60; const [turboColor, setTurboColor] = useState(0xffffff); const boostDuration = useRef(0); - const isBoosting = useRef(false); + const [isBoosting, setIsBoosting] = useState(false); let targetXPosition = 0; let targetZPosition = 8; const [steeringAngleWheels, setSteeringAngleWheels] = useState(0); @@ -261,8 +263,10 @@ export const PlayerController = () => { setCurrentSpeed(boostSpeed); boostDuration.current -= 1; targetZPosition = 10; + setIsBoosting(true); } else if (boostDuration.current <= 1) { targetZPosition = 8; + setIsBoosting(false); } // CAMERA WORK @@ -355,7 +359,8 @@ export const PlayerController = () => { opacity={0.4} /> - + {/* */} +