From a8cf0d1ca494b556792c60238cb298a40d4deac2 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 26 Jan 2024 14:07:58 +0100 Subject: [PATCH] message --- package-lock.json | 25 +++-- package.json | 2 +- src/components/PlayerController.jsx | 137 ++++++++++++++++++---------- src/components/Skid.jsx | 2 +- src/components/store.jsx | 33 +++++++ src/components/useGamepad.jsx | 55 +++++++++++ 6 files changed, 193 insertions(+), 61 deletions(-) create mode 100644 src/components/useGamepad.jsx 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; +};