message
parent
faad40aa9d
commit
a8cf0d1ca4
|
@ -13,10 +13,10 @@
|
|||
"@react-three/postprocessing": "^2.15.11",
|
||||
"@react-three/rapier": "^1.2.1",
|
||||
"gsap": "^3.12.5",
|
||||
"joymap": "^2.2.4",
|
||||
"leva": "^0.9.35",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-gamepad": "^1.0.3",
|
||||
"three": "^0.160.1",
|
||||
"zustand": "^4.5.0"
|
||||
},
|
||||
|
@ -1862,6 +1862,11 @@
|
|||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||
},
|
||||
"node_modules/fast-memoize": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz",
|
||||
"integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw=="
|
||||
},
|
||||
"node_modules/fflate": {
|
||||
"version": "0.6.10",
|
||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz",
|
||||
|
@ -2140,6 +2145,16 @@
|
|||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/joymap": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/joymap/-/joymap-2.2.4.tgz",
|
||||
"integrity": "sha512-5N0VMbym49AwrfUz0vD6tE++I50SFjBYtwcJsdgE086GgAraGB2YQFsgVj+cG2fd8eUFmK+8U36Ecud3/UYTRg==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.9.2",
|
||||
"fast-memoize": "^2.5.2",
|
||||
"lodash": "^4.17.15"
|
||||
}
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
|
@ -2583,14 +2598,6 @@
|
|||
"react": ">= 16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-gamepad": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/react-gamepad/-/react-gamepad-1.0.3.tgz",
|
||||
"integrity": "sha512-gMwITmfoHtCaMFpDaEshcjeibHAgynXD28NnS2pa+dG+stwNoN66YDVizN7GfyIrYiW5Ft1ubRxs6/2xW9sRhQ==",
|
||||
"peerDependencies": {
|
||||
"react": ">=15.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
"@react-three/postprocessing": "^2.15.11",
|
||||
"@react-three/rapier": "^1.2.1",
|
||||
"gsap": "^3.12.5",
|
||||
"joymap": "^2.2.4",
|
||||
"leva": "^0.9.35",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-gamepad": "^1.0.3",
|
||||
"three": "^0.160.1",
|
||||
"zustand": "^4.5.0"
|
||||
},
|
||||
|
|
|
@ -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 { useGamepad } from "./useGamepad";
|
||||
|
||||
export const PlayerController = () => {
|
||||
const upPressed = useKeyboardControls((state) => state[Controls.up]);
|
||||
|
@ -63,14 +64,16 @@ export const PlayerController = () => {
|
|||
let targetZPosition = 8;
|
||||
const [steeringAngleWheels, setSteeringAngleWheels] = useState(0);
|
||||
const engineSound = useRef();
|
||||
const { buttonA, joystick, RB } = useGamepad();
|
||||
|
||||
const [scale, setScale] = useState(0);
|
||||
const { actions, addPastPosition } = useStore();
|
||||
|
||||
useFrame(({ pointer, clock }, delta) => {
|
||||
const time = clock.getElapsedTime();
|
||||
if (!body.current && !mario.current) return;
|
||||
|
||||
// console.log(buttonA, joystick);
|
||||
|
||||
// HANDLING AND STEERING
|
||||
const kartRotation =
|
||||
kart.current.rotation.y - driftDirection.current * driftForce.current;
|
||||
|
@ -79,8 +82,6 @@ export const PlayerController = () => {
|
|||
0,
|
||||
-Math.cos(kartRotation)
|
||||
);
|
||||
actions.setBodyPosition(body.current.translation());
|
||||
actions.setBodyRotation(kart.current.rotation);
|
||||
|
||||
if (leftPressed && currentSpeed > 0) {
|
||||
steeringAngle = currentSteeringSpeed;
|
||||
|
@ -95,6 +96,7 @@ export const PlayerController = () => {
|
|||
}
|
||||
|
||||
// mouse steering
|
||||
const steer = joystick[0] * 0.8;
|
||||
|
||||
if (!driftLeft.current && !driftRight.current) {
|
||||
steeringAngle = currentSteeringSpeed * -pointer.x;
|
||||
|
@ -106,6 +108,19 @@ export const PlayerController = () => {
|
|||
steeringAngle = currentSteeringSpeed * -(pointer.x + 0.5);
|
||||
targetXPosition = -camMaxOffset * -pointer.x;
|
||||
}
|
||||
|
||||
if (steer) {
|
||||
if (!driftLeft.current && !driftRight.current) {
|
||||
steeringAngle = currentSteeringSpeed * -joystick[0];
|
||||
targetXPosition = -camMaxOffset * -joystick[0];
|
||||
} else if (driftLeft.current && !driftRight.current) {
|
||||
steeringAngle = currentSteeringSpeed * -(joystick[0] - 1);
|
||||
targetXPosition = -camMaxOffset * -joystick[0];
|
||||
} else if (driftRight.current && !driftLeft.current) {
|
||||
steeringAngle = currentSteeringSpeed * -(joystick[0] + 1);
|
||||
targetXPosition = -camMaxOffset * -joystick[0];
|
||||
}
|
||||
}
|
||||
// ACCELERATING
|
||||
|
||||
if (upPressed && currentSpeed < maxSpeed) {
|
||||
|
@ -133,6 +148,33 @@ export const PlayerController = () => {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (buttonA && currentSpeed < maxSpeed) {
|
||||
// Accelerate the kart within the maximum speed limit
|
||||
setCurrentSpeed(
|
||||
Math.min(currentSpeed + acceleration * delta * 144, maxSpeed)
|
||||
);
|
||||
} else if (
|
||||
buttonA &&
|
||||
currentSpeed > maxSpeed &&
|
||||
boostDuration.current > 0
|
||||
) {
|
||||
setCurrentSpeed(
|
||||
Math.max(currentSpeed - decceleration * delta * 144, maxSpeed)
|
||||
);
|
||||
}
|
||||
|
||||
if (buttonA) {
|
||||
if (currentSteeringSpeed < MaxSteeringSpeed) {
|
||||
setCurrentSteeringSpeed(
|
||||
Math.min(
|
||||
currentSteeringSpeed + 0.0001 * delta * 144,
|
||||
MaxSteeringSpeed
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// REVERSING
|
||||
if (downPressed && currentSpeed < -maxSpeed) {
|
||||
setCurrentSpeed(
|
||||
|
@ -140,7 +182,7 @@ export const PlayerController = () => {
|
|||
);
|
||||
}
|
||||
// DECELERATING
|
||||
else if (!upPressed && !downPressed) {
|
||||
else if (!buttonA && !downPressed) {
|
||||
if (currentSteeringSpeed > 0) {
|
||||
setCurrentSteeringSpeed(
|
||||
Math.max(currentSteeringSpeed - 0.00005 * delta * 144, 0)
|
||||
|
@ -177,23 +219,46 @@ export const PlayerController = () => {
|
|||
jumpForce.current += 10;
|
||||
isOnFloor.current = false;
|
||||
jumpIsHeld.current = true;
|
||||
} else if (RB && isOnFloor.current && !jumpIsHeld.current) {
|
||||
jumpForce.current += 10;
|
||||
isOnFloor.current = false;
|
||||
jumpIsHeld.current = true;
|
||||
}
|
||||
|
||||
if (!isOnFloor.current && jumpForce.current > 0) {
|
||||
jumpForce.current -= 1 * delta * 144;
|
||||
}
|
||||
if (!jumpPressed) {
|
||||
if (!jumpPressed && !RB) {
|
||||
jumpIsHeld.current = false;
|
||||
driftDirection.current = 0;
|
||||
driftForce.current = 0;
|
||||
driftLeft.current = false;
|
||||
driftRight.current = false;
|
||||
}
|
||||
console.log(jumpIsHeld.current);
|
||||
// DRIFTING
|
||||
// if (
|
||||
// jumpIsHeld.current &&
|
||||
// currentSteeringSpeed > 0 &&
|
||||
// pointer.x < -0.1 &&
|
||||
// !driftRight.current
|
||||
// ) {
|
||||
// driftLeft.current = true;
|
||||
// }
|
||||
// if (
|
||||
// jumpIsHeld.current &&
|
||||
// currentSteeringSpeed > 0 &&
|
||||
// pointer.x > 0.1 &&
|
||||
// !driftLeft.current
|
||||
// ) {
|
||||
// driftRight.current = true;
|
||||
// }
|
||||
|
||||
if (steer) {
|
||||
if (
|
||||
jumpIsHeld.current &&
|
||||
currentSteeringSpeed > 0 &&
|
||||
pointer.x < -0.1 &&
|
||||
steer < -0.1 &&
|
||||
!driftRight.current
|
||||
) {
|
||||
driftLeft.current = true;
|
||||
|
@ -201,11 +266,12 @@ export const PlayerController = () => {
|
|||
if (
|
||||
jumpIsHeld.current &&
|
||||
currentSteeringSpeed > 0 &&
|
||||
pointer.x > 0.1 &&
|
||||
steer > 0.1 &&
|
||||
!driftLeft.current
|
||||
) {
|
||||
driftRight.current = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!jumpIsHeld.current && !driftLeft.current && !driftRight.current) {
|
||||
mario.current.rotation.y = THREE.MathUtils.lerp(
|
||||
|
@ -324,7 +390,7 @@ export const PlayerController = () => {
|
|||
<RigidBody
|
||||
ref={body}
|
||||
colliders={false}
|
||||
position={[8, 20, -96]}
|
||||
position={[8, 100, -96]}
|
||||
centerOfMass={[0, -1, 0]}
|
||||
mass={3}
|
||||
ccd
|
||||
|
@ -335,12 +401,8 @@ export const PlayerController = () => {
|
|||
onCollisionEnter={(event) => {
|
||||
isOnFloor.current = true;
|
||||
}}
|
||||
// onCollisionExit={(event) => {
|
||||
// isOnFloor.current = false
|
||||
// }}
|
||||
/>
|
||||
</RigidBody>
|
||||
|
||||
<group ref={kart} rotation={[0, Math.PI / 2, 0]}>
|
||||
<group ref={mario}>
|
||||
<Mario
|
||||
|
@ -348,13 +410,6 @@ export const PlayerController = () => {
|
|||
steeringAngleWheels={steeringAngleWheels}
|
||||
isBoosting={isBoosting}
|
||||
/>
|
||||
{/* <pointLight
|
||||
position={[0.6, 0.05, 0.5]}
|
||||
intensity={scale}
|
||||
color={turboColor}
|
||||
distance={1}
|
||||
/> */}
|
||||
|
||||
<mesh position={[0.6, 0.05, 0.5]} scale={scale}>
|
||||
<sphereGeometry args={[0.05, 16, 16]} />
|
||||
<meshStandardMaterial
|
||||
|
@ -365,12 +420,6 @@ export const PlayerController = () => {
|
|||
opacity={0.4}
|
||||
/>
|
||||
</mesh>
|
||||
{/* <pointLight
|
||||
position={[-0.6, 0.05, 0.5]}
|
||||
intensity={scale}
|
||||
color={turboColor}
|
||||
distance={1}
|
||||
/> */}
|
||||
<mesh position={[-0.6, 0.05, 0.5]} scale={scale}>
|
||||
<sphereGeometry args={[0.05, 16, 16]} />
|
||||
<meshStandardMaterial
|
||||
|
@ -381,15 +430,6 @@ export const PlayerController = () => {
|
|||
opacity={0.4}
|
||||
/>
|
||||
</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} />
|
||||
<DriftParticlesLeft turboColor={turboColor} scale={scale} />
|
||||
<DriftParticlesRight turboColor={turboColor} scale={scale} />
|
||||
|
@ -414,15 +454,12 @@ export const PlayerController = () => {
|
|||
turboColor={turboColor}
|
||||
/>
|
||||
</group>
|
||||
|
||||
{/* <ContactShadows frames={1} /> */}
|
||||
<PerspectiveCamera
|
||||
makeDefault
|
||||
position={[0, 2, 8]}
|
||||
fov={50}
|
||||
ref={cam}
|
||||
/>
|
||||
{/* <PositionalAudio ref={engineSound} url="./sounds/engine.wav" autoplay loop distance={10}/> */}
|
||||
</group>
|
||||
</group>
|
||||
);
|
||||
|
|
|
@ -57,7 +57,7 @@ function setItemAt(instances, bodyPosition, bodyRotation, index) {
|
|||
.add(bodyPosition);
|
||||
|
||||
// Apply the offset to position the skid marks behind the body
|
||||
console.log(bodyPosition);
|
||||
// console.log(bodyPosition);
|
||||
o.position.copy(bodyPosition.x, bodyPosition.y + 2, bodyPosition.z);
|
||||
|
||||
o.rotation.set(0, bodyRotation, 0);
|
||||
|
|
|
@ -6,6 +6,39 @@ export const useStore = create((set, get) => ({
|
|||
bodyPosition: [0, 0, 0],
|
||||
bodyRotation: [0, 0, 0],
|
||||
pastPositions: [],
|
||||
LeftAxis: [0, 0],
|
||||
buttons : {
|
||||
A: false,
|
||||
B: false,
|
||||
X: false,
|
||||
Y: false,
|
||||
LB: false,
|
||||
RB: false,
|
||||
LT: false,
|
||||
RT: false,
|
||||
Back: false,
|
||||
Start: false,
|
||||
LeftStick: false,
|
||||
RightStick: false,
|
||||
Up: false,
|
||||
Down: false,
|
||||
Left: false,
|
||||
Right: false,
|
||||
},
|
||||
setLeftAxis: (axis) => {
|
||||
set({ LeftAxis: axis });
|
||||
},
|
||||
setButtons: (button, value) => {
|
||||
set((state) => ({
|
||||
buttons: {
|
||||
...state.buttons,
|
||||
[button]: value,
|
||||
},
|
||||
}));
|
||||
},
|
||||
getButtons: () => {
|
||||
return get().buttons;
|
||||
},
|
||||
addPastPosition: (position) => {
|
||||
set((state) => ({
|
||||
pastPositions: [position, ...state.pastPositions.slice(0, 499)],
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
import { useState, useEffect } from 'react';
|
||||
|
||||
export const useGamepad = () => {
|
||||
const [gamepadInfo, setGamepadInfo] = useState({ connected: false, buttonA: false, joystick: [0, 0], RB: false });
|
||||
|
||||
// Function to update gamepad state
|
||||
const updateGamepadState = () => {
|
||||
const gamepads = navigator.getGamepads ? navigator.getGamepads() : [];
|
||||
const gamepad = gamepads[0]; // Assuming the first gamepad
|
||||
|
||||
if (gamepad) {
|
||||
const newGamepadInfo = {
|
||||
connected: true,
|
||||
buttonA: gamepad.buttons[0].pressed,
|
||||
RB: gamepad.buttons[5].pressed,
|
||||
joystick: [gamepad.axes[0], gamepad.axes[1]]
|
||||
};
|
||||
|
||||
// Update state only if there's a change
|
||||
if (JSON.stringify(newGamepadInfo) !== JSON.stringify(gamepadInfo)) {
|
||||
setGamepadInfo(newGamepadInfo);
|
||||
}
|
||||
} else {
|
||||
if (gamepadInfo.connected) {
|
||||
setGamepadInfo({ connected: false, buttonA: false, joystick: [0, 0], RB: false });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const gamepadConnected = () => {
|
||||
console.log('Gamepad connected!');
|
||||
updateGamepadState();
|
||||
};
|
||||
|
||||
const gamepadDisconnected = () => {
|
||||
console.log('Gamepad disconnected!');
|
||||
setGamepadInfo({ connected: false, buttonA: false, joystick: [0, 0], RB: false });
|
||||
};
|
||||
|
||||
window.addEventListener('gamepadconnected', gamepadConnected);
|
||||
window.addEventListener('gamepaddisconnected', gamepadDisconnected);
|
||||
|
||||
// Polling the gamepad state
|
||||
const interval = setInterval(updateGamepadState, 100);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('gamepadconnected', gamepadConnected);
|
||||
window.removeEventListener('gamepaddisconnected', gamepadDisconnected);
|
||||
clearInterval(interval);
|
||||
};
|
||||
}, [gamepadInfo]);
|
||||
|
||||
return gamepadInfo;
|
||||
};
|
Loading…
Reference in New Issue