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

Movimiento continuo en canvas con setInterval

Resumen

Aprende a mover un personaje dentro de un canvas en todas las direcciones y a lograr movimiento continuo en JavaScript mientras mantienes presionado un botón. Esta guía te sirve si estás creando tu primer videojuego web y quieres entender cómo combinar eventos de mouse, velocidad y setInterval para animar a tu personaje.

¿Cómo creo botones de movimiento en las cuatro direcciones?

El primer paso es darle al jugador control en los cuatro ejes. Para eso duplicas la línea del botón en HTML cuatro veces y asignas una función distinta a cada una: moverArriba, moverIzquierda, moverAbajo y moverDerecha.

Cada función modifica las coordenadas del personaje de forma diferente:

  • Derecha: suma 5 píxeles en x.
  • Izquierda: resta 5 píxeles en x.
  • Abajo: suma 5 píxeles en y.
  • Arriba: resta 5 píxeles en y.

En un canvas de HTML5 el eje y crece hacia abajo, no hacia arriba como en matemáticas. Por eso para subir restas y para bajar sumas. Pequeño detalle, gran diferencia.

¿Por qué se resta en y para mover hacia arriba? Porque en un canvas el origen (0,0) está en la esquina superior izquierda y los valores de y aumentan hacia abajo. Restar acerca al personaje al borde superior.

¿Cómo logro movimiento continuo mientras dejo presionado un botón?

El evento onclick solo dispara la acción una vez, así que aunque mantengas el botón presionado, el personaje se mueve un solo paso. Para un juego eso no funciona.

La solución es reemplazar onclick por dos eventos que detectan cuándo empieza y cuándo termina la interacción: onmouseover para iniciar el movimiento y onmouseout para detenerlo. Mientras el cursor esté sobre el botón, el personaje sigue moviéndose; cuando sale, se detiene.

Un truco útil del editor: si tienes varias líneas que empiezan igual, presiona Ctrl + D para seleccionarlas todas a la vez y editarlas en paralelo. Acelera muchísimo el trabajo cuando repites estructuras.

¿Cómo asigno velocidad a Capipepo en lugar de moverlo directamente?

Aquí viene el cambio mental importante. En vez de sumar píxeles directamente cada vez que haces clic, le das al personaje dos propiedades: velocidadX y velocidadY, ambas iniciadas en cero dentro de la clase Moquepom.

Las funciones de movimiento ya no pintan al personaje, solo actualizan su velocidad:

  • moverDerecha: velocidadX = 5.
  • moverIzquierda: velocidadX = -5.
  • moverAbajo: velocidadY = 5.
  • moverArriba: velocidadY = -5.

¿Por qué separar velocidad y dibujo? Porque el evento se ejecuta una sola vez al activarlo, pero el dibujo del personaje necesita ejecutarse muchas veces para que veas la animación. La velocidad queda guardada como un estado que persiste hasta que el botón se suelte.

¿Cómo uso setInterval para animar al personaje en el canvas?

La función pintarPersonaje ahora actualiza la posición usando la velocidad guardada:

javascript capipepo.x = capipepo.x + capipepo.velocidadX; capipepo.y = capipepo.y + capipepo.velocidadY;

Para que esa actualización ocurra de forma constante usas setInterval, una función nativa de JavaScript que ejecuta otra función cada cierto número de milisegundos.

javascript intervalo = setInterval(pintarPersonaje, 50);

Con 50 milisegundos entre cada ejecución, el personaje se redibuja unas 20 veces por segundo, suficiente para que el ojo perciba un movimiento fluido.

¿Qué hace setInterval en JavaScript? Ejecuta una función repetidamente con un intervalo de tiempo en milisegundos. Recibe dos parámetros: la función que se va a ejecutar y el tiempo de espera entre cada ejecución.

¿Cómo detengo el movimiento al soltar el botón?

La función detenerMovimiento que enlazas a onmouseout simplemente regresa ambas velocidades a cero:

javascript capipepo.velocidadX = 0; capipepo.velocidadY = 0;

El setInterval sigue ejecutándose, pero como la velocidad es cero, la posición del personaje deja de cambiar. Visualmente parece detenido aunque el motor del juego siga corriendo en segundo plano.

Un error común que puede aparecer en consola es algo como detenerMovimiento is not defined. Suele ser un typo en el nombre de la función entre el HTML y el JavaScript. Revisa siempre que coincidan exactamente.

¿Qué patrón de animación acabas de implementar?

Lo que construiste sigue un patrón clásico de los videojuegos: separar estado (velocidad y posición) de renderizado (dibujar al personaje en pantalla). Los botones modifican el estado, y un game loop basado en setInterval se encarga de leer ese estado y reflejarlo visualmente cada 50 milisegundos.

Esta arquitectura escala bien. Cuando quieras agregar gravedad, colisiones o aceleración, solo modificas las propiedades del personaje sin tocar la lógica de dibujo. El siguiente paso natural es reemplazar los botones del mouse por eventos de teclado, para que tu juego se sienta como un juego de verdad.

¿Ya probaste cambiar el valor de setInterval a 16 milisegundos para alcanzar 60 FPS? Cuéntame cómo se ve tu Capipepo a esa velocidad.