Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54810a73cd | ||
|
|
fdd821e630 | ||
|
|
2d9230b8ea |
No files matched your search
+1
-1
@@ -43,7 +43,7 @@ function App() {
|
||||
<KeyboardControls map={map}>
|
||||
<Experience />
|
||||
</KeyboardControls>
|
||||
{/* <Stats /> */}
|
||||
<Stats />
|
||||
</Physics>
|
||||
</Suspense>
|
||||
</Canvas>
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
@@ -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} />
|
||||
|
||||
Reference in new issue
Block a user