diff --git a/public/particles/smokes/smoke_01.png b/public/particles/smokes/smoke_01.png new file mode 100644 index 0000000..1cd418e Binary files /dev/null and b/public/particles/smokes/smoke_01.png differ diff --git a/public/particles/smokes/smoke_02.png b/public/particles/smokes/smoke_02.png new file mode 100644 index 0000000..d866368 Binary files /dev/null and b/public/particles/smokes/smoke_02.png differ diff --git a/public/particles/smokes/smoke_03.png b/public/particles/smokes/smoke_03.png new file mode 100644 index 0000000..909717a Binary files /dev/null and b/public/particles/smokes/smoke_03.png differ diff --git a/public/particles/smokes/smoke_04.png b/public/particles/smokes/smoke_04.png new file mode 100644 index 0000000..74a2695 Binary files /dev/null and b/public/particles/smokes/smoke_04.png differ diff --git a/public/particles/smokes/smoke_05.png b/public/particles/smokes/smoke_05.png new file mode 100644 index 0000000..0ac46dc Binary files /dev/null and b/public/particles/smokes/smoke_05.png differ diff --git a/public/particles/smokes/smoke_06.png b/public/particles/smokes/smoke_06.png new file mode 100644 index 0000000..300c5fa Binary files /dev/null and b/public/particles/smokes/smoke_06.png differ diff --git a/public/particles/smokes/smoke_07.png b/public/particles/smokes/smoke_07.png new file mode 100644 index 0000000..fb78c0f Binary files /dev/null and b/public/particles/smokes/smoke_07.png differ diff --git a/public/particles/smokes/smoke_08.png b/public/particles/smokes/smoke_08.png new file mode 100644 index 0000000..feec49e Binary files /dev/null and b/public/particles/smokes/smoke_08.png differ diff --git a/src/components/Dust.jsx b/src/components/Dust.jsx new file mode 100644 index 0000000..a0c21cb --- /dev/null +++ b/src/components/Dust.jsx @@ -0,0 +1,86 @@ +import { Euler, Object3D, Vector3, Matrix4, DoubleSide, Quaternion, TextureLoader, BackSide } from 'three' +import { useRef, useLayoutEffect } from 'react' +import { useFrame, useLoader } from '@react-three/fiber' +import { vec3 } from '@react-three/rapier' + + +import { useStore } from './store' + + +const e = new Euler() +const m = new Matrix4() +const o = new Object3D() +const v = new Vector3() +const q = new Quaternion() + + + +export function Dust({ count = 500, opacity = 0.1, size = 0.6 }) { + const smoke01 = useLoader(TextureLoader, './particles/smokes/smoke_01.png'); + const smoke02 = useLoader(TextureLoader, './particles/smokes/smoke_02.png'); + const smoke03 = useLoader(TextureLoader, './particles/smokes/smoke_03.png'); + const smoke04 = useLoader(TextureLoader, './particles/smokes/smoke_04.png'); + const smoke05 = useLoader(TextureLoader, './particles/smokes/smoke_05.png'); + const smoke06 = useLoader(TextureLoader, './particles/smokes/smoke_06.png'); + const smoke07 = useLoader(TextureLoader, './particles/smokes/smoke_07.png'); + const smoke08 = useLoader(TextureLoader, './particles/smokes/smoke_08.png'); + + const texture = [smoke01, smoke02, smoke03, smoke04, smoke05, smoke06, smoke07, smoke08] + const ref = useRef(null); + const { leftWheel, rightWheel } = useStore(); + let index = 0 + let time = 0 + let i = 0 + useFrame((state,delta ) => { + const rotation = leftWheel.kartRotation; + if (state.clock.getElapsedTime() - time > 0.02 && leftWheel && rightWheel && ref.current && leftWheel.isSpinning) { + time = state.clock.getElapsedTime() + setItemAt(ref.current, rotation, leftWheel, index++); + setItemAt(ref.current, rotation, rightWheel, index++); + + if (index === count) index = 0 + } else { + // Shrink old one + for (i = 0; i < count; i++) { + const direction = new Vector3(Math.sin(time * 6 + i * 10) , 2, 0); + ref.current.getMatrixAt(i, m) + m.decompose(o.position, q, v) + o.scale.setScalar(Math.max(0, v.x - 0.005)) + o.position.addScaledVector(direction, 0.01) + o.updateMatrix() + ref.current.setMatrixAt(i, o.matrix) + ref.current.instanceMatrix.needsUpdate = true + } + } + }) + + useLayoutEffect(() => { + if(ref.current){ + ref.current.geometry.rotateY(-Math.PI / 2) + return () => { + ref.current.geometry.rotateY(Math.PI / 2) + } + } + }) + + return ( + + + + + ) +} + +function setItemAt(instances, rotation, body, index) { + const randomOffset = (Math.random() - 0.5) * 0.3 ; + const pos = body.getWorldPosition(v); + o.rotation.set(0, rotation + Math.PI / 2, 0); + pos.x += randomOffset + // pos.y += randomOffset + pos.z += randomOffset + o.position.copy(pos); + o.scale.setScalar(1) + o.updateMatrix() + instances.setMatrixAt(index, o.matrix) + instances.instanceMatrix.needsUpdate = true +} diff --git a/src/components/Experience.jsx b/src/components/Experience.jsx index 33a44fa..13d734e 100644 --- a/src/components/Experience.jsx +++ b/src/components/Experience.jsx @@ -43,6 +43,7 @@ import { LUTPass, LUTCubeLoader } from "three-stdlib"; import { useCurvedPathPoints } from "./useCurvedPath"; import { ParisBis } from "./models/tracks/Paris-bis"; import { Skid } from "./Skid"; +import { Dust } from "./Dust"; export const Experience = () => { const onCollide = (event) => {}; @@ -152,10 +153,11 @@ export const Experience = () => { + + - {networkBananas.map((banana) => ( { + if (leftWheel.current && rightWheel.current && body.current) { + actions.setLeftWheel(leftWheel.current); + actions.setRightWheel(rightWheel.current); + } + }, [body.current]); useFrame(({ pointer, clock }, delta) => { if (player.id !== id) return; const time = clock.getElapsedTime(); @@ -115,11 +124,13 @@ export const PlayerController = ({ 0, -Math.cos(kartRotation) ); - + if (escPressed) { actions.setGameStarted(false); } - + if(kartRotation){ + leftWheel.current.kartRotation = kartRotation; + } if (leftPressed && currentSpeed > 0) { steeringAngle = currentSteeringSpeed; targetXPosition = -camMaxOffset; @@ -179,6 +190,8 @@ export const PlayerController = ({ } } if (shouldSlow) { + rightWheel.current.isSpinning = true; + setCurrentSpeed( Math.max(currentSpeed - decceleration * 2 * delta * 144, 0) ); @@ -186,6 +199,7 @@ export const PlayerController = ({ slowDownDuration.current -= 1500 * delta; setShouldLaunch(true); if (slowDownDuration.current <= 1) { + rightWheel.current.isSpinning = false; actions.setShouldSlowDown(false); slowDownDuration.current = 1500; setShouldLaunch(false); @@ -311,7 +325,11 @@ export const PlayerController = ({ steeringAngle * 25 + 0.4, 0.05 * delta * 144 ); - accumulatedDriftPower.current += 0.1 * (steeringAngle + 1) * delta * 144; + if (isOnFloor.current) { + leftWheel.current.isSpinning = true; + accumulatedDriftPower.current += + 0.1 * (steeringAngle + 1) * delta * 144; + } } if (driftRight.current) { driftDirection.current = -1; @@ -321,7 +339,11 @@ export const PlayerController = ({ -(-steeringAngle * 25 + 0.4), 0.05 * delta * 144 ); - accumulatedDriftPower.current += 0.1 * (-steeringAngle + 1) * delta * 144; + if(isOnFloor.current){ + leftWheel.current.isSpinning = true; + accumulatedDriftPower.current += 0.1 * (-steeringAngle + 1) * delta * 144; + + } } if (!driftLeft.current && !driftRight.current) { mario.current.rotation.y = THREE.MathUtils.lerp( @@ -330,6 +352,11 @@ export const PlayerController = ({ 0.05 * delta * 144 ); setScale(0); + if((pointer.x > 0.8 || pointer.x < -0.8) && currentSpeed > 20 && isOnFloor.current){ + leftWheel.current.isSpinning = true; + } else { + leftWheel.current.isSpinning = false; + } } if (accumulatedDriftPower.current > blueTurboThreshold) { setTurboColor(0x00ffff); @@ -559,6 +586,8 @@ export const PlayerController = ({ opacity={0.4} /> + + */} - + { - const [isOnGround, setIsOnGround] = useState(false); const body = useRef(); const kart = useRef(); @@ -84,7 +82,8 @@ export const PlayerControllerGamepad = ({ const effectiveBoost = useRef(0); const text = useRef(); - const { actions, shouldSlowDown, item, bananas, coins, id, controls } = useStore(); + const { actions, shouldSlowDown, item, bananas, coins, id, controls } = + useStore(); const slowDownDuration = useRef(1500); const { buttonA, buttonB, RB, LB, joystick, select, start } = useGamepad(); @@ -94,14 +93,11 @@ export const PlayerControllerGamepad = ({ const leftWheel = useRef(); const isDrifting = useRef(false); useEffect(() => { - if(leftWheel.current && rightWheel.current && body.current) { + if (leftWheel.current && rightWheel.current && body.current) { actions.setLeftWheel(leftWheel.current); actions.setRightWheel(rightWheel.current); - actions.setIsDrifting(isDrifting.current); } }, [body.current]); - - useFrame(({ pointer, clock }, delta) => { if (player.id !== id) return; @@ -129,6 +125,7 @@ export const PlayerControllerGamepad = ({ if (start) { actions.setGameStarted(false); } + leftWheel.current.kartRotation = kartRotation ; if (!driftLeft.current && !driftRight.current) { steeringAngle = currentSteeringSpeed * -joystick[0]; @@ -169,6 +166,7 @@ export const PlayerControllerGamepad = ({ } } if (shouldSlow) { + rightWheel.current.isSpinning = true; setCurrentSpeed( Math.max(currentSpeed - decceleration * 2 * delta * 144, 0) ); @@ -176,6 +174,7 @@ export const PlayerControllerGamepad = ({ slowDownDuration.current -= 1500 * delta; setShouldLaunch(true); if (slowDownDuration.current <= 1) { + rightWheel.current.isSpinning = false; actions.setShouldSlowDown(false); slowDownDuration.current = 1500; setShouldLaunch(false); @@ -299,9 +298,13 @@ export const PlayerControllerGamepad = ({ steeringAngle * 25 + 0.4, 0.05 * delta * 144 ); - accumulatedDriftPower.current += 0.1 * (steeringAngle + 1) * delta * 144; + if(isOnFloor.current){ + leftWheel.current.isSpinning = true; + accumulatedDriftPower.current += 0.1 * (steeringAngle + 1) * delta * 144; + + } } - if (driftRight.current) { + if (driftRight.current ) { driftDirection.current = -1; driftForce.current = 0.4; mario.current.rotation.y = THREE.MathUtils.lerp( @@ -309,7 +312,11 @@ export const PlayerControllerGamepad = ({ -(-steeringAngle * 25 + 0.4), 0.05 * delta * 144 ); - accumulatedDriftPower.current += 0.1 * (-steeringAngle + 1) * delta * 144; + if(isOnFloor.current){ + leftWheel.current.isSpinning = true; + accumulatedDriftPower.current += 0.1 * (-steeringAngle + 1) * delta * 144; + + } } if (!driftLeft.current && !driftRight.current) { mario.current.rotation.y = THREE.MathUtils.lerp( @@ -318,6 +325,12 @@ export const PlayerControllerGamepad = ({ 0.05 * delta * 144 ); setScale(0); + + if((joystick[0] > 0.8 || joystick[0] < -0.8) && currentSpeed > 20 && isOnFloor.current){ + leftWheel.current.isSpinning = true; + } else { + leftWheel.current.isSpinning = false; + } } if (accumulatedDriftPower.current > blueTurboThreshold) { setTurboColor(0x00ffff); @@ -387,6 +400,7 @@ export const PlayerControllerGamepad = ({ 0.01 * delta * 144 ); + cam.current.position.z = THREE.MathUtils.lerp( cam.current.position.z, targetZPosition, @@ -473,7 +487,6 @@ export const PlayerControllerGamepad = ({ actions.useItem(); } - player.setState("position", body.current.translation()); player.setState("rotation", kartRotation + mario.current.rotation.y); player.setState("isBoosting", isBoosting); @@ -550,8 +563,7 @@ export const PlayerControllerGamepad = ({ opacity={0.4} /> - - + - - + {/* */} - { + if (leftWheel.current && rightWheel.current && body.current) { + actions.setLeftWheel(leftWheel.current); + actions.setRightWheel(rightWheel.current); + } + }, [body.current]); + useFrame(({ pointer, clock }, delta) => { if (player.id !== id) return; const time = clock.getElapsedTime(); @@ -116,7 +127,7 @@ export const PlayerControllerKeyboard = ({ 0, -Math.cos(kartRotation) ); - + leftWheel.current.kartRotation = kartRotation; if (escPressed) { actions.setGameStarted(false); } @@ -168,6 +179,7 @@ export const PlayerControllerKeyboard = ({ } } if (shouldSlow) { + rightWheel.current.isSpinning = true; setCurrentSpeed( Math.max(currentSpeed - decceleration * 2 * delta * 144, 0) ); @@ -175,6 +187,7 @@ export const PlayerControllerKeyboard = ({ slowDownDuration.current -= 1500 * delta; setShouldLaunch(true); if (slowDownDuration.current <= 1) { + rightWheel.current.isSpinning = false; actions.setShouldSlowDown(false); slowDownDuration.current = 1500; setShouldLaunch(false); @@ -300,7 +313,11 @@ export const PlayerControllerKeyboard = ({ steeringAngle * 25 + 0.4, 0.05 * delta * 144 ); - accumulatedDriftPower.current += 0.1 * (steeringAngle + 1) * delta * 144; + if (isOnFloor.current) { + leftWheel.current.isSpinning = true; + accumulatedDriftPower.current += + 0.1 * (steeringAngle + 1) * delta * 144; + } } if (driftRight.current) { driftDirection.current = -1; @@ -310,7 +327,11 @@ export const PlayerControllerKeyboard = ({ -(-steeringAngle * 25 + 0.4), 0.05 * delta * 144 ); - accumulatedDriftPower.current += 0.1 * (-steeringAngle + 1) * delta * 144; + if (isOnFloor.current) { + leftWheel.current.isSpinning = true; + accumulatedDriftPower.current += + 0.1 * (-steeringAngle + 1) * delta * 144; + } } if (!driftLeft.current && !driftRight.current) { mario.current.rotation.y = THREE.MathUtils.lerp( @@ -319,6 +340,11 @@ export const PlayerControllerKeyboard = ({ 0.05 * delta * 144 ); setScale(0); + if((leftPressed || rightPressed) && currentSpeed > 20 && isOnFloor.current){ + leftWheel.current.isSpinning = true; + } else { + leftWheel.current.isSpinning = false; + } } if (accumulatedDriftPower.current > blueTurboThreshold) { setTurboColor(0x00ffff); @@ -529,6 +555,8 @@ export const PlayerControllerKeyboard = ({ opacity={0.4} /> + + + */} - + { + if (leftWheel.current && rightWheel.current && body.current) { + actions.setLeftWheel(leftWheel.current); + actions.setRightWheel(rightWheel.current); + } + }, [body.current]); useFrame(({ pointer, clock }, delta) => { if (player.id !== id) return; @@ -108,7 +117,7 @@ export const PlayerControllerTouch = ({ 0, -Math.cos(kartRotation) ); - + leftWheel.current.kartRotation = kartRotation; if (menuButton) { actions.setGameStarted(false); } @@ -153,6 +162,8 @@ export const PlayerControllerTouch = ({ ); } if (shouldSlow) { + rightWheel.current.isSpinning = true; + setCurrentSpeed( Math.max(currentSpeed - decceleration * 2 * delta * 144, 0) ); @@ -160,6 +171,8 @@ export const PlayerControllerTouch = ({ slowDownDuration.current -= 1500 * delta; setShouldLaunch(true); if (slowDownDuration.current <= 1) { + rightWheel.current.isSpinning = false; + actions.setShouldSlowDown(false); slowDownDuration.current = 1500; setShouldLaunch(false); @@ -252,7 +265,11 @@ export const PlayerControllerTouch = ({ steeringAngle * 25 + 0.4, 0.05 * delta * 144 ); - accumulatedDriftPower.current += 0.1 * (steeringAngle + 1) * delta * 144; + if(isOnFloor.current){ + leftWheel.current.isSpinning = true; + accumulatedDriftPower.current += 0.1 * (steeringAngle + 1) * delta * 144; + + } } if (driftRight.current) { driftDirection.current = -1; @@ -262,7 +279,11 @@ export const PlayerControllerTouch = ({ -(-steeringAngle * 25 + 0.4), 0.05 * delta * 144 ); - accumulatedDriftPower.current += 0.1 * (-steeringAngle + 1) * delta * 144; + if(isOnFloor.current){ + leftWheel.current.isSpinning = true; + accumulatedDriftPower.current += 0.1 * (-steeringAngle + 1) * delta * 144; + + } } if (!driftLeft.current && !driftRight.current) { mario.current.rotation.y = THREE.MathUtils.lerp( @@ -271,6 +292,11 @@ export const PlayerControllerTouch = ({ 0.05 * delta * 144 ); setScale(0); + if((joystickX > 0.8 || joystickX < -0.8) && currentSpeed > 20 && isOnFloor.current){ + leftWheel.current.isSpinning = true; + } else { + leftWheel.current.isSpinning = false; + } } if (accumulatedDriftPower.current > blueTurboThreshold) { setTurboColor(0x00ffff); @@ -466,6 +492,8 @@ export const PlayerControllerTouch = ({ opacity={0.4} /> + + { - const isDrifting = useStore.getState() - console.log(isDrifting) - if (leftWheel && rightWheel && ref.current && isDrifting) { - setItemAt(ref.current, leftWheel.rotation, leftWheel, index++); - setItemAt(ref.current, rightWheel.rotation, rightWheel, index++); + const rotation = leftWheel.kartRotation; + if (leftWheel && rightWheel && ref.current && (leftWheel.isSpinning || rightWheel.isSpinning)) { + setItemAt(ref.current, rotation, leftWheel, index++); + setItemAt(ref.current, rotation, rightWheel, index++); if (index === count) index = 0 } @@ -48,7 +47,7 @@ export function Skid({ count = 500, opacity = 0.5, size = 0.3 }) { function setItemAt(instances, rotation, body, index) { o.position.copy(body.getWorldPosition(v)); - o.rotation.copy(rotation) + o.rotation.set(0, rotation, 0); o.scale.setScalar(1) o.updateMatrix() instances.setMatrixAt(index, o.matrix)