feat(game): added sound Effects

This commit is contained in:
Alex committed 2024-01-28 12:12:02 +01:00
1 parent f356585be2
commit 11be02d977
20 files changed
+254 -118

No files matched your search

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -10,15 +10,23 @@ export const DriftParticlesLeft = ({turboColor,scale, ...props}) => {
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} />
<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} /> */}
</group>
@@ -10,7 +10,24 @@ export const DriftParticlesRight = ({turboColor,scale, ...props}) => {
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} />
<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} />
</group>
)
}
+1 -1
View File
@@ -58,7 +58,7 @@ export const FlameParticle = ({ position, png, isBoosting, delay = 0 }) => {
alphaMap={texture}
transparent={true}
depthWrite={false}
color={0x000000}
color={0xff9900}
opacity={1}
toneMapped={false}
/>
+42 -44
View File
@@ -1,57 +1,55 @@
import { useRef, useMemo } from "react";
import { useRef } from "react";
import { useFrame } from "@react-three/fiber";
import * as THREE from 'three';
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) => {
if (!instancedMeshRef.current) {
return;
}
// Manage visibility directly in the animation loop
instancedMeshRef.current.visible = scale >= 0.8;
if (scale < 0.8) {
return;
}
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;
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;
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 (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,
};
}
ref.current.position.set(position.x, position.y, position.z);
});
return (
<instancedMesh ref={instancedMeshRef} args={[null, null, numParticles]} visible={scale >= 0.8}>
<mesh ref={ref} position={[-0.6, 0.05, 0.5]} scale={[scale, scale * 5, scale]}>
<sphereGeometry args={[0.01, 16, 16]} />
<meshStandardMaterial
emissive={turboColor}
toneMapped={false}
emissiveIntensity={5}
/>
</instancedMesh>
</mesh>
);
};
};
+41 -44
View File
@@ -1,57 +1,54 @@
import { useRef, useMemo } from "react";
import { useRef } from "react";
import { useFrame } from "@react-three/fiber";
import * as THREE from 'three';
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) => {
if (!instancedMeshRef.current) {
return;
}
// Manage visibility directly in the animation loop
instancedMeshRef.current.visible = scale >= 0.8;
if (scale < 0.8) {
return;
}
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;
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;
useFrame((state, delta) => {
let position = ref.current.position;
let velocityVector = new THREE.Vector3(velocity.current.x, velocity.current.y, velocity.current.z);
velocity.current.y += gravity * delta * 144;
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) {
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,
};
}
ref.current.position.set(position.x, position.y, position.z);
});
return (
<instancedMesh ref={instancedMeshRef} args={[null, null, numParticles]} visible={scale >= 0.8}>
<mesh ref={ref} position={[0.6, 0.05, 0.5]} scale={[scale, scale * 5, scale]}>
<sphereGeometry args={[0.01, 16, 16]} />
<meshStandardMaterial
emissive={turboColor}
toneMapped={false}
emissiveIntensity={5}
/>
</instancedMesh>
</mesh>
);
};
};
+123 -15
View File
@@ -22,6 +22,7 @@ import { PointParticle } from "./Particles/PointParticle";
import { FlameParticles } from "./Particles/FlameParticles";
import { useStore } from "./store";
import { Cylinder } from "@react-three/drei";
import FakeGlowMaterial from "./ShaderMaterials/FakeGlow/FakeGlowMaterial";
export const PlayerController = () => {
const upPressed = useKeyboardControls((state) => state[Controls.up]);
@@ -63,13 +64,28 @@ export const PlayerController = () => {
let targetZPosition = 8;
const [steeringAngleWheels, setSteeringAngleWheels] = useState(0);
const engineSound = useRef();
const driftSound = useRef();
const driftTwoSound = useRef();
const driftOrangeSound = useRef();
const driftPurpleSound = useRef();
const driftBlueSound = useRef();
const jumpSound = useRef();
const landingSound = useRef();
const turboSound = useRef();
const [scale, setScale] = useState(0);
const { actions, addPastPosition } = useStore();
useFrame(({ pointer, clock }, delta) => {
const time = clock.getElapsedTime();
if (!body.current && !mario.current) return;
engineSound.current.setVolume(currentSpeed / 300 + 0.2);
engineSound.current.setPlaybackRate(currentSpeed / 10 + 0.1);
jumpSound.current.setPlaybackRate(1.5);
jumpSound.current.setVolume(0.5);
driftSound.current.setVolume(0.2);
driftBlueSound.current.setVolume(0.5);
driftOrangeSound.current.setVolume(0.6);
driftPurpleSound.current.setVolume(0.7);
// HANDLING AND STEERING
const kartRotation =
@@ -79,8 +95,6 @@ export const PlayerController = () => {
0,
-Math.cos(kartRotation)
);
actions.setBodyPosition(body.current.translation());
actions.setBodyRotation(kart.current.rotation);
if (leftPressed && currentSpeed > 0) {
steeringAngle = currentSteeringSpeed;
@@ -177,8 +191,17 @@ export const PlayerController = () => {
jumpForce.current += 10;
isOnFloor.current = false;
jumpIsHeld.current = true;
jumpSound.current.play();
if (jumpSound.current.isPlaying) {
jumpSound.current.stop();
jumpSound.current.play();
}
}
if (isOnFloor.current && jumpForce.current > 0) {
landingSound.current.play();
}
if (!isOnFloor.current && jumpForce.current > 0) {
jumpForce.current -= 1 * delta * 144;
}
@@ -215,6 +238,10 @@ export const PlayerController = () => {
);
setTurboColor(0xffffff);
accumulatedDriftPower.current = 0;
driftSound.current.stop();
driftTwoSound.current.stop();
driftOrangeSound.current.stop();
driftPurpleSound.current.stop();
}
if (driftLeft.current) {
@@ -248,14 +275,19 @@ export const PlayerController = () => {
if (accumulatedDriftPower.current > blueTurboThreshold) {
setTurboColor(0x00ffff);
boostDuration.current = 50;
driftBlueSound.current.play();
}
if (accumulatedDriftPower.current > orangeTurboThreshold) {
setTurboColor(0xffcf00);
boostDuration.current = 100;
driftBlueSound.current.stop();
driftOrangeSound.current.play();
}
if (accumulatedDriftPower.current > purpleTurboThreshold) {
setTurboColor(0xff00ff);
boostDuration.current = 250;
driftOrangeSound.current.stop();
driftPurpleSound.current.play();
}
if (driftLeft.current || driftRight.current) {
@@ -267,6 +299,11 @@ export const PlayerController = () => {
} else {
setScale(vibration);
}
if (isOnFloor.current && !driftSound.current.isPlaying) {
driftSound.current.play();
driftTwoSound.current.play();
landingSound.current.play();
}
}
// RELEASING DRIFT
@@ -281,9 +318,15 @@ export const PlayerController = () => {
setCurrentSpeed(boostSpeed);
boostDuration.current -= 1 * delta * 144;
targetZPosition = 10;
turboSound.current.play();
driftTwoSound.current.play();
driftBlueSound.current.stop();
driftOrangeSound.current.stop();
driftPurpleSound.current.stop();
} else if (boostDuration.current <= 1) {
setIsBoosting(false);
targetZPosition = 8;
turboSound.current.stop();
}
// CAMERA WORK
@@ -324,7 +367,7 @@ export const PlayerController = () => {
<RigidBody
ref={body}
colliders={false}
position={[8, 20, -96]}
position={[8, 20, -119]}
centerOfMass={[0, -1, 0]}
mass={3}
ccd
@@ -365,6 +408,15 @@ export const PlayerController = () => {
opacity={0.4}
/>
</mesh>
<mesh position={[0.6, 0.05, 0.5]} scale={scale * 10}>
<sphereGeometry args={[0.05, 16, 16]} />
<FakeGlowMaterial
falloff={3}
glowInternalRadius={1}
glowColor={turboColor}
glowSharpness={1}
/>
</mesh>
{/* <pointLight
position={[-0.6, 0.05, 0.5]}
intensity={scale}
@@ -381,16 +433,17 @@ export const PlayerController = () => {
opacity={0.4}
/>
</mesh>
<mesh position={[-0.6, 0.05, 0.5]} scale={scale * 10}>
<sphereGeometry args={[0.05, 16, 16]} />
<FakeGlowMaterial
falloff={3}
glowInternalRadius={1}
glowColor={turboColor}
glowSharpness={1}
/>
</mesh>
{/* <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> */}
{/* <Flame/> */}
<FlameParticles isBoosting={isBoosting} />
{/* <FlameParticles isBoosting={isBoosting} /> */}
<DriftParticlesLeft turboColor={turboColor} scale={scale} />
<DriftParticlesRight turboColor={turboColor} scale={scale} />
<PointParticle
@@ -422,7 +475,62 @@ export const PlayerController = () => {
fov={50}
ref={cam}
/>
{/* <PositionalAudio ref={engineSound} url="./sounds/engine.wav" autoplay loop distance={10}/> */}
<PositionalAudio
ref={engineSound}
url="./sounds/engine.wav"
autoplay
loop
distance={1000}
/>
<PositionalAudio
ref={driftSound}
url="./sounds/drifting.mp3"
loop
distance={1000}
/>
<PositionalAudio
ref={driftTwoSound}
url="./sounds/driftingTwo.mp3"
loop
distance={1000}
/>
<PositionalAudio
ref={driftOrangeSound}
url="./sounds/driftOrange.wav"
loop={false}
distance={1000}
/>
<PositionalAudio
ref={driftBlueSound}
url="./sounds/driftBlue.wav"
loop={false}
distance={1000}
/>
<PositionalAudio
ref={driftPurpleSound}
url="./sounds/driftPurple.wav"
loop={false}
distance={1000}
/>
<PositionalAudio
ref={jumpSound}
url="./sounds/jump.mp3"
loop={false}
distance={1000}
/>
<PositionalAudio
ref={landingSound}
url="./sounds/landing.wav"
loop={false}
distance={1000}
/>
<PositionalAudio
ref={turboSound}
url="./sounds/turbo.wav"
loop={false}
distance={1000}
/>
</group>
</group>
);
@@ -39,11 +39,11 @@ export default function FakeFlame({ falloff = 3, glowInternalRadius = 1.0, glowC
float glitchStrength = sin(glitchTime) + sin(glitchTime * .05) + sin(glitchTime * .36);
glitchStrength /= 2.0;
glitchStrength = smoothstep(0.2, 0.8, glitchStrength);
glitchStrength *= 0.05;
glitchStrength *= 0.;
modelPosition.x += (random2D(modelNormal.xx + time) - 0.5) * glitchStrength;
modelPosition.x += (random2D(modelNormal.xx - time) - 0.2) * glitchStrength;
modelPosition.y += sin(smoothstep(0.3, vUv.y - 2.2, position.y) * 2.) * sin(time * 48.);
modelPosition.z += sin(smoothstep(0., vUv.x - 0.8, position.z) * 2.) * sin(time * 24.) * .6;
modelPosition.y += sin(smoothstep(0.4, vUv.y - 2.5, position.y) * 2.) * sin(time * 48.);
modelPosition.z += sin(smoothstep(0., vUv.x - 1.8, position.z) * 2.) * sin(time * 24.);
gl_Position = projectionMatrix * viewMatrix * modelPosition;
@@ -107,7 +107,7 @@ export default function FakeFlame({ falloff = 3, glowInternalRadius = 1.0, glowC
q.x *= 2.;
q.y *= 2.;
float strength = floor(q.x+1.5);
float T3 = max(2.,2.25*strength)*time * 3.;
float T3 = max(2.,2.25*strength)*time * 4.;
q.x = mod(q.x,1.)-0.5;
q.y -= 0.05;
float n = fbm(strength*q + vec2(0,T3));
@@ -86,7 +86,7 @@ export function Mario({ currentSpeed, steeringAngleWheels, isBoosting, ...props
<Cylinder
args={[0.1, 0, 1, 128, 64, true]}
position={[0.3, 0.6, -1.2]}
position={[0.3, 0.65, -1.35]}
rotation={[Math.PI / 1.5, 0, 0]}
scale={scale}
@@ -96,7 +96,7 @@ export function Mario({ currentSpeed, steeringAngleWheels, isBoosting, ...props
<Cylinder
args={[0.1, 0, 1, 128, 64, true]}
position={[-0.3, 0.6, -1.2]}
position={[-0.3, 0.65, -1.35]}
rotation={[Math.PI / 1.5, 0, 0]}
scale={scale}
>
@@ -104,17 +104,17 @@ export function Mario({ currentSpeed, steeringAngleWheels, isBoosting, ...props
</Cylinder>
<Cylinder
args={[0.09, 0, 1, 128, 64, true]}
position={[0.18, 0.7, -0.8]}
position={[0.18, 0.75, -1.1]}
rotation={[Math.PI / 1.5, 0, 0]}
scale={scale}
scale={scale * 0.8}
>
<FakeFlame isBoosting={isBoosting} />
</Cylinder>
<Cylinder
args={[0.09, 0, 1, 128, 64, true]}
position={[-0.18, 0.7, -0.8]}
position={[-0.18, 0.75, -1.1]}
rotation={[Math.PI / 1.5, 0, 0]}
scale={scale}
scale={scale * 0.8}
>
<FakeFlame isBoosting={isBoosting}/>
</Cylinder>
@@ -17,7 +17,7 @@ export function Paris(props) {
materials.M_Cmn_ShadowCollision.opacity = 0
materials.M_Cmn_ShadowCollision.transparent = true
return (
<group {...props} scale={40} position={[0,-3.6,0]}dispose={null}>
<group {...props} scale={50} position={[0,-3.6,0]}dispose={null}>
<mesh castShadow receiveShadow geometry={nodes.N_Road_Ground_M_Cmn_MainColor_Detail_0.geometry} material={materials.M_Cmn_MainColor_Detail} scale={0.01} />
<mesh castShadow receiveShadow geometry={nodes.N_Road_Ground_M_Mobp1_Road_A_0.geometry} material={materials.M_Mobp1_Road_A} scale={0.01} />
<mesh castShadow receiveShadow geometry={nodes.N_Road_Ground_M_Mobp1_Road_B_0.geometry} material={materials.M_Mobp1_Road_B} scale={0.01} />
+8
View File
@@ -1,5 +1,13 @@
import { create } from "zustand";
export const playAudio = (path, callback) => {
const audio = new Audio(`./sounds/${path}.mp3`);
if (callback) {
audio.addEventListener("ended", callback);
}
audio.play();
};
export const useStore = create((set, get) => ({
particles1: [],
particles2: [],