8 changed files with 143 additions and 141 deletions

No files matched your search

+1 -1
View File
@@ -43,7 +43,7 @@ function App() {
<KeyboardControls map={map}>
<Experience />
</KeyboardControls>
{/* <Stats /> */}
<Stats />
</Physics>
</Suspense>
</Canvas>
+6 -6
View File
@@ -3,23 +3,23 @@ import { Particles3 } from "./Particles3";
export const DriftParticlesLeft = ({turboColor,scale, ...props}) => {
if(scale < 0.8) {
return null;
}
// if(scale < 0.8) {
// return null;
// }
return (
<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} /> */}
<Particles3 turboColor={turboColor} scale={scale} />
{/* <Particles3 turboColor={turboColor} scale={scale} /> */}
</group>
)
+4 -15
View File
@@ -3,24 +3,13 @@ import { Particles4 } from "./Particles4";
export const DriftParticlesRight = ({turboColor,scale, ...props}) => {
if(scale < 0.8) {
return null;
}
// if(scale < 0.8) {
// return null;
// }
return (
<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} />
<Particles4 turboColor={turboColor} scale={scale} />
<Particles2 turboColor={turboColor} scale={scale} />
</group>
)
+31 -20
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 * 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 pointsRef = useRef();
const [size, setSize] = useState(1);
const [opacity, setOpacity] = useState(1);
const [initialized, setInitialized] = useState(false);
const initialized = useRef(false);
useEffect(() => {
// Initialize after delay
useMemo(() => {
const timer = setTimeout(() => {
setInitialized(true);
initialized.current = true;
}, delay);
return () => clearTimeout(timer);
}, [delay]);
const points = React.useMemo(() => {
const points = useMemo(() => {
const geom = new THREE.BufferGeometry();
geom.setAttribute(
"position",
@@ -26,29 +25,41 @@ export const FlameParticle = ({ position, png, turboColor, delay = 0 }) => {
}, [position]);
useFrame(({clock}, delta) => {
if (!initialized) return;
if (!initialized.current) return;
pointsRef.current.position.y += 0.03 * delta * 144;
pointsRef.current.position.z += 0.06 * delta * 144;
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 * delta * 144);
const pointsCurrent = pointsRef.current;
if (isBoosting) {
// Update logic when boosting
pointsCurrent.position.y += 0.03 * delta * 144;
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(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 (
<points ref={pointsRef} geometry={points}>
<pointsMaterial
size={size}
size={1}
alphaMap={texture}
transparent={true}
depthWrite={false}
color={0x000000}
opacity={opacity}
opacity={1}
toneMapped={false}
/>
</points>
+25 -27
View File
@@ -2,9 +2,7 @@ import { FlameParticle } from "./FlameParticle";
export const FlameParticles = ({ isBoosting }) => {
if (!isBoosting) {
return null;
}
return (
<group>
{/* bottom left */}
@@ -12,37 +10,37 @@ export const FlameParticles = ({ isBoosting }) => {
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={0}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={100}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={200}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={300}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={400}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={500}
/>
</group>
@@ -52,37 +50,37 @@ export const FlameParticles = ({ isBoosting }) => {
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={0}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={100}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={200}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={300}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={400}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={500}
/>
</group>
@@ -91,37 +89,37 @@ export const FlameParticles = ({ isBoosting }) => {
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={0}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={100}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={200}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={300}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={400}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={500}
/>
</group>
@@ -129,37 +127,37 @@ export const FlameParticles = ({ isBoosting }) => {
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={0}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={100}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={200}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={300}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={400}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
isBoosting={isBoosting}
delay={500}
/>
</group>
+37 -35
View File
@@ -1,55 +1,57 @@
import { useRef } from "react";
import { useRef, useMemo } from "react";
import { useFrame } from "@react-three/fiber";
import * as THREE from 'three';
export const Particles1 = ({ turboColor, scale, ...props }) => {
const ref = useRef();
const velocity = useRef({
x: -Math.random() * 0.05,
y: Math.random() * 0.05,
z: Math.random() * 0.02,
});
const gravity = -0.003;
export const Particles1 = ({ turboColor, scale, numParticles = 50, ...props }) => {
const instancedMeshRef = useRef();
const particlesData = useMemo(() => {
return new Array(numParticles).fill().map(() => ({
position: new THREE.Vector3(-0.6, 0.05, 0.5),
velocity: new THREE.Vector3(-Math.random() * 0.05, Math.random() * 0.05, Math.random() * 0.02),
gravity: -0.003
}));
}, [numParticles]);
useFrame((state, delta) => {
let position = ref.current.position;
let velocityVector = new THREE.Vector3(velocity.current.x, velocity.current.y, velocity.current.z);
// 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 (!instancedMeshRef.current) {
return;
}
if (position.y < 0.05) {
position.set(-0.6, 0.05, 0.5);
velocity.current = {
x: -Math.random() * 0.05,
y: Math.random() * 0.05,
z: Math.random() * 0.02,
};
// Manage visibility directly in the animation loop
instancedMeshRef.current.visible = scale >= 0.8;
if (scale < 0.8) {
return;
}
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 (
<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]} />
<meshStandardMaterial
emissive={turboColor}
toneMapped={false}
emissiveIntensity={5}
/>
</mesh>
</instancedMesh>
);
};
+37 -35
View File
@@ -1,55 +1,57 @@
import { useRef } from "react";
import { useRef, useMemo } from "react";
import { useFrame } from "@react-three/fiber";
import * as THREE from 'three';
export const Particles2 = ({ turboColor, scale, ...props }) => {
const ref = useRef();
const velocity = useRef({
x: Math.random() * 0.05,
y: Math.random() * 0.05,
z: Math.random() * 0.02,
});
const gravity = -0.003;
export const Particles2 = ({ turboColor, scale, numParticles = 50, ...props }) => {
const instancedMeshRef = useRef();
const particlesData = useMemo(() => {
return new Array(numParticles).fill().map(() => ({
position: new THREE.Vector3(0.6, 0.05, 0.5),
velocity: new THREE.Vector3(Math.random() * 0.05, Math.random() * 0.05, Math.random() * 0.02),
gravity: -0.003
}));
}, [numParticles]);
useFrame((state, delta) => {
let position = ref.current.position;
let velocityVector = new THREE.Vector3(velocity.current.x, velocity.current.y, velocity.current.z);
// 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 (!instancedMeshRef.current) {
return;
}
if (position.y < 0.05) {
position.set(0.6, 0.05, 0.5);
velocity.current = {
x: Math.random() * 0.05,
y: Math.random() * 0.05,
z: Math.random() * 0.02,
};
// Manage visibility directly in the animation loop
instancedMeshRef.current.visible = scale >= 0.8;
if (scale < 0.8) {
return;
}
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 (
<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]} />
<meshStandardMaterial
emissive={turboColor}
toneMapped={false}
emissiveIntensity={5}
/>
</mesh>
</instancedMesh>
);
};
+2 -2
View File
@@ -387,13 +387,13 @@ export const PlayerController = () => {
/>
</mesh>
<Cylinder
{/* <Cylinder
args={[0.1, 0, 1, 128, 64, true]}
position={[-0.6, 0.05, 0.5]}
rotation={[Math.PI / 3, 0 , 0]}
>
<meshStandardMaterial side={THREE.DoubleSide} />
</Cylinder>
</Cylinder> */}
{/* <Flame/> */}
<FlameParticles isBoosting={isBoosting} />
<DriftParticlesLeft turboColor={turboColor} scale={scale} />