Contenido del curso

Fundamentos de Programación

Desarrollando un juego con HTML y JavaScript

Estilos con CSS

Optimización de código

Mapa con canvas

Backend: videojuego multijugador

Elimina el parpadeo con map en JavaScript

Resumen

Cuando construyes un videojuego multijugador con frontend y backend, el retardo en la comunicación genera un parpadeo visible en los jugadores enemigos. Para evitarlo, puedes optimizar el renderizado en JavaScript usando una variable auxiliar y la función map, manteniendo el dibujo fluido aunque los datos del servidor lleguen con delay.

¿Por qué aparece el parpadeo en un videojuego multijugador?

El parpadeo ocurre porque cada vez que el cliente solicita las coordenadas actualizadas de los enemigos al servidor, existe un pequeño retardo en esa respuesta. Durante ese intervalo, si dibujas directamente lo que llega del backend, el personaje se oculta y se muestra repetidamente, generando un efecto visual molesto.

¿Qué causa el parpadeo de un sprite en un juego online? El delay entre frontend y backend. Si dibujas solo cuando llegan datos nuevos, hay frames vacíos entre respuestas. La solución es dibujar siempre desde una variable local que se actualice cuando llegue nueva información.

La idea central es separar el flujo de datos del flujo de renderizado. Tu frontend debe pintar continuamente desde una fuente local, y solo refrescar esa fuente cuando el backend entregue datos frescos.

¿Cómo se usa una variable auxiliar para suavizar el render?

La estrategia consiste en declarar una lista global llamada moqueponesEnemigos, inicialmente vacía, que vivirá en el frontend y servirá como fuente única para dibujar [02:00].

Esta variable se coloca arriba del archivo, junto a las otras declaraciones globales como la lista moquepones. Así queda accesible desde cualquier parte del código del cliente.

javascript let moqueponesEnemigos = [];

Con esa lista en su lugar, el dibujo de enemigos ya no depende del momento exacto en que responde el servidor. Tú decides cuándo pintar y desde dónde leer.

¿Cuál es la diferencia entre forEach y map en este caso?

Antes, el código usaba un forEach sobre la respuesta del servidor para pintar a cada enemigo en cada ciclo. forEach itera y ejecuta una función por elemento, pero no devuelve nada [02:30].

La función map, en cambio, recorre la lista y retorna una nueva lista con el mismo número de elementos transformados. Eso es justo lo que necesitas: convertir la respuesta cruda del backend en objetos listos para dibujar y guardarlos en tu variable auxiliar.

¿Qué hace map en JavaScript? Recorre un array y retorna uno nuevo con cada elemento transformado por la función que le pases. A diferencia de forEach, map sí devuelve un valor por cada iteración.

El reemplazo se ve así en la lógica:

  • Antes con forEach: por cada enemigo recibido, llamar inmediatamente a pintarMoquepon.
  • Ahora con map: por cada enemigo recibido, retornar el objeto y guardarlo en moqueponesEnemigos.
  • Resultado: la lista local queda actualizada sin pintar nada todavía.

javascript moqueponesEnemigos = enemigos.map(enemigo => { // construir el moquepón enemigo return moqueponEnemigo; });

Fíjate en el cambio clave: dentro del map ya no se llama a pintarMoquepon. Esa línea se reemplaza por un return que devuelve el moquepón generado.

¿Dónde se ejecuta ahora el dibujo de los enemigos?

El pintado se mueve fuera de la petición de enviar posición y queda en el flujo continuo de renderizado, justo debajo de enviarPosicion [03:30].

Ahí sí usas un forEach sobre moqueponesEnemigos, porque en este punto solo necesitas ejecutar el método de dibujo, no transformar datos.

javascript moqueponesEnemigos.forEach(moquepon => { moquepon.pintarMoquepon(); });

Con esta separación, el navegador dibuja a los enemigos en cada frame desde la lista local. Cuando llega una respuesta nueva del backend, map refresca esa lista, pero el render nunca se queda sin datos que mostrar.

¿Cómo se comprueba que el bug desapareció?

Después de guardar los cambios, reinicias el servidor y abres dos ventanas del navegador. En una eliges a Ratiguella y en la otra a Hipodosh.

Al mover un personaje hacia el pasto o las flores, la otra ventana refleja el movimiento sin parpadeos. El sprite ya no se oculta entre frames, y la experiencia se siente continua [04:30].

Esta optimización aprovecha tres ideas que conviene tener claras:

  • Separación de responsabilidades: el backend entrega datos, el frontend decide cuándo y cómo dibujarlos.
  • Estado local como buffer: la variable moqueponesEnemigos actúa como caché entre cada respuesta del servidor.
  • map para transformar, forEach para ejecutar: usa cada uno según retornes valor o solo ejecutes acción.

Con esto cierras la segunda parte del videojuego: el mapa multijugador con jugadores conectados, movimiento sincronizado y render fluido. La siguiente etapa es la mecánica de combate, donde dos jugadores chocan, intercambian ataques y se resuelve el ganador.

¿Aplicarías esta misma técnica de variable auxiliar en otros proyectos en tiempo real? Cuéntame en los comentarios qué bug visual resolverías con map.