Necesito hacer un juego de pexeso como tarea para la escuela. Básicamente he implementado todo el juego, pero estoy atascado en el problema setTimeout.
Esta es la lógica principal del juego:
let firstCard = null; let secondCard = null; let points = 0; let turnedCards = 0; const createCard = (cityName) => { const card = document.createElement('div'); card.classList.add('card'); card.innerText = cityName; card.addEventListener('click', () => { if (firstCard == null) { firstCard = card; card.classList.add('revealed'); } else if (secondCard == null) { secondCard = card; card.classList.add('revealed'); if (firstCard.innerText == secondCard.innerText && firstCard != secondCard && !firstCard.classList.contains('final') && !secondCard.classList.contains('final')) { updateScore(); firstCard.classList.add('final'); secondCard.classList.add('final'); } else { setTimeout(() => { if (!firstCard.classList.contains('final')) { firstCard.classList.remove('revealed'); } if (!secondCard.classList.contains('final')) { secondCard.classList.remove('revealed'); } },2000); } firstCard = null; secondCard = null; } }); gameArea.appendChild(card); }el método setTimeout está ahí para darle algo de tiempo para ver las cartas giradas. Ahora, cuando empiezo este juego, siempre obtengo
main.js:38 Uncaught TypeError: Cannot read properties of null (reading 'classList')Que provienen de firstCard.classList y secondCard.classList en el método setTimeout. Quiero decir, ¿cómo pueden ser nulos firstCard y secondCard, si les asigné un valor explícitamente justo antes de que se ejecutara el método?
Cualquier ayuda apreciada :)
Como se señaló en un comentario, lo más probable es que el error se deba a las asignaciones
firstCard = null; secondCard = null; que se ejecutan antes de la devolución de llamada setTimeout . De hecho, la devolución de llamada se ejecuta con un retraso de 2000 ms, por lo que lo más probable es que se haya ejecutado esa asignación.
No estoy seguro de si esto romperá la lógica del juego, pero una solución podría ser mover estas asignaciones dentro de la misma devolución de llamada setTimeout (así como en la rama "entonces" del bloque if más grande).
if (firstCard.innerText == secondCard.innerText && firstCard != secondCard && !firstCard.classList.contains('final') && !secondCard.classList.contains('final')) { updateScore(); firstCard.classList.add('final'); secondCard.classList.add('final'); firstCard = null; secondCard = null; } else { setTimeout(() => { if (!firstCard.classList.contains('final')) { firstCard.classList.remove('revealed'); } if (!secondCard.classList.contains('final')) { secondCard.classList.remove('revealed'); } firstCard = null; secondCard = null; },2000); } La guía de Mozilla para setTimeout podría ser un buen recurso para ayudar con este problema: https://developer.mozilla.org/en-US/docs/Web/API/setTimeout