diff --git a/public/sounds/driftBlue.wav b/public/sounds/driftBlue.wav new file mode 100644 index 0000000..ac0c7c6 Binary files /dev/null and b/public/sounds/driftBlue.wav differ diff --git a/public/sounds/driftOrange.wav b/public/sounds/driftOrange.wav new file mode 100644 index 0000000..6cf428e Binary files /dev/null and b/public/sounds/driftOrange.wav differ diff --git a/public/sounds/driftPurple.wav b/public/sounds/driftPurple.wav new file mode 100644 index 0000000..8dd9c5e Binary files /dev/null and b/public/sounds/driftPurple.wav differ diff --git a/public/sounds/drifting.mp3 b/public/sounds/drifting.mp3 new file mode 100644 index 0000000..aa967eb Binary files /dev/null and b/public/sounds/drifting.mp3 differ diff --git a/public/sounds/drifting.wav b/public/sounds/drifting.wav new file mode 100644 index 0000000..5e6d82f Binary files /dev/null and b/public/sounds/drifting.wav differ diff --git a/public/sounds/driftingTwo.mp3 b/public/sounds/driftingTwo.mp3 new file mode 100644 index 0000000..f7fef32 Binary files /dev/null and b/public/sounds/driftingTwo.mp3 differ diff --git a/public/sounds/engineTwo.wav b/public/sounds/engineTwo.wav new file mode 100644 index 0000000..38deba3 Binary files /dev/null and b/public/sounds/engineTwo.wav differ diff --git a/public/sounds/jump.mp3 b/public/sounds/jump.mp3 new file mode 100644 index 0000000..017dc5f Binary files /dev/null and b/public/sounds/jump.mp3 differ diff --git a/public/sounds/landing.wav b/public/sounds/landing.wav new file mode 100644 index 0000000..83fcba8 Binary files /dev/null and b/public/sounds/landing.wav differ diff --git a/public/sounds/turbo.wav b/public/sounds/turbo.wav new file mode 100644 index 0000000..c663dcc Binary files /dev/null and b/public/sounds/turbo.wav differ diff --git a/src/components/Particles/DriftParticlesLeft.jsx b/src/components/Particles/DriftParticlesLeft.jsx index ea780dd..644cb28 100644 --- a/src/components/Particles/DriftParticlesLeft.jsx +++ b/src/components/Particles/DriftParticlesLeft.jsx @@ -10,15 +10,23 @@ export const DriftParticlesLeft = ({turboColor,scale, ...props}) => { return ( - {/* - */} - + + + + + + + + + + + {/* */} diff --git a/src/components/Particles/DriftParticlesRight.jsx b/src/components/Particles/DriftParticlesRight.jsx index 6e08f49..99b481a 100644 --- a/src/components/Particles/DriftParticlesRight.jsx +++ b/src/components/Particles/DriftParticlesRight.jsx @@ -10,7 +10,24 @@ export const DriftParticlesRight = ({turboColor,scale, ...props}) => { return ( + + + + + + + + + + + + + + + + + ) } \ No newline at end of file diff --git a/src/components/Particles/FlameParticle.jsx b/src/components/Particles/FlameParticle.jsx index f7931b5..c84f01d 100644 --- a/src/components/Particles/FlameParticle.jsx +++ b/src/components/Particles/FlameParticle.jsx @@ -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} /> diff --git a/src/components/Particles/Particles1.jsx b/src/components/Particles/Particles1.jsx index ef156ad..507a07c 100644 --- a/src/components/Particles/Particles1.jsx +++ b/src/components/Particles/Particles1.jsx @@ -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 ( - = 0.8}> + - + ); -}; +}; \ No newline at end of file diff --git a/src/components/Particles/Particles2.jsx b/src/components/Particles/Particles2.jsx index 797e5ff..dfef986 100644 --- a/src/components/Particles/Particles2.jsx +++ b/src/components/Particles/Particles2.jsx @@ -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 ( - = 0.8}> + - + ); -}; +}; \ No newline at end of file diff --git a/src/components/PlayerController.jsx b/src/components/PlayerController.jsx index b1f1d06..af7ca62 100644 --- a/src/components/PlayerController.jsx +++ b/src/components/PlayerController.jsx @@ -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 = () => { { opacity={0.4} /> + + + + {/* { opacity={0.4} /> + + + + - {/* - - */} - {/* */} - + {/* */} { fov={50} ref={cam} /> - {/* */} + + + + + + + + + + ); diff --git a/src/components/ShaderMaterials/FakeFlame/FakeFlame.jsx b/src/components/ShaderMaterials/FakeFlame/FakeFlame.jsx index 086ca7c..022e56e 100644 --- a/src/components/ShaderMaterials/FakeFlame/FakeFlame.jsx +++ b/src/components/ShaderMaterials/FakeFlame/FakeFlame.jsx @@ -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)); diff --git a/src/components/models/characters/Mario_kart.jsx b/src/components/models/characters/Mario_kart.jsx index c8469b5..21cd2dc 100644 --- a/src/components/models/characters/Mario_kart.jsx +++ b/src/components/models/characters/Mario_kart.jsx @@ -86,7 +86,7 @@ export function Mario({ currentSpeed, steeringAngleWheels, isBoosting, ...props @@ -104,17 +104,17 @@ export function Mario({ currentSpeed, steeringAngleWheels, isBoosting, ...props diff --git a/src/components/models/tracks/Tour_paris_promenade.jsx b/src/components/models/tracks/Tour_paris_promenade.jsx index 6d43456..ff1fcc8 100644 --- a/src/components/models/tracks/Tour_paris_promenade.jsx +++ b/src/components/models/tracks/Tour_paris_promenade.jsx @@ -17,7 +17,7 @@ export function Paris(props) { materials.M_Cmn_ShadowCollision.opacity = 0 materials.M_Cmn_ShadowCollision.transparent = true return ( - + diff --git a/src/components/store.jsx b/src/components/store.jsx index da4455a..c12aeb1 100644 --- a/src/components/store.jsx +++ b/src/components/store.jsx @@ -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: [],