my old gamePage look like this :
import React, { useEffect, useState, useRef } from 'react';
import GamepadManager from '../utils/GamepadManager';
import Stick from '../utils/Stick';
import PlatoTemplate from '../organisms/platoTemplate';
import mapConfigFile from '../assets/mapConfig/BepoStyle.json';
import '../styles/gamePage.css';
import LetterFall from '../organisms/LetterFall';
import { useDispatch, useSelector } from 'react-redux';
import { hit } from '../controler/lettersSlice';
import { addPrintableLetters } from '../controler/printableLettersSlice';
export default function GamePage() {
const dispatch = useDispatch();
const mapConfig = mapConfigFile;
const letters = useSelector((state) => state.letters);
const printableLetters = useSelector((state) => state.printableLetters);
const lettersRef = useRef(letters);
const [plato, setPlato] = useState(mapConfig.plato[0]);
const [key, setKey] = useState('');
const requestRef = useRef();
let lastButtonPressed = [];
useEffect(() => {
lettersRef.current = letters;
}, [letters]);
useEffect(() => {
lettersRef.current = printableLetters;
}, [printableLetters]);
useEffect(() => {
const Gamepad = new GamepadManager();
const leftStick = new Stick(0, 0);
const rightStick = new Stick(0, 0);
const selectPlato = ({ leftStickPosition, rightStickPosition }) => {
const findedPlato = mapConfig.plato.find(plato => {
return plato.joystick[0] === leftStickPosition && plato.joystick[1] === rightStickPosition;
});
setPlato(findedPlato);
return findedPlato;
};
const selectKey = (curentPlato, buttonsPressed) => {
const buttonPresse = buttonsPressed.findIndex(button => button === true);
//je suis pas super fiere de mon systéme de gestion des input je me prendrais la tete dessus plus tard
if (buttonPresse === -1) {
lastButtonPressed = [];
}
if (buttonPresse === -1 || curentPlato === null || curentPlato === undefined) return;
if (lastButtonPressed.includes(buttonPresse)) return;
lastButtonPressed.push(buttonPresse);
console.log(lettersRef.current);
const keyPressed = curentPlato.KeyTab[mapConfig.buttonId[buttonPresse]];
dispatch(hit(keyPressed));
setKey(keyPressed);
};
const getGamepadsInfo = () => {
const gamepadState = Gamepad.getState();
if (gamepadState == null) return;
leftStick.setDirection(gamepadState.axes[0], gamepadState.axes[1]);
rightStick.setDirection(gamepadState.axes[2], gamepadState.axes[3]);
const curentPlato = selectPlato({ leftStickPosition: leftStick.getDirection(), rightStickPosition: rightStick.getDirection() });
selectKey(curentPlato, gamepadState.buttonsPressed);
};
const gameLoop = () => {
getGamepadsInfo();
requestRef.current = requestAnimationFrame(gameLoop);
};
requestRef.current = requestAnimationFrame(gameLoop);
return () => cancelAnimationFrame(requestRef.current);
}, [mapConfig]);
const test = () => {
console.log(letters);
}
const addPlato = (platoId) => {
console.log(platoId);
const plato = mapConfig.plato.find(plato => plato.id === platoId);
//mettre les non selectionner en gris
mapConfig.plato.forEach(plato => {
plato.selected = false;
});
plato.selected = true;
console.log(plato);
Object.entries(plato.KeyTab).forEach(([buttonId, key]) => {
if (key && key !== "void" && key !== "" &&
!["Space", "Backspace", "Tab", "Enter", "Esc"].includes(key)) {
if (key.length === 1) {
dispatch(addPrintableLetters(key));
}
else if (key.length > 1) {
dispatch(addPrintableLetters(key.slice(0, 1)));
}
}
});
}
return (
<div className='gamePage'>
<button onClick={test}>test</button>
<button onClick={addPlato}>test2</button>
{plato != null ? <PlatoTemplate plato={plato} /> : null}
<LetterFall />
<div className='key'>{key}</div>
<div className='score'>{letters.length}</div>
<div className='map' onClick={() => console.log('click')}>
{mapConfig.plato.map(plato =>
<div
className={plato.selected ? 'selected' : 'notSelected'}
onClick={() => {
console.log('Plato clicked:', plato.id);
addPlato(plato.id);
}}>
<PlatoTemplate key={plato.id} plato={plato} />
</div>
)}
</div>
</div>
);
}
and now i just replace all whit this :
import React, { useEffect, useState, useRef } from 'react';
import GamepadManager from '../utils/GamepadManager';
import Stick from '../utils/Stick';
import PlatoTemplate from '../organisms/platoTemplate';
import mapConfigFile from '../assets/mapConfig/BepoStyle.json';
import '../styles/gamePage.css';
import LetterFall from '../organisms/LetterFall';
import { useDispatch, useSelector } from 'react-redux';
import { hit } from '../controler/lettersSlice';
import { addPrintableLetters } from '../controler/printableLettersSlice';
import MapConfig from '../utils/MapConfig';
export default function GamePage() {
const dispatch = useDispatch();
const mapConfig = new MapConfig(mapConfigFile);
const letters = useSelector((state) => state.letters);
const printableLetters = useSelector((state) => state.printableLetters);
const lettersRef = useRef(letters);
const [plato, setPlato] = useState(mapConfig.platos[0]);
const [key, setKey] = useState('');
const requestRef = useRef();
let lastButtonPressed = [];
const lastTime = useRef(0);
useEffect(() => {
lettersRef.current = letters;
}, [letters]);
useEffect(() => {
lettersRef.current = printableLetters;
}, [printableLetters]);
useEffect(() => {
const Gamepad = new GamepadManager();
const leftStick = new Stick(0, 0);
const rightStick = new Stick(0, 0);
const selectPlato = ({ leftStickPosition, rightStickPosition }) => {
const findedPlato = mapConfig.platos[0] ;//mapConfig.platos.find(plato => plato.sameJostick([leftStickPosition, rightStickPosition]));
setPlato(findedPlato);
return findedPlato;
};
const selectKey = (curentPlato, buttonsPressed) => {
const buttonPresse = buttonsPressed.findIndex(button => button === true);
//je suis pas super fiere de mon systéme de gestion des input je me prendrais la tete dessus plus tard
if (buttonPresse === -1) {
lastButtonPressed = [];
}
if (buttonPresse === -1 || curentPlato === null || curentPlato === undefined) return;
if (lastButtonPressed.includes(buttonPresse)) return;
lastButtonPressed.push(buttonPresse);
console.log(lettersRef.current);
const keyPressed = curentPlato.keys[mapConfig.buttons[buttonPresse]];
dispatch(hit(keyPressed));
setKey(keyPressed);
};
const getGamepadsInfo = () => {
const gamepadState = Gamepad.getState();
if (gamepadState == null) return;
leftStick.setDirection(gamepadState.axes[0], gamepadState.axes[1]);
rightStick.setDirection(gamepadState.axes[2], gamepadState.axes[3]);
const curentPlato = selectPlato({ leftStickPosition: leftStick.getDirection(), rightStickPosition: rightStick.getDirection() });
selectKey(curentPlato, gamepadState.buttonsPressed);
};
const gameLoop = (timestamp) => {
if (timestamp - lastTime.current >= 1000) {
console.log("timestamp:", timestamp)
getGamepadsInfo();
lastTime.current = timestamp;
}
requestRef.current = requestAnimationFrame(gameLoop);
};
requestRef.current = requestAnimationFrame(gameLoop);
return () => cancelAnimationFrame(requestRef.current);
}, [mapConfig]);
const addPlato = (platoId) => {
console.log(platoId);
const plato = mapConfig.platos.find(plato => plato.id === platoId);
//mettre les non selectionner en gris
plato.selected = true;
plato.keyList.forEach(key => {
dispatch(addPrintableLetters(key));
})
}
return (
<div className='gamePage'>
{plato != null ? <PlatoTemplate plato={plato} /> : null}
<LetterFall />
<div className='key'>{key}</div>
<div className='score'>{letters.length}</div>
<div className='map' >
{mapConfig.platos.map(plato =>
<div key={plato.id}
className={plato.selected ? 'selected' : 'notSelected'}
onClick={() => {
addPlato(plato.id);
}}>
<PlatoTemplate key={plato.id} plato={plato} />
</div>
)}
</div>
</div>
);
}
i replace requestAnimationFrame whit setTimeout and it work again . but i want to use requestAnimationFrame !
my MapConfig is just a setter
import Plato from "./PlatoHandler";
export default class MapConfig {
constructor(mapConfig) {
this.buttons = mapConfig.buttonId;
this.platos = [];
mapConfig.plato.forEach(plato => {
this.platos.push(new Plato(plato));
});
}
}
and same for plato class
whit a litel extra if function
export default class Plato {
constructor(plato) {
this.id = plato.id;
this.joystick = plato.joystick;
//liste de touche mapper avec l'id des touches
this.keys = plato.KeyTab;
this.selected = false;
//lister les touches
this.keyList = [];
// Object.entries(plato.KeyTab).forEach(([buttonId, key]) => {
// if (key && key !== "void" && key !== "" &&
// !["Space", "Backspace", "Tab", "Enter", "Esc"].includes(key)) {
// this.keyList.push(key);
// }
// });
}
sameJostick(joystick) {
if (this.joystick[0] === joystick[0] && this.joystick[1] === joystick[1]) {
return true;
}
return false;
}
}
also i can show you my gamepadcontroller. is realy basic
export default class GamepadManager {
/**
* Initializes the GamepadManager object and sets up event listeners for gamepad connection and disconnection.
* Also starts the gamepad loop to update the gamepad state at each frame.
*/
controllerIndex = {
index: null,
};
constructor() {
window.addEventListener('gamepadconnected', (event) => {
console.log('Gamepad connected:', event.gamepad);
this.controllerIndex = event.gamepad.index;
});
window.addEventListener('gamepaddisconnected', (event) => {
console.log('Gamepad disconnected:', event.gamepad);
this.controllerIndex = null;
});
}
updateGamepadState() {
if (!this.gamepad) {
return;
}
this.previousGamepadState = { ...this.currentGamepadState };
this.currentGamepadState = {
buttons: this.gamepad.buttons.map(button => button.pressed),
axes: this.gamepad.axes.map(axis => axis.toFixed(2)),
};
}
getState() {
if (this.controllerIndex === null) return null;
const gamepad = navigator.getGamepads()[this.controllerIndex];
if (!gamepad) return null;
return {
buttonsPressed: gamepad.buttons.map(el => el.pressed),
axes: gamepad.axes.map(axis => axis.toFixed(2)),
};
}
}
i will ad more funciton in this 2 class later and make game page litter .
i asking myself i am supose to do some
react return in class ?
so i can make a function to return this in mapConfig
<div className='map' >
{mapConfig.platos.map(plato =>
<div key={plato.id}
className={plato.selected ? 'selected' : 'notSelected'}
onClick={() => {
addPlato(plato.id);
}}>
<PlatoTemplate key={plato.id} plato={plato} />
</div>
)}
</div>
or we are not supos to use react like this ?