CodeForge

Maquetación Web Dinámica / Canvas y videojuegos 2D

Sprites y spritesheets: animar personajes

Teoría22 min20 XP

Los personajes de un juego no son formas dibujadas a mano en cada fotograma: son imágenes, y su animación (caminar, saltar, atacar) es una tira de dibujos que se pasan rápido — como un folioscopio. Esta lección te enseña el drawImage completo para recortar esas tiras, y el patrón para animarlas cuadro a cuadro.

El folioscopio y la tira de dibujos

drawImage con recorte: los 9 argumentos

Ya usaste drawImage(img, x, y) para pegar una imagen entera. La versión poderosa toma 9 argumentos y recorta una REGIÓN de la fuente:

drawimage.js
ctx.drawImage(
hoja,                    // la imagen fuente (el spritesheet)
sx, sy, sw, sh,          // RECORTE en la fuente: origen x,y + ancho,alto
dx, dy, dw, dh           // DESTINO en el canvas: dónde y de qué tamaño
);
// "toma el rectángulo (sx,sy,sw,sh) de la hoja y píntalo en (dx,dy) del canvas"

La clave está en sx: si cada cuadro mide 56px de ancho, el cuadro número n empieza en sx = n * 56. Cambiando ese multiplicador avanzas por la tira. Y como dw/dh pueden diferir del recorte, escalas el sprite de paso (pixel art se ve genial ampliado).

animar-sprite.js
const ANCHO = 56, CUADROS = 4;
let cuadro = 0, tick = 0;

function update() {
tick++;
if (tick % 8 === 0) cuadro = (cuadro + 1) % CUADROS;   // avanza cada 8 fotogramas
}
function draw() {
const sx = cuadro * ANCHO;                              // recorte del cuadro actual
ctx.drawImage(hoja, sx, 0, ANCHO, 56, x, y, ANCHO, 56);
}

El tick % 8 es el control de velocidad de la animación: a 60fps, cambiar de cuadro cada 8 fotogramas da ~7 cuadros/segundo, el ritmo de un caminado. Sube el número para animar más lento, bájalo para más rápido — independiente de la velocidad a la que el personaje se DESPLAZA.

Un personaje caminando

Truco del ejemplo (nota honesta de tramoya): construí el spritesheet dibujándolo en un canvas oculto, para que el demo no dependa de descargar un PNG. En un juego real, hoja sería const hoja = new Image(); hoja.src = "player.png" y dibujarías dentro de su onload. Pero el mecanismo que importa — drawImage recortando el cuadro cuadro * FW y avanzándolo con el tiempo — es EXACTAMENTE el mismo con una imagen de verdad.

Tu personaje camina, pero la animación va demasiado rápida (patalea frenético) aunque se desplaza a una velocidad normal por la pantalla. ¿Qué ajustas?

Mini-reto

Dale a tu personaje DOS animaciones: además del caminado, un estado "quieto" (idle) que use solo el cuadro 0 cuando no se mueve. La lógica: si hay input de movimiento, avanza los cuadros; si no, fija cuadro = 0. Es la base de las máquinas de estados de animación de todo juego — caminar, saltar, atacar — donde el estado del personaje decide qué tira de la hoja reproducir.

Qué sigue

Tu personaje se mueve y se anima, pero atraviesa todo como un fantasma. La próxima lección le da cuerpo físico: DETECCIÓN DE COLISIONES — saber cuándo dos cosas se tocan. Cajas contra cajas, distancias entre círculos: la matemática (sencilla) detrás de recoger una moneda o chocar con un enemigo.