La función cambiará la posición de la serpiente al eliminar la cola y agregar una nueva cabeza en la dirección necesaria (Vector X / Y). Pero cuando presiono cualquier botón, los vectores no cambian.
const canvas = document.getElementById('map'); const cs = canvas.getContext('2d'); function drawSqr(color, size, position){ cs.fillStyle = color; cs.fillRect(position[0] * size, position[1] * size, size, size); } const sqrSize = 20; cs.fillStyle = "#000000"; cs.fillRect(0, 0, canvas.width, canvas.height); let vectorX = 0, vectorY = 0; let snake = { position : [ [1, 1], [2, 1], [3, 1], ], color: "#00FFFF", snakeRender: function(event){ document.addEventListener('keydown', function(event, vectorX, vectorY){ switch(event){ case "w": vectorX = 0, vectorY = 1; break; case "a": vectorX = -1, vectorY = 0; break; case "s": vectorX = 0, vectorY = -1; break; case "d": vectorX = 1, vectorY = 0; break; } return alert(event + " was pressed!"); }); let [x, y] = this.position.at(-1); this.position.push([x + vectorX, y + vectorY]); let oldTail = this.position.shift() console.log(this.position) console.log(vectorX, vectorY) drawSqr("#000000", sqrSize, oldTail); for(let pos of this.position){ drawSqr(this.color, sqrSize, pos); } setTimeout(() => snake.snakeRender(), 1000); } }; snake.snakeRender(); <!DOCTYPE html> <html> <head> <title>The snake</title> <meta charset="utf-8"> </head> <body> <canvas id="map" width="1280" height="720"></canvas> <script src="script.js"></script> </body> </html>Los vectores Ps cambiarán cuando presiones "W", "A", "S", "D". Creo que el problema está en setTimeOut pero no sé cómo puedo solucionarlo. Gracias por tu ayuda. Pps he comprobado si el programa ve los botones presionados y se devuelve [objeto KeyboardEvent]
Prueba esto:
switch(ev.key){ case "w": vectorX = 0, vectorY = 1; break; case "a": vectorX = -1, vectorY = 0; break; case "s": vectorX = 0, vectorY = -1; break; case "d": vectorX = 1, vectorY = 0; break; }Hay dos problemas:
function(ev, vectorX, vectorY) significa que actualizar vectorX y vectorY actualizará esas variables locales y no las globales declaradas aquí: let vectorX = 0, vectorY = 0; . (Y solo los globales son accesibles para los actualizadores).switch(ev) en lugar de switch(ev.key) significa que nunca coincidirá con ninguna tecla, porque ev es un objeto, no una cadena. const canvas = document.getElementById('map'); const cs = canvas.getContext('2d'); function drawSqr(color, size, position){ cs.fillStyle = color; cs.fillRect(position[0] * size, position[1] * size, size, size); } const sqrSize = 20; cs.fillStyle = "#000000"; cs.fillRect(0, 0, canvas.width, canvas.height); let vectorX = 0, vectorY = 0; let snake = { position : [ [1, 1], [2, 1], [3, 1], ], color: "#00FFFF", snakeRender: function(event){ document.addEventListener('keydown', function(ev){ switch(ev.key){ case "w": vectorX = 0, vectorY = 1; break; case "a": vectorX = -1, vectorY = 0; break; case "s": vectorX = 0, vectorY = -1; break; case "d": vectorX = 1, vectorY = 0; break; } return }); let [x, y] = this.position.at(-1); this.position.push([x + vectorX, y + vectorY]); let oldTail = this.position.shift() console.log(this.position) console.log(vectorX, vectorY) drawSqr("#000000", sqrSize, oldTail); for(let pos of this.position){ drawSqr(this.color, sqrSize, pos); } setTimeout(() => snake.snakeRender(), 1000); } }; snake.snakeRender(); <!DOCTYPE html> <html> <head> <title>The snake</title> <meta charset="utf-8"> </head> <body> <canvas id="map" width="1280" height="720"></canvas> <script src="script.js"></script> </body> </html> Además, agregar un detector de eventos cada vez snakeRender() significa que hay muchos detectores de eventos, cada uno haciendo lo mismo. Sin embargo, no ajusté nada allí.