diff --git a/package-lock.json b/package-lock.json
index 9a53cfb..41114d9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -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",
diff --git a/package.json b/package.json
index 110a1e7..7012caa 100644
--- a/package.json
+++ b/package.json
@@ -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"
},
diff --git a/src/components/PlayerController.jsx b/src/components/PlayerController.jsx
index b1f1d06..1dd2361 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 { 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,34 +219,58 @@ 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 (
+ // 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 &&
+ steer < -0.1 &&
+ !driftRight.current
+ ) {
+ driftLeft.current = true;
+ }
+ if (
+ jumpIsHeld.current &&
+ currentSteeringSpeed > 0 &&
+ steer > 0.1 &&
+ !driftLeft.current
+ ) {
+ driftRight.current = true;
+ }
}
if (!jumpIsHeld.current && !driftLeft.current && !driftRight.current) {
@@ -324,7 +390,7 @@ export const PlayerController = () => {
{
onCollisionEnter={(event) => {
isOnFloor.current = true;
}}
- // onCollisionExit={(event) => {
- // isOnFloor.current = false
- // }}
/>
-
{
steeringAngleWheels={steeringAngleWheels}
isBoosting={isBoosting}
/>
- {/* */}
-
{
opacity={0.4}
/>
- {/* */}
{
opacity={0.4}
/>
-
- {/*
-
- */}
- {/* */}
@@ -414,15 +454,12 @@ export const PlayerController = () => {
turboColor={turboColor}
/>
-
- {/* */}
- {/* */}
);
diff --git a/src/components/Skid.jsx b/src/components/Skid.jsx
index 06bb461..f023584 100644
--- a/src/components/Skid.jsx
+++ b/src/components/Skid.jsx
@@ -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);
diff --git a/src/components/store.jsx b/src/components/store.jsx
index da4455a..a23a4c1 100644
--- a/src/components/store.jsx
+++ b/src/components/store.jsx
@@ -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)],
diff --git a/src/components/useGamepad.jsx b/src/components/useGamepad.jsx
new file mode 100644
index 0000000..b347660
--- /dev/null
+++ b/src/components/useGamepad.jsx
@@ -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;
+};