New Sep 19, 2024

I try to make a class to turn my react neater. and now use efffect or requestAnimation make my game controller disconect [closed]

Libraries, Frameworks, etc. All from Newest questions tagged reactjs - Stack Overflow View I try to make a class to turn my react neater. and now use efffect or requestAnimation make my game controller disconect [closed] on stackoverflow.com

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 ?

Scroll to top