8 changed files with 139 additions and 137 deletions

No files matched your search

+1 -1
View File
@@ -43,7 +43,7 @@ function App() {
<KeyboardControls map={map}> <KeyboardControls map={map}>
<Experience /> <Experience />
</KeyboardControls> </KeyboardControls>
{/* <Stats /> */} <Stats />
</Physics> </Physics>
</Suspense> </Suspense>
</Canvas> </Canvas>
+6 -6
View File
@@ -3,23 +3,23 @@ import { Particles3 } from "./Particles3";
export const DriftParticlesLeft = ({turboColor,scale, ...props}) => { export const DriftParticlesLeft = ({turboColor,scale, ...props}) => {
if(scale < 0.8) { // if(scale < 0.8) {
return null; // return null;
} // }
return ( return (
<group {...props}> <group {...props}>
<Particles1 turboColor={turboColor} scale={scale} /> <Particles1 turboColor={turboColor} scale={scale} />
{/* <Particles1 turboColor={turboColor} scale={scale} />
<Particles1 turboColor={turboColor} scale={scale} /> <Particles1 turboColor={turboColor} scale={scale} />
<Particles1 turboColor={turboColor} scale={scale} /> <Particles1 turboColor={turboColor} scale={scale} />
<Particles1 turboColor={turboColor} scale={scale} /> <Particles1 turboColor={turboColor} scale={scale} />
<Particles1 turboColor={turboColor} scale={scale} /> <Particles1 turboColor={turboColor} scale={scale} />
<Particles1 turboColor={turboColor} scale={scale} /> <Particles1 turboColor={turboColor} scale={scale} />
<Particles1 turboColor={turboColor} scale={scale} /> <Particles1 turboColor={turboColor} scale={scale} />
<Particles1 turboColor={turboColor} scale={scale} /> <Particles1 turboColor={turboColor} scale={scale} /> */}
<Particles1 turboColor={turboColor} scale={scale} />
<Particles3 turboColor={turboColor} scale={scale} /> {/* <Particles3 turboColor={turboColor} scale={scale} /> */}
</group> </group>
) )
+3 -14
View File
@@ -3,24 +3,13 @@ import { Particles4 } from "./Particles4";
export const DriftParticlesRight = ({turboColor,scale, ...props}) => { export const DriftParticlesRight = ({turboColor,scale, ...props}) => {
if(scale < 0.8) { // if(scale < 0.8) {
return null; // return null;
} // }
return ( return (
<group {...props}> <group {...props}>
<Particles2 turboColor={turboColor} scale={scale} /> <Particles2 turboColor={turboColor} scale={scale} />
<Particles2 turboColor={turboColor} scale={scale} />
<Particles2 turboColor={turboColor} scale={scale} />
<Particles2 turboColor={turboColor} scale={scale} />
<Particles2 turboColor={turboColor} scale={scale} />
<Particles2 turboColor={turboColor} scale={scale} />
<Particles2 turboColor={turboColor} scale={scale} />
<Particles2 turboColor={turboColor} scale={scale} />
<Particles2 turboColor={turboColor} scale={scale} />
<Particles4 turboColor={turboColor} scale={scale} />
</group> </group>
) )
+30 -19
View File
@@ -1,22 +1,21 @@
import React, { useState, useEffect, useRef } from "react"; import React, { useRef, useMemo } from "react";
import { useLoader, useFrame } from "@react-three/fiber"; import { useLoader, useFrame } from "@react-three/fiber";
import * as THREE from "three"; import * as THREE from "three";
export const FlameParticle = ({ position, png, turboColor, delay = 0 }) => { export const FlameParticle = ({ position, png, isBoosting, delay = 0 }) => {
const texture = useLoader(THREE.TextureLoader, png); const texture = useLoader(THREE.TextureLoader, png);
const pointsRef = useRef(); const pointsRef = useRef();
const [size, setSize] = useState(1); const initialized = useRef(false);
const [opacity, setOpacity] = useState(1);
const [initialized, setInitialized] = useState(false);
useEffect(() => { // Initialize after delay
useMemo(() => {
const timer = setTimeout(() => { const timer = setTimeout(() => {
setInitialized(true); initialized.current = true;
}, delay); }, delay);
return () => clearTimeout(timer); return () => clearTimeout(timer);
}, [delay]); }, [delay]);
const points = React.useMemo(() => { const points = useMemo(() => {
const geom = new THREE.BufferGeometry(); const geom = new THREE.BufferGeometry();
geom.setAttribute( geom.setAttribute(
"position", "position",
@@ -26,29 +25,41 @@ export const FlameParticle = ({ position, png, turboColor, delay = 0 }) => {
}, [position]); }, [position]);
useFrame(({clock}, delta) => { useFrame(({clock}, delta) => {
if (!initialized) return; if (!initialized.current) return;
pointsRef.current.position.y += 0.03 * delta * 144; const pointsCurrent = pointsRef.current;
pointsRef.current.position.z += 0.06 * delta * 144;
if(pointsRef.current.position.y > 0.4) { if (isBoosting) {
pointsRef.current.position.y = 0; // Update logic when boosting
pointsRef.current.position.z = 0; pointsCurrent.position.y += 0.03 * delta * 144;
setOpacity(1); pointsCurrent.position.z += 0.06 * delta * 144;
if(pointsCurrent.position.y > 0.4) {
pointsCurrent.position.y = 0;
pointsCurrent.position.z = 0;
pointsCurrent.material.opacity = 1;
} }
if(opacity > 0) {
setOpacity((opacity) => opacity - 0.05 * delta * 144); if(pointsCurrent.material.opacity > 0) {
pointsCurrent.material.opacity -= 0.05 * delta * 144;
}
} else {
// Reset position and opacity when not boosting
pointsCurrent.position.y = 0;
pointsCurrent.position.z = 0;
pointsCurrent.material.opacity = 0;
} }
}); });
return ( return (
<points ref={pointsRef} geometry={points}> <points ref={pointsRef} geometry={points}>
<pointsMaterial <pointsMaterial
size={size} size={1}
alphaMap={texture} alphaMap={texture}
transparent={true} transparent={true}
depthWrite={false} depthWrite={false}
color={0x000000} color={0x000000}
opacity={opacity} opacity={1}
toneMapped={false} toneMapped={false}
/> />
</points> </points>
+25 -27
View File
@@ -2,9 +2,7 @@ import { FlameParticle } from "./FlameParticle";
export const FlameParticles = ({ isBoosting }) => { export const FlameParticles = ({ isBoosting }) => {
if (!isBoosting) {
return null;
}
return ( return (
<group> <group>
{/* bottom left */} {/* bottom left */}
@@ -12,37 +10,37 @@ export const FlameParticles = ({ isBoosting }) => {
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_01.png" png="./fire_01.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={0} delay={0}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_02.png" png="./fire_02.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={100} delay={100}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_01.png" png="./fire_01.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={200} delay={200}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_02.png" png="./fire_02.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={300} delay={300}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_02.png" png="./fire_02.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={400} delay={400}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_01.png" png="./fire_01.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={500} delay={500}
/> />
</group> </group>
@@ -52,37 +50,37 @@ export const FlameParticles = ({ isBoosting }) => {
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_01.png" png="./fire_01.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={0} delay={0}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_02.png" png="./fire_02.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={100} delay={100}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_01.png" png="./fire_01.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={200} delay={200}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_02.png" png="./fire_02.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={300} delay={300}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_01.png" png="./fire_01.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={400} delay={400}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_02.png" png="./fire_02.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={500} delay={500}
/> />
</group> </group>
@@ -91,37 +89,37 @@ export const FlameParticles = ({ isBoosting }) => {
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_02.png" png="./fire_02.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={0} delay={0}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_01.png" png="./fire_01.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={100} delay={100}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_02.png" png="./fire_02.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={200} delay={200}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_01.png" png="./fire_01.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={300} delay={300}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_02.png" png="./fire_02.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={400} delay={400}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_01.png" png="./fire_01.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={500} delay={500}
/> />
</group> </group>
@@ -129,37 +127,37 @@ export const FlameParticles = ({ isBoosting }) => {
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_02.png" png="./fire_02.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={0} delay={0}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_01.png" png="./fire_01.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={100} delay={100}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_02.png" png="./fire_02.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={200} delay={200}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_01.png" png="./fire_01.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={300} delay={300}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_02.png" png="./fire_02.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={400} delay={400}
/> />
<FlameParticle <FlameParticle
position={[0, 0, 0]} position={[0, 0, 0]}
png="./fire_01.png" png="./fire_01.png"
turboColor={0xfea347} isBoosting={isBoosting}
delay={500} delay={500}
/> />
</group> </group>
+36 -34
View File
@@ -1,55 +1,57 @@
import { useRef } from "react"; import { useRef, useMemo } from "react";
import { useFrame } from "@react-three/fiber"; import { useFrame } from "@react-three/fiber";
import * as THREE from 'three'; import * as THREE from 'three';
export const Particles1 = ({ turboColor, scale, ...props }) => { export const Particles1 = ({ turboColor, scale, numParticles = 50, ...props }) => {
const ref = useRef(); const instancedMeshRef = useRef();
const velocity = useRef({ const particlesData = useMemo(() => {
x: -Math.random() * 0.05, return new Array(numParticles).fill().map(() => ({
y: Math.random() * 0.05, position: new THREE.Vector3(-0.6, 0.05, 0.5),
z: Math.random() * 0.02, velocity: new THREE.Vector3(-Math.random() * 0.05, Math.random() * 0.05, Math.random() * 0.02),
}); gravity: -0.003
const gravity = -0.003; }));
}, [numParticles]);
useFrame((state, delta) => { useFrame((state, delta) => {
let position = ref.current.position; if (!instancedMeshRef.current) {
let velocityVector = new THREE.Vector3(velocity.current.x, velocity.current.y, velocity.current.z); return;
// Adjust gravity and velocity based on delta
velocity.current.y += gravity * delta * 144; // Multiply by 144 to scale for 144 FPS
// Scale velocity changes by delta
position.x += velocity.current.x * delta * 144;
position.y += velocity.current.y * delta * 144;
position.z += velocity.current.z * delta * 144;
if (!velocityVector.equals(new THREE.Vector3(0, 0, 0))) {
const alignmentQuaternion = new THREE.Quaternion();
alignmentQuaternion.setFromUnitVectors(new THREE.Vector3(0, 1, 0), velocityVector.normalize());
ref.current.quaternion.slerp(alignmentQuaternion, 0.1);
} }
if (position.y < 0.05) { // Manage visibility directly in the animation loop
position.set(-0.6, 0.05, 0.5); instancedMeshRef.current.visible = scale >= 0.8;
velocity.current = {
x: -Math.random() * 0.05, if (scale < 0.8) {
y: Math.random() * 0.05, return;
z: Math.random() * 0.02,
};
} }
ref.current.position.set(position.x, position.y, position.z); const deltaScaled = delta * 144; // Scale for 144 FPS
particlesData.forEach((particle, i) => {
particle.velocity.y += particle.gravity * deltaScaled;
particle.position.x += particle.velocity.x * deltaScaled;
particle.position.y += particle.velocity.y * deltaScaled;
particle.position.z += particle.velocity.z * deltaScaled;
if (particle.position.y < 0.05) {
particle.position.set(-0.6, 0.05, 0.5);
particle.velocity.set(-Math.random() * 0.05, Math.random() * 0.05, Math.random() * 0.02);
}
const matrix = new THREE.Matrix4();
matrix.setPosition(particle.position);
instancedMeshRef.current.setMatrixAt(i, matrix);
}); });
instancedMeshRef.current.instanceMatrix.needsUpdate = true;
});
return ( return (
<mesh ref={ref} position={[-0.6, 0.05, 0.5]} scale={[scale, scale * 5, scale]}> <instancedMesh ref={instancedMeshRef} args={[null, null, numParticles]} visible={scale >= 0.8}>
<sphereGeometry args={[0.01, 16, 16]} /> <sphereGeometry args={[0.01, 16, 16]} />
<meshStandardMaterial <meshStandardMaterial
emissive={turboColor} emissive={turboColor}
toneMapped={false} toneMapped={false}
emissiveIntensity={5} emissiveIntensity={5}
/> />
</mesh> </instancedMesh>
); );
}; };
+36 -34
View File
@@ -1,55 +1,57 @@
import { useRef } from "react"; import { useRef, useMemo } from "react";
import { useFrame } from "@react-three/fiber"; import { useFrame } from "@react-three/fiber";
import * as THREE from 'three'; import * as THREE from 'three';
export const Particles2 = ({ turboColor, scale, ...props }) => { export const Particles2 = ({ turboColor, scale, numParticles = 50, ...props }) => {
const ref = useRef(); const instancedMeshRef = useRef();
const velocity = useRef({ const particlesData = useMemo(() => {
x: Math.random() * 0.05, return new Array(numParticles).fill().map(() => ({
y: Math.random() * 0.05, position: new THREE.Vector3(0.6, 0.05, 0.5),
z: Math.random() * 0.02, velocity: new THREE.Vector3(Math.random() * 0.05, Math.random() * 0.05, Math.random() * 0.02),
}); gravity: -0.003
const gravity = -0.003; }));
}, [numParticles]);
useFrame((state, delta) => { useFrame((state, delta) => {
let position = ref.current.position; if (!instancedMeshRef.current) {
let velocityVector = new THREE.Vector3(velocity.current.x, velocity.current.y, velocity.current.z); return;
// Adjust gravity and velocity based on delta
velocity.current.y += gravity * delta * 144; // Multiply by 144 to scale for 144 FPS
// Scale velocity changes by delta
position.x += velocity.current.x * delta * 144;
position.y += velocity.current.y * delta * 144;
position.z += velocity.current.z * delta * 144;
if (!velocityVector.equals(new THREE.Vector3(0, 0, 0))) {
const alignmentQuaternion = new THREE.Quaternion();
alignmentQuaternion.setFromUnitVectors(new THREE.Vector3(0, 1, 0), velocityVector.normalize());
ref.current.quaternion.slerp(alignmentQuaternion, 0.1);
} }
if (position.y < 0.05) { // Manage visibility directly in the animation loop
position.set(0.6, 0.05, 0.5); instancedMeshRef.current.visible = scale >= 0.8;
velocity.current = {
x: Math.random() * 0.05, if (scale < 0.8) {
y: Math.random() * 0.05, return;
z: Math.random() * 0.02,
};
} }
ref.current.position.set(position.x, position.y, position.z); const deltaScaled = delta * 144; // Scale for 144 FPS
particlesData.forEach((particle, i) => {
particle.velocity.y += particle.gravity * deltaScaled;
particle.position.x += particle.velocity.x * deltaScaled;
particle.position.y += particle.velocity.y * deltaScaled;
particle.position.z += particle.velocity.z * deltaScaled;
if (particle.position.y < 0.05) {
particle.position.set(0.6, 0.05, 0.5);
particle.velocity.set(Math.random() * 0.05, Math.random() * 0.05, Math.random() * 0.02);
}
const matrix = new THREE.Matrix4();
matrix.setPosition(particle.position);
instancedMeshRef.current.setMatrixAt(i, matrix);
}); });
instancedMeshRef.current.instanceMatrix.needsUpdate = true;
});
return ( return (
<mesh ref={ref} position={[0.6, 0.05, 0.5]} scale={[scale, scale * 5, scale]}> <instancedMesh ref={instancedMeshRef} args={[null, null, numParticles]} visible={scale >= 0.8}>
<sphereGeometry args={[0.01, 16, 16]} /> <sphereGeometry args={[0.01, 16, 16]} />
<meshStandardMaterial <meshStandardMaterial
emissive={turboColor} emissive={turboColor}
toneMapped={false} toneMapped={false}
emissiveIntensity={5} emissiveIntensity={5}
/> />
</mesh> </instancedMesh>
); );
}; };
+2 -2
View File
@@ -387,13 +387,13 @@ export const PlayerController = () => {
/> />
</mesh> </mesh>
<Cylinder {/* <Cylinder
args={[0.1, 0, 1, 128, 64, true]} args={[0.1, 0, 1, 128, 64, true]}
position={[-0.6, 0.05, 0.5]} position={[-0.6, 0.05, 0.5]}
rotation={[Math.PI / 3, 0 , 0]} rotation={[Math.PI / 3, 0 , 0]}
> >
<meshStandardMaterial side={THREE.DoubleSide} /> <meshStandardMaterial side={THREE.DoubleSide} />
</Cylinder> </Cylinder> */}
{/* <Flame/> */} {/* <Flame/> */}
<FlameParticles isBoosting={isBoosting} /> <FlameParticles isBoosting={isBoosting} />
<DriftParticlesLeft turboColor={turboColor} scale={scale} /> <DriftParticlesLeft turboColor={turboColor} scale={scale} />