feat:(game) added flame particles for boosting

skidmarks
Alex 2024-01-23 12:56:30 +01:00
parent 6d4032d9c7
commit 16b2bbb93a
6 changed files with 233 additions and 4 deletions

BIN
public/fire_01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

BIN
public/fire_02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@ -39,7 +39,7 @@ export const Experience = () => {
>
<SMAA />
{/* <N8AO distanceFalloff={1} aoRadius={1} intensity={3} /> */}
<N8AO distanceFalloff={1} aoRadius={1} intensity={3} />
<Bloom
luminanceThreshold={0}
mipmapBlur

View File

@ -0,0 +1,56 @@
import React, { useState, useEffect, useRef } from "react";
import { useLoader, useFrame } from "@react-three/fiber";
import * as THREE from "three";
export const FlameParticle = ({ position, png, turboColor, 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);
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 (
<points ref={pointsRef} geometry={points}>
<pointsMaterial
size={size}
alphaMap={texture}
transparent={true}
depthWrite={false}
color={turboColor}
opacity={opacity}
toneMapped={false}
/>
</points>
);
};

View File

@ -0,0 +1,168 @@
import { FlameParticle } from "./FlameParticle";
export const FlameParticles = ({ isBoosting }) => {
if (!isBoosting) {
return null;
}
return (
<group>
{/* bottom left */}
<group position={[-0.26, 0.45, 1]}>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
delay={0}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
delay={100}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
delay={200}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
delay={300}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
delay={400}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
delay={500}
/>
</group>
{/* bottom right */}
<group position={[0.26, 0.45, 1]}>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
delay={0}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
delay={100}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
delay={200}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
delay={300}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
delay={400}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
delay={500}
/>
</group>
{/* top left */}
<group position={[-0.18, 0.6, 0.8]}>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
delay={0}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
delay={100}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
delay={200}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
delay={300}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
delay={400}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
delay={500}
/>
</group>
<group position={[0.18, 0.6, 0.8]}>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
delay={0}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
delay={100}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
delay={200}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
delay={300}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_02.png"
turboColor={0xfea347}
delay={400}
/>
<FlameParticle
position={[0, 0, 0]}
png="./fire_01.png"
turboColor={0xfea347}
delay={500}
/>
</group>
</group>
);
};

View File

@ -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}
/>
</mesh>
{/* <Flame/> */}
<FlameParticles isBoosting={isBoosting}/>
<DriftParticlesLeft turboColor={turboColor} scale={scale} />
<DriftParticlesRight turboColor={turboColor} scale={scale} />
<PointParticle position={[-0.6, 0.05, 0.5]} png="./circle.png" turboColor={turboColor}/>