feat:(game) adding multiplayer
parent
df76bb5f35
commit
b825b0fc20
|
@ -14,6 +14,7 @@
|
||||||
"@react-three/rapier": "^1.2.1",
|
"@react-three/rapier": "^1.2.1",
|
||||||
"gsap": "^3.12.5",
|
"gsap": "^3.12.5",
|
||||||
"leva": "^0.9.35",
|
"leva": "^0.9.35",
|
||||||
|
"playroomkit": "^0.0.61",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-gamepad": "^1.0.3",
|
"react-gamepad": "^1.0.3",
|
||||||
|
@ -2423,6 +2424,15 @@
|
||||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/playroomkit": {
|
||||||
|
"version": "0.0.61",
|
||||||
|
"resolved": "https://registry.npmjs.org/playroomkit/-/playroomkit-0.0.61.tgz",
|
||||||
|
"integrity": "sha512-BUjGkZZcV5OQ29sTmjjI3Ad0SZLRvuBYWAdu4MqhnCjiaHTDJp4KvacVx6rJEJe9jdamtCimkZ/5XXuGm9h2AQ==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=17.0.2 <= 18",
|
||||||
|
"react-dom": ">=17.0.2 <= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.4.33",
|
"version": "8.4.33",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz",
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
"@react-three/rapier": "^1.2.1",
|
"@react-three/rapier": "^1.2.1",
|
||||||
"gsap": "^3.12.5",
|
"gsap": "^3.12.5",
|
||||||
"leva": "^0.9.35",
|
"leva": "^0.9.35",
|
||||||
|
"playroomkit": "^0.0.61",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-gamepad": "^1.0.3",
|
"react-gamepad": "^1.0.3",
|
||||||
|
|
24
src/App.jsx
24
src/App.jsx
|
@ -1,8 +1,10 @@
|
||||||
import { Canvas } from '@react-three/fiber'
|
import { Canvas } from '@react-three/fiber'
|
||||||
import { Experience } from './components/Experience'
|
import { Experience } from './components/Experience'
|
||||||
import { Suspense, useMemo } from 'react'
|
import { Suspense, useEffect, useMemo } from 'react'
|
||||||
import { Physics } from '@react-three/rapier'
|
import { Physics } from '@react-three/rapier'
|
||||||
import { KeyboardControls, Loader, OrbitControls, Preload, Stats } from '@react-three/drei'
|
import { KeyboardControls, Loader, OrbitControls, Preload, Stats } from '@react-three/drei'
|
||||||
|
import { insertCoin, onPlayerJoin } from 'playroomkit'
|
||||||
|
import { useStore } from "./components/store";
|
||||||
|
|
||||||
export const Controls = {
|
export const Controls = {
|
||||||
up: 'up',
|
up: 'up',
|
||||||
|
@ -29,6 +31,26 @@ function App() {
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const { actions } = useStore();
|
||||||
|
const start = async () => {
|
||||||
|
await insertCoin();
|
||||||
|
|
||||||
|
onPlayerJoin((state) => {
|
||||||
|
actions.addPlayer(state);
|
||||||
|
console.log('player joined', state);
|
||||||
|
actions.setId(state.id);
|
||||||
|
|
||||||
|
state.onQuit(() => {
|
||||||
|
actions.removePlayer(state);
|
||||||
|
console.log('player quit', state);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
start();
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Loader />
|
<Loader />
|
||||||
|
|
|
@ -40,7 +40,6 @@ export const HUD = () => {
|
||||||
default:
|
default:
|
||||||
setImage("");
|
setImage("");
|
||||||
}
|
}
|
||||||
console.log(item);
|
|
||||||
}, [item]);
|
}, [item]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -23,16 +23,32 @@ import { ItemBox } from "./models/misc/Gift";
|
||||||
import { useStore } from "./store";
|
import { useStore } from "./store";
|
||||||
import { Shell } from "./models/items/Mario_shell_red";
|
import { Shell } from "./models/items/Mario_shell_red";
|
||||||
import { Coin } from "./models/misc/Super_mario_bros_coin";
|
import { Coin } from "./models/misc/Super_mario_bros_coin";
|
||||||
|
import { RPC, insertCoin, myPlayer, onPlayerJoin, useMultiplayerState } from "playroomkit";
|
||||||
|
import { PlayerDummies } from "./PlayerDummies";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useFrame } from "@react-three/fiber";
|
||||||
|
|
||||||
export const Experience = () => {
|
export const Experience = () => {
|
||||||
const onCollide = (event) => {
|
const onCollide = (event) => {
|
||||||
console.log(event);
|
console.log(event);
|
||||||
};
|
};
|
||||||
const { bananas, shells} = useStore();
|
const { bananas, shells, players, id, actions} = useStore();
|
||||||
|
const [networkBananas, setNetworkBananas] = useMultiplayerState("bananas", []);
|
||||||
|
|
||||||
|
const [networkShells, setNetworkShells] = useMultiplayerState("shells", []);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PlayerController />
|
{players.map((player) => (
|
||||||
|
<PlayerController key={player.id} player={player} userPlayer={player.id === myPlayer()?.id} />
|
||||||
|
))}
|
||||||
|
|
||||||
|
{players.map((player) => (
|
||||||
|
<PlayerDummies key={player.id} player={player} userPlayer={player.id === myPlayer()?.id} />
|
||||||
|
))}
|
||||||
|
|
||||||
|
|
||||||
<Paris position={[0, 0, 0]} />
|
<Paris position={[0, 0, 0]} />
|
||||||
<Banana onCollide={onCollide} position={[-10, 1.8, -119]} />
|
<Banana onCollide={onCollide} position={[-10, 1.8, -119]} />
|
||||||
{/* <Shell position={[-20, 2, -119]} /> */}
|
{/* <Shell position={[-20, 2, -119]} /> */}
|
||||||
|
@ -44,7 +60,7 @@ export const Experience = () => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{bananas.map((banana) => (
|
{/* {bananas.map((banana) => (
|
||||||
<Banana
|
<Banana
|
||||||
key={banana.id}
|
key={banana.id}
|
||||||
position={banana.position}
|
position={banana.position}
|
||||||
|
@ -52,7 +68,7 @@ export const Experience = () => {
|
||||||
id={banana.id}
|
id={banana.id}
|
||||||
// rotation={banana.rotation}
|
// rotation={banana.rotation}
|
||||||
/>
|
/>
|
||||||
))}
|
))} */}
|
||||||
|
|
||||||
{shells.map((shell) => (
|
{shells.map((shell) => (
|
||||||
<Shell
|
<Shell
|
||||||
|
|
|
@ -26,8 +26,10 @@ import FakeGlowMaterial from "./ShaderMaterials/FakeGlow/FakeGlowMaterial";
|
||||||
import { HitParticles } from "./Particles/hits/HitParticles";
|
import { HitParticles } from "./Particles/hits/HitParticles";
|
||||||
import { CoinParticles } from "./Particles/coins/CoinParticles";
|
import { CoinParticles } from "./Particles/coins/CoinParticles";
|
||||||
import { ItemParticles } from "./Particles/items/ItemParticles";
|
import { ItemParticles } from "./Particles/items/ItemParticles";
|
||||||
|
import { isHost } from "playroomkit";
|
||||||
|
|
||||||
|
export const PlayerController = ( { player, userPlayer }) => {
|
||||||
|
|
||||||
export const PlayerController = () => {
|
|
||||||
const upPressed = useKeyboardControls((state) => state[Controls.up]);
|
const upPressed = useKeyboardControls((state) => state[Controls.up]);
|
||||||
const downPressed = useKeyboardControls((state) => state[Controls.down]);
|
const downPressed = useKeyboardControls((state) => state[Controls.down]);
|
||||||
const leftPressed = useKeyboardControls((state) => state[Controls.left]);
|
const leftPressed = useKeyboardControls((state) => state[Controls.left]);
|
||||||
|
@ -85,11 +87,11 @@ export const PlayerController = () => {
|
||||||
const effectiveBoost = useRef(0);
|
const effectiveBoost = useRef(0);
|
||||||
|
|
||||||
|
|
||||||
const { actions, shouldSlowDown, item, bananas, coins} = useStore();
|
const { actions, shouldSlowDown, item, bananas, coins, id} = useStore();
|
||||||
const slowDownDuration = useRef(1500);
|
const slowDownDuration = useRef(1500);
|
||||||
|
|
||||||
|
|
||||||
useFrame(({ pointer, clock }, delta) => {
|
useFrame(({ pointer, clock }, delta) => {
|
||||||
|
if(player.id !== id) return;
|
||||||
const time = clock.getElapsedTime();
|
const time = clock.getElapsedTime();
|
||||||
if (!body.current && !mario.current) return;
|
if (!body.current && !mario.current) return;
|
||||||
engineSound.current.setVolume(currentSpeed / 300 + 0.2);
|
engineSound.current.setVolume(currentSpeed / 300 + 0.2);
|
||||||
|
@ -121,6 +123,8 @@ export const PlayerController = () => {
|
||||||
targetXPosition = 0;
|
targetXPosition = 0;
|
||||||
1;
|
1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// mouse steering
|
// mouse steering
|
||||||
|
|
||||||
|
@ -464,9 +468,19 @@ export const PlayerController = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
player.setState("position", body.current.translation());
|
||||||
|
player.setState("rotation", kartRotation + mario.current.rotation.y);
|
||||||
|
player.setState("isBoosting", isBoosting);
|
||||||
|
player.setState("shouldLaunch", shouldLaunch);
|
||||||
|
player.setState("turboColor", turboColor);
|
||||||
|
player.setState("scale", scale);
|
||||||
|
player.setState("bananas", bananas);
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return player.id === id ?(
|
||||||
<group>
|
<group>
|
||||||
<RigidBody
|
<RigidBody
|
||||||
ref={body}
|
ref={body}
|
||||||
|
@ -476,6 +490,7 @@ export const PlayerController = () => {
|
||||||
mass={3}
|
mass={3}
|
||||||
ccd
|
ccd
|
||||||
name="player"
|
name="player"
|
||||||
|
type={player.id === id ? "dynamic" : "kinematic"}
|
||||||
>
|
>
|
||||||
<BallCollider
|
<BallCollider
|
||||||
args={[0.5]}
|
args={[0.5]}
|
||||||
|
@ -631,5 +646,5 @@ export const PlayerController = () => {
|
||||||
/>
|
/>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
);
|
) : null;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,252 @@
|
||||||
|
import { Controls } from "../App";
|
||||||
|
import { BallCollider, RigidBody, useRapier, vec3 } from "@react-three/rapier";
|
||||||
|
import {
|
||||||
|
useKeyboardControls,
|
||||||
|
PerspectiveCamera,
|
||||||
|
ContactShadows,
|
||||||
|
Sphere,
|
||||||
|
OrbitControls,
|
||||||
|
Trail,
|
||||||
|
PositionalAudio,
|
||||||
|
} from "@react-three/drei";
|
||||||
|
import { useFrame, useThree } from "@react-three/fiber";
|
||||||
|
import { useRef, useState, useEffect, useCallback } from "react";
|
||||||
|
import * as THREE from "three";
|
||||||
|
|
||||||
|
import { Mario } from "./models/characters/Mario_kart";
|
||||||
|
import { DriftParticlesLeft } from "./Particles/drifts/DriftParticlesLeft";
|
||||||
|
import { DriftParticlesRight } from "./Particles/drifts/DriftParticlesRight";
|
||||||
|
|
||||||
|
import { PointParticle } from "./Particles/drifts/PointParticle";
|
||||||
|
|
||||||
|
import { FlameParticles } from "./Particles/flames/FlameParticles";
|
||||||
|
import { useStore } from "./store";
|
||||||
|
import { Cylinder } from "@react-three/drei";
|
||||||
|
import FakeGlowMaterial from "./ShaderMaterials/FakeGlow/FakeGlowMaterial";
|
||||||
|
import { HitParticles } from "./Particles/hits/HitParticles";
|
||||||
|
import { CoinParticles } from "./Particles/coins/CoinParticles";
|
||||||
|
import { ItemParticles } from "./Particles/items/ItemParticles";
|
||||||
|
import { isHost } from "playroomkit";
|
||||||
|
import { Banana } from "./models/items/Banana_peel_mario_kart";
|
||||||
|
|
||||||
|
export const PlayerDummies = ( { player, userPlayer }) => {
|
||||||
|
const upPressed = useKeyboardControls((state) => state[Controls.up]);
|
||||||
|
const downPressed = useKeyboardControls((state) => state[Controls.down]);
|
||||||
|
const leftPressed = useKeyboardControls((state) => state[Controls.left]);
|
||||||
|
const rightPressed = useKeyboardControls((state) => state[Controls.right]);
|
||||||
|
const jumpPressed = useKeyboardControls((state) => state[Controls.jump]);
|
||||||
|
const shootPressed = useKeyboardControls((state) => state[Controls.shoot]);
|
||||||
|
const resetPressed = useKeyboardControls((state) => state[Controls.reset]);
|
||||||
|
|
||||||
|
const [isOnGround, setIsOnGround] = useState(false);
|
||||||
|
const body = useRef();
|
||||||
|
const kart = useRef();
|
||||||
|
const cam = useRef();
|
||||||
|
const initialSpeed = 0;
|
||||||
|
const maxSpeed = 30;
|
||||||
|
const boostSpeed = 50;
|
||||||
|
const acceleration = 0.1;
|
||||||
|
const decceleration = 0.2;
|
||||||
|
const damping = -0.1;
|
||||||
|
const MaxSteeringSpeed = 0.01;
|
||||||
|
const [currentSteeringSpeed, setCurrentSteeringSpeed] = useState(0);
|
||||||
|
const [currentSpeed, setCurrentSpeed] = useState(initialSpeed);
|
||||||
|
const camMaxOffset = 1;
|
||||||
|
let steeringAngle = 0;
|
||||||
|
const isOnFloor = useRef(false);
|
||||||
|
const jumpForce = useRef(0);
|
||||||
|
const jumpIsHeld = useRef(false);
|
||||||
|
const driftDirection = useRef(0);
|
||||||
|
const driftLeft = useRef(false);
|
||||||
|
const driftRight = useRef(false);
|
||||||
|
const driftForce = useRef(0);
|
||||||
|
const mario = useRef();
|
||||||
|
const accumulatedDriftPower = useRef(0);
|
||||||
|
const blueTurboThreshold = 10;
|
||||||
|
const orangeTurboThreshold = 30;
|
||||||
|
const purpleTurboThreshold = 60;
|
||||||
|
const [turboColor, setTurboColor] = useState(0xffffff);
|
||||||
|
const boostDuration = useRef(0);
|
||||||
|
const [isBoosting, setIsBoosting] = useState(false);
|
||||||
|
let targetXPosition = 0;
|
||||||
|
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 raycaster = new THREE.Raycaster();
|
||||||
|
const downDirection = new THREE.Vector3(0, -1, 0);
|
||||||
|
const [shouldLaunch, setShouldLaunch] = useState(false);
|
||||||
|
const effectiveBoost = useRef(0);
|
||||||
|
const [networkBananas, setNetworkBananas] = useState([]);
|
||||||
|
const [networkShells, setNetworkShells] = useState([]);
|
||||||
|
|
||||||
|
|
||||||
|
const { actions, shouldSlowDown, item, coins, id} = useStore();
|
||||||
|
const slowDownDuration = useRef(1500);
|
||||||
|
|
||||||
|
useFrame((state, delta) => {
|
||||||
|
const bodyPosition = player.getState("position");
|
||||||
|
const bodyRotation = player.getState("rotation");
|
||||||
|
setIsBoosting(player.getState("isBoosting"));
|
||||||
|
setShouldLaunch(player.getState("shouldLaunch"));
|
||||||
|
setTurboColor(player.getState("turboColor"));
|
||||||
|
setScale(player.getState("scale"));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(bodyPosition && bodyRotation && kart.current && mario.current){
|
||||||
|
kart.current.position.set(bodyPosition.x, bodyPosition.y -.5, bodyPosition.z);
|
||||||
|
kart.current.rotation.set(0, bodyRotation, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return player.id != id? (
|
||||||
|
<>
|
||||||
|
<group>
|
||||||
|
|
||||||
|
<group ref={kart} rotation={[0, Math.PI / 2, 0]}>
|
||||||
|
<group ref={mario}>
|
||||||
|
<Mario
|
||||||
|
currentSpeed={currentSpeed}
|
||||||
|
steeringAngleWheels={steeringAngleWheels}
|
||||||
|
isBoosting={isBoosting}
|
||||||
|
/>
|
||||||
|
<CoinParticles coins={coins}/>
|
||||||
|
<ItemParticles item={item}/>
|
||||||
|
<mesh position={[0.6, 0.05, 0.5]} scale={scale}>
|
||||||
|
<sphereGeometry args={[0.05, 16, 16]} />
|
||||||
|
<meshStandardMaterial
|
||||||
|
emissive={turboColor}
|
||||||
|
toneMapped={false}
|
||||||
|
emissiveIntensity={100}
|
||||||
|
transparent
|
||||||
|
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>
|
||||||
|
<mesh position={[-0.6, 0.05, 0.5]} scale={scale}>
|
||||||
|
<sphereGeometry args={[0.05, 16, 16]} />
|
||||||
|
<meshStandardMaterial
|
||||||
|
emissive={turboColor}
|
||||||
|
toneMapped={false}
|
||||||
|
emissiveIntensity={100}
|
||||||
|
transparent
|
||||||
|
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>
|
||||||
|
|
||||||
|
{/* <FlameParticles isBoosting={isBoosting} /> */}
|
||||||
|
<DriftParticlesLeft turboColor={turboColor} scale={scale} />
|
||||||
|
<DriftParticlesRight turboColor={turboColor} scale={scale} />
|
||||||
|
<PointParticle
|
||||||
|
position={[-0.6, 0.05, 0.5]}
|
||||||
|
png="./particles/circle.png"
|
||||||
|
turboColor={turboColor}
|
||||||
|
/>
|
||||||
|
<PointParticle
|
||||||
|
position={[0.6, 0.05, 0.5]}
|
||||||
|
png="./particles/circle.png"
|
||||||
|
turboColor={turboColor}
|
||||||
|
/>
|
||||||
|
<PointParticle
|
||||||
|
position={[-0.6, 0.05, 0.5]}
|
||||||
|
png="./particles/star.png"
|
||||||
|
turboColor={turboColor}
|
||||||
|
/>
|
||||||
|
<PointParticle
|
||||||
|
position={[0.6, 0.05, 0.5]}
|
||||||
|
png="./particles/star.png"
|
||||||
|
turboColor={turboColor}
|
||||||
|
/>
|
||||||
|
<HitParticles shouldLaunch={shouldLaunch}/>
|
||||||
|
</group>
|
||||||
|
|
||||||
|
{/* <ContactShadows frames={1} /> */}
|
||||||
|
<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>
|
||||||
|
</>
|
||||||
|
) : null;
|
||||||
|
};
|
|
@ -20,11 +20,13 @@ export const useStore = create((set, get) => ({
|
||||||
pastPositions: [],
|
pastPositions: [],
|
||||||
shouldSlowdown: false,
|
shouldSlowdown: false,
|
||||||
bananas: [],
|
bananas: [],
|
||||||
items: ["banana", "shell", "mushroom"],
|
items: ["banana"],
|
||||||
item: "",
|
item: "",
|
||||||
shells: [],
|
shells: [],
|
||||||
skids: [],
|
skids: [],
|
||||||
coins : 0,
|
coins : 0,
|
||||||
|
players : [],
|
||||||
|
id : "",
|
||||||
addPastPosition: (position) => {
|
addPastPosition: (position) => {
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
pastPositions: [position, ...state.pastPositions.slice(0, 499)],
|
pastPositions: [position, ...state.pastPositions.slice(0, 499)],
|
||||||
|
@ -87,6 +89,9 @@ export const useStore = create((set, get) => ({
|
||||||
bananas: state.bananas.filter((b) => b.id !== id),
|
bananas: state.bananas.filter((b) => b.id !== id),
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
setBananas: (bananas) => {
|
||||||
|
set({ bananas });
|
||||||
|
},
|
||||||
setItem:() => {
|
setItem:() => {
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
item: state.items[Math.floor(Math.random() * state.items.length)],
|
item: state.items[Math.floor(Math.random() * state.items.length)],
|
||||||
|
@ -122,6 +127,19 @@ export const useStore = create((set, get) => ({
|
||||||
coins: state.coins - 1,
|
coins: state.coins - 1,
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
addPlayer : (player) => {
|
||||||
|
set((state) => ({
|
||||||
|
players: [...state.players, player],
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
removePlayer : (player) => {
|
||||||
|
set((state) => ({
|
||||||
|
players: state.players.filter((p) => p.id !== player.id),
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
setId : (id) => {
|
||||||
|
set({id});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
}));
|
}));
|
||||||
|
|
Loading…
Reference in New Issue