miércoles, 9 de diciembre de 2009

ActionScript 3: Solución para problemas con la Clase Tween

Hoy te traigo un jueguito muy simple pero que tiene algunas cosas interesante para analizar como listeners para teclado y mouse, setInterval() y otras yerbas que irán apareciendo en el script.
Desde ActionScript2 vengo utilizando con maravillosos resultados la clase tween para hacer animaciones pequeñas (cambiar alphas, posicion, tamaño, etc).

Por eso, cuando me mudé a ActionScript3 me puse muy contento al saber que todavía existia nuestra clase Tween.

El problema es que, entregado al Tween, de pronto me encontré haciendo algo como esto:

import fl.transitions.*;
import fl.transitions.easing.*;
function hacerAlgo():void{
var mySprite:Sprite;
for (var i:uint = 0; i <>
mySprite = new cuadrado_mc();
stage.addChild(mySprite);
mySprite.x = Math.random() * stage.stageWidth;
mySprite.y = Math.random() * stage.stageHeight;
new Tween(mySprite, 'alpha', None.easeNone, 0, 1, 1, true);
}
}
hacerAlgo();

Mientras éste código lo cargo una vez no hay problemas, pero cuando necesita rehacer el dibujo (digamos si cambio los valores desde un combo box u otra modificación en tiempo de ejecución) ocurre que a veces funciona y a veces no.

Cuando me cansé de buscar y rebuscar donde me había equivocado empecé a buscar respuestas en internet. Resulta que este problemita del tween viene de la mano de un nuevo artilugio de flash (al menos nuevo para mí): El Garbage Collector.

Lo que hace este recolector de basura es borrar las variables que flash carga en la memoria y que estan sin uso. El asunto parece ser que el tween ocupa mucho espacio en memoria y como flash termina el bucle (for) antes de que el tween termine su proceso, se borran las variables temporales y el proceso del tween queda trunco: A veces funciona, a veces funciona a medias y otras directamente no funciona.

Encontré montones de recomendaciones muy complejas. Algunas no las entendí, otras directamente no funcionaban.

La solución definitiva (hasta el momento porque nada es definitivo) la encontré con una Clase externa que se monta en tu proyecto y reemplaza a la clase tween de flash.
Esta galería de clases se llama CGSafe (algo así como seguro contra el garbage collector) y funciona muy parecido a la de flash, pero bien ;). Es gratuita y funciona muy bien.

Además sirve para problemas similarers con: Timers, Loaders y URLLoaders.

Lo que hay que hacer es:
1) Descargarse el paquete de Clases de la pagina del desarrollador. o haciendo click AQUI (es la ruta original del desarrollador).
2) Poner dentro de tu proyecto la carpeta com que contiene todas las clases CGSafe.
3) Importar las clases en actionscript:
donde antes importabas import fl.transitions.*; ahora importas import com.exanimo.transitions.GCSafeTween;.
4) En lugar crear al tween como new Tween(mySprite, 'alpha', None.easeNone, 0, 1, 1, true); ahora lo creas escribiendo new new CSafeTween(mySprite, 'alpha', None.easeNone, 0, 1, 1, true);.
Es prácticamente igual. El código de nuestro ejemplo, modificado, quedaría así:

import com.exanimo.transitions.GCSafeTween;
import fl.transitions.easing.*;
function hacerAlgo():void{
var mySprite:Sprite;
for (var i:uint = 0; i <>
mySprite = new cuadrado_mc();
stage.addChild(mySprite);
mySprite.x = Math.random() * stage.stageWidth;
mySprite.y = Math.random() * stage.stageHeight;
new CSafeTween(mySprite, 'alpha', None.easeNone, 0, 1, 1, true);
}
}
hacerAlgo();

5) Disfrutas viendo tus animaciones sin cortes abruptos ni errores incomprensibles.

Nota: Hay un monton de Clases por ahí que hacen lo mismo. Yo elegí la GCSafe porque es la más similar a la de Adobe y porque funciona muy bien.

Nota 2: Si esta información te sirvió por favor hacé click en los enlaces patrocinados para ayudarme a mantener este blog en línea.