Los MovieClips con filtros se cachean como Bitmaps

Siempre que he podido, he evitado utilizar MovieClips con filtros porque la lógica me decía que cuantas más operaciones se realizan por fotograma más a trompicones va cualquier animación.
Quizás por eso nunca había caído en los pormenores del porqué de esta máxima en el caso de los filtros.

Hoy, por casualidad, releyendo la documentación de Greensock para optimizar las animaciones me he encontrado con esto:

If your animation looks a little jerky, it may be caused by cacheAsBitmap being set to true on your animating object(s). Whenever cacheAsBitmap is true, it only allows the object to render on whole pixel values which can make it look slightly jerky at slow speeds.

Nada nuevo, cacheAsBitmap = true convierte cualquier DisplayObject a Bitmap en tiempo real; los Bitmaps sólo se pueden colocar en píxeles exactos. Eso ya lo sabíamos. Pero después continua:

Important: whenever a DisplayObject has a filter applied to it (blur, glow, drop shadow, etc.), it forces cacheAsBitmap to true and cannot be reset to false unless the filter is removed. That’s a Flash limitation and has nothing to do with the tweening engine.

De esto no me acordaba: Un MovieClip al que se le aplican filtros se cachea automáticamente como Bitmap.

O sea, que esta es la razón principal, si el MovieClip está animado, de que se ralentice: Un MovieCLip cacheado como bitmap, al estar animado fuerza al reproductor a hacer un BitmapData.draw() en cada fotograma, lo cual es especialmente lento cuando los vectores contenidos en el MovieClip son complejos.
Además, como explican desde Greensock, como sólo se puede colocar en píxeles exactos, si se está moviendo, puede hacerloa a trompicones cunado los desplazamientos empiezan a ser cortos.

Escribiendo me doy cuenta de que probablemente esto ya lo haya leído alguna vez en otro lugar, pero nunca viene mal hacer recordatorios sobre cosas tan importantes, aunque a uno le deje una inquietante sensación de déjà vu.

PuzzleBobble game

Este es un ejemplo de lo que se puede llegar a hacer con Sprite Sheets, tanto en as3 como en otros lenguajes. En lugar de utilizar gráficos vectoriales para las animaciones, que al tener filtros y ser relativamente complejos tienen un coste importante en tiempo de proceso, las rasterizamos a una secuencia de fotogramas (bitmaps).
Para utilizar esta técnica no queda otra que programarse uno su propia librería para que resulte algo más cómodo manejar sprite sheets, o utilizar Starling, que a mi personalmente no me gusta (en el momento de desarrollo de este proyecto, además, no estaba muy claro si la plataforma final iba a ser el desktop o movil-tablet y no me quería arriesgar a contar con la presencia de una tarjeta gráfica potente).

Un detalle: el juego se bloquea cuando pierdes 🙁 . Así que tendréis que recargar la página cuando queráis volver a jugar. Esto se debe a que está pensado para integrarse en facebook y cuando pierdes hace varias llamadas a la API de facebook, que no está permitido hacer desde aquí.

[gigya src=»https://dl.dropboxusercontent.com/u/3646945/newbeForever/personal/graniniBobble.swf» width=»700px» height=»700px»]

Como veis el juego va muy suave (55-60 fps) sin necesidad de aceleración gráfica. Aunque no hay app publicada en iOS (Al cliente no le interesaba) yo hice mis propias pruebas y con algunos cambios (fundamentalmente haciendo algunas clases estáticas y prescindiendo de algunos eventos) el juego corre perfectamente en un iPad 1.

A ver cuanto tiempo aguantáis la embestida de la fruta!! 😉