Tu juego tiene 200 sprites y va a 30 fps en un móvil decente. El problema casi nunca es el número de sprites. Es el número de texturas.
Draw calls
La GPU es rapidísima dibujando cosas, y lentísima cambiando de contexto. Cada vez que el renderer tiene que cambiar de textura, corta el lote actual y empieza uno nuevo. Eso es un draw call.
- 200 sprites, 200 PNGs distintos → hasta 200 draw calls
- 200 sprites, 1 atlas → 1 draw call
Mismo resultado en pantalla, dos órdenes de magnitud de diferencia en coste.
Por eso todos los motores empujan hacia el atlas. No es una optimización prematura: es la forma normal de trabajar con sprites.
Spritesheet vs atlas
Un spritesheet es una cuadrícula regular: todos los frames del mismo tamaño.
this.load.spritesheet('heroe', 'heroe.png', {
frameWidth: 32,
frameHeight: 48
})
Simple, pero desperdicia espacio si tus frames tienen tamaños distintos.
Un atlas es irregular: los frames se empaquetan donde quepan y un JSON dice dónde está cada uno.
this.load.atlas('heroe', 'heroe.png', 'heroe.json')
Para personajes con animaciones de tamaños variables, el atlas gana claramente. Para tiles, el spritesheet está bien porque ya son regulares por definición.
Se generan con TexturePacker (de pago, el estándar) o free-tex-packer (gratis, web). Ambos exportan el formato de Phaser directamente.
Animar
Con el atlas cargado, la animación es una lista de frames:
this.anims.create({
key: 'correr',
frames: this.anims.generateFrameNames('heroe', {
prefix: 'correr_',
start: 1,
end: 8,
zeroPad: 2 // correr_01 … correr_08
}),
frameRate: 12,
repeat: -1 // en bucle
})
this.player.play('correr')
frameRate: 12 es un buen punto de partida para pixel art. El cine son 24 y la animación tradicional trabaja "a dos" (12 efectivos). Muy por encima de eso, la animación se vuelve blanda en vez de más fluida.
El detalle que te va a morder
El bleeding. Cuando el renderer escala o filtra tu atlas, puede muestrear un píxel del frame de al lado y ver una línea de color en el borde del sprite.
Dos arreglos, ponlos los dos:
- Genera el atlas con padding / extrude de 2 px entre frames.
- Si es pixel art, desactiva el filtrado suave:
// en la config del juego
render: { pixelArt: true }
pixelArt: true fuerza filtrado NEAREST y desactiva el antialiasing. Sin eso, tu pixel art se ve borroso y no vas a entender por qué.
Sesión 2 del curso presencial de Phaser.