Hello im kinda new to React im trying to make a kinda snake game, but im struggling at the movement.
the x and y value are never realy changed he is only able to move a like 1 gridcell but when i press another key he jsut goes to the starting position and goes 1 cell in the other direction.. what am i missing?
function App() {
const [_x, setX] = useState(0);
const [_y, setY] = useState(0);
let lastPressedKey = '';
let gameTicker = null;
function triggerMovement(x, y) {
if (lastPressedKey === 100)
move(10, 0);
if (lastPressedKey === 97)
move(-10, 0);
if (lastPressedKey === 119)
move(0, 10);
if (lastPressedKey === 155)
move(0, -10);
}
function move(x, y){
console.log(lastPressedKey);
console.log(x, _x, y, _y);
setX(_x x);
setY(_y y);
}
function handleKeyEvent(event) {
lastPressedKey = event.keyCode;
}
function startTimer() {
gameTicker = setInterval(triggerMovement, 1000);
}
function clearTimer() {
clearInterval(gameTicker)
}
const element = (
<div>
<Screen farbe="darkslategray">
<Snake x={_x} y={_y} farbe="red"/>
</Screen>
<button onClick={startTimer} style={{
bottom: 5,
position: 'absolute'
}}>
Start Game
</button>
<button onClick={clearTimer} style={{
bottom: 5,
left: 625,
position: 'absolute'
}}>
StopGame
</button>
</div>
)
window.addEventListener('keypress', handleKeyEvent, true);
return element;
}
function Snake(props){
const [x, setX] = useState(250);
const [y, setY] = useState(250);
let speed = props.speed;
const element = (
<div style={{
width: 10,
height: 10,
backgroundColor: props.farbe,
position: 'absolute',
left: props.x,
bottom: props.y
}}>
</div>
)
return element;
}
Really trying to get behind this, but I'm trying to get this snake to move since this morning idk what I'm missing here.
The console logs are always
10, 0 , 0 , 0
10, 0 , 0 , 10
10, 0 , 0 , 0 ...
CodePudding user response:
It is because of stale closures.
Here
function move(x, y){
console.log(lastPressedKey);
console.log(x, _x, y, _y);
setX(_x x);
setY(_y y);
}
_x
and _y
are referencing values from the render in which you called the startTimer
function.
You can use functional form of setState
to avoid this problem:
setX(ps => ps x)