fix(game): fixed state management causing a rerender stuttered trigger when boosting with flame Particles

instancedMeshParticles
Alex 2024-01-25 12:14:23 +01:00
parent fdd821e630
commit 54810a73cd
2 changed files with 56 additions and 47 deletions

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>

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>