Jugable
Apuntarme
Fundamentos

Spritesheets y atlas de texturas: por qué no cargas 200 PNGs

Qué es un draw call, por qué juntar tus sprites en una sola textura multiplica el rendimiento, y cómo montar animaciones en Phaser.

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:

  1. Genera el atlas con padding / extrude de 2 px entre frames.
  2. 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.