Carga secuencial de contenido desde XML hacia clase externa AS3/Flash CS4
Wenas a tod@s.
Me estoy volviendo loco con esta historía a ver si algun alma caritativa me puediera echar un cable.
El tema es que he creado una clase externa en la que cargo desde un XML una serie de fotos. En este XML uso el tag project como referencia. Mi "problema" es que quiero que dicha información sea cargada secuencialmente (una detras de otra, con un orden) para así, una vez cargada cada una de esas fotos, poder manipular su alpha y hacer un fade-in de cada foto segun se vayan cargando.
Os dejo el código que llevo hasta ahora.
Para la clase:
package tsk.utils{
import com.greensock.*;
import com.greensock.easing.*;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.ProgressEvent;
import flash.filters.GlowFilter;
import flash.net.URLLoader;
import flash.net.URLRequest;
import fl.transitions.*;
import fl.transitions.easing.*;
public class projectObject extends Sprite
{
private var tb:MovieClip;
private var vis:MovieClip;
private var i:Number;
private var num:Number;
private var ldr:Loader;
private var foto; Loader;
private var req:URLRequest;
private var uldr:URLLoader;
private var xml:XML;
private static const url:String = "xml/data.xml";
private var per:Number;
public function projectObject():void
{
req = new URLRequest(url);
uldr = new URLLoader(req);
uldr.addEventListener(Event.COMPLETE, alCompletar);
}
private function alCompletar(e:Event):void
{
xml = new XML(e.currentTarget.data);
for (i = 0; i < xml.project.length(); i++)
{
tb = new MovieClip();
addChild(tb);
CargarThumbs();
Sobre(tb);
}
}
private function CargarThumbs():void
{
ldr = new Loader();
ldr.load(new URLRequest(xml.project[i].@preview));
ldr.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, whileLoad);
ldr.x = 562*i;
tb.addChild(ldr);
Click(i);
}
private function Click(n:Number):void
{
function alClick(e:MouseEvent):void
{
trace("alguien me clickeo");
}
ldr.addEventListener(MouseEvent.CLICK, alClick);
}
private function Sobre(tb:MovieClip):void
{
tb.buttonMode = true;
function over(e:MouseEvent):void
{
TransitionManager.start(tb, {type: Photo, direction: Transition.IN, duration: 1, easing: Strong.easeOut } );
}
tb.addEventListener(MouseEvent.MOUSE_OVER, over);
}
private function whileLoad(e:ProgressEvent):void
{
per=Math.round(e.bytesLoaded*100/e.bytesTotal);
trace(per);
atLoad();
}
private function atLoad()
{
this.alpha = 0;
TweenMax.to(this, 1, {alpha:1});
}
}
}
Para el fla:
import tsk.utils.projectObject;
var myStage:Stage=this.stage;
myStage.scaleMode=StageScaleMode.NO_SCALE;
myStage.align=StageAlign.TOP_LEFT;
var homePage:projectObject = new projectObject();
addChild(homePage);
En este punto no consigo que, a pesar de secuenciar la carga de las imagenes mediante el loop de "alCompletar" la carga se realice de forma ordenada y como resultado me encuentro que mis MovieClips al añadirese a la DisplayList actuen de manera extraña cuando simulo la descargar y que el fecto sea visible sobre el contenedor de todas las fotos cuando exporto localmente. He tratado de reubicar la funcion "atLoad" en distintos momentos de la carga pero no obtengo los resultados que quiero.
Es esto un comportamiento por defecto de Flash?, el cargar indiscriminadamente toda la información que se le pide?. Imagino que tendre el mismo problema a la hora de visualizar el porcentage de carga para cada una de las fotos...Que estoy haciendo mal?.
Cualquier ayuda es bien recibida.
Saludos.
tsk.
Ochionet
Hola, no me lo he mirado del todo, de entrada no estas pasando el parametro i al método CargarThumbs(), independientemente de esto tienes que tener en cuenta que el for lo hace en un fracción de segundo, por lo que aunque quieras que siga un orden la carga, se disparan todas casi a la vez, en cuanto una imagen pese mas que otra, ya estará descompensado el efecto que quieres hacer.
Para que las cargas sean una detrás de otra, no debes de cargar la siguiente imagen hasta que no este cargada la anterior. Puedes controlar facilmente cuando una carga ha acabado con un Listener, en ese caso incrementas en 1 un contador que debe de estar inicializado a 0 al principio de la aplicación, validas que no sea mayor que la cantidad de imágenes a cargar, para que no se pierda en caso de que sea la última imagen la que acabas de cargar y entonces llamas a la siguiente carga si la condición del contador te lo permite. El contador debe debe de ser accesible en toda la clase, no dentro de un método.
Digamos que contador = 0,
CargarThumbs() que siempre hace lo mismo, dado que contador cambia en el evento de fin de carga.
Fin de Carga >>> incrementas contador
Validas que contador no sea mayor que la cantidad de imágenes a cargar
CargarThumbs()
....
....
CargarThumbs()
......
....
Saludos,
RobertoAbril
Gracias por la respuesta Ochionet. Disculpa la tardanza, estube dandole vueltas al código antes de lanzarme a contestar.
Entiendo lo que quieres decirme. Lo que no tengo claro es donde ubicar mi listener COMPLETE. Yo lo que uso como "contador" es la propiedad length del tag project de mi XML quien indica cuantas imagenes hay que mostrar de tal forma que si en mi xml dispongo de 6 tags con nombre project el propio loop parará cuando ya no haya más que cargar. En realidad acaba siendo la variable i del loop. Al menos esa es mi idea. No sé si es factible esta forma de trabajar ya que, como comento, no conseguí que mi función COMPLETE controlara el momento en el que se acababa una carga para empezar otra por eso me decante por directamente llamar a la función atLoad() si pasar ningun parametro ya que no le vi la utilidad a utilizar el evento COMPLETE, algo no muy logico si quieres saber cuando algo acaba de cargar pero es que ya no pienso con claridad.
He trabajado un poco más en la clase pero es que ahora al parecer no consigo ni llegar a la función COMPLETE ya que no veo mi trace "acabé de cargar". Lo lógico sería poner el listener COMPLETE dentro de la funcion PROGRESS para que una vez acabado el porcentage de cargar me llevara a la funcion encargada de manegar el contenido de esa carga no?. El codigo funciona pero a su bola como antes. Esto es lo que tengo:
package tsk.utils{
import caurina.transitions.*;
import com.greensock.*;
import com.greensock.easing.*;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.ProgressEvent;
import flash.filters.GlowFilter;
import flash.net.URLLoader;
import flash.net.URLRequest;
import fl.transitions.*;
import fl.transitions.easing.*;
public class projectObject extends Sprite {
private var tb:MovieClip;
private var i:Number;
private var ldr:Loader;
private var req:URLRequest;
private var uldr:URLLoader;
private var xml:XML;
private static const url:String="xml/data.xml";
private var per:Number;
public function projectObject():void {
req=new URLRequest(url);
uldr=new URLLoader(req);
uldr.addEventListener(Event.COMPLETE, alCompletar);
}
private function alCompletar(e:Event):void {
xml=new XML(e.currentTarget.data);
trace("el total de imaganes es..."+ xml.project.length());
for (i = 0; i < xml.project.length(); i++) {
tb = new MovieClip();
CargarThumbs();
Sobre(tb);
}
}
private function CargarThumbs():void {
trace("sigo contando");
trace("voy por la imagen "+i);
ldr = new Loader();
ldr.load(new URLRequest(xml.project[i].@preview));
ldr.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, whileLoad);
ldr.x=562*i;
tb.addChild(ldr);
Click(i);
}
private function Click(n:Number):void {
function alClick(e:MouseEvent):void {
trace("alguien me clickeo");
}
ldr.addEventListener(MouseEvent.CLICK, alClick);
}
private function Sobre(tb:MovieClip):void {
tb.buttonMode=true;
function over(e:MouseEvent):void {
TransitionManager.start(tb, {type: Photo, direction: Transition.IN, duration: 1, easing: Strong.easeOut } );
}
tb.addEventListener(MouseEvent.MOUSE_OVER, over);
}
private function whileLoad(e:ProgressEvent):void {
per=Math.round(e.bytesLoaded*100/e.bytesTotal);
trace(per);
ldr.addEventListener(Event.COMPLETE, atLoadThumb);
}
private function atLoadThumb(e:Event):void {
this.alpha=0;
TweenMax.to(this, 1, {alpha:1});
trace("acabé de cargar!");
}
}
}
Entiendo que necesito crear una función que secuencie las cargas al margen de lo que ya tengo, pero llegados a este punto y teniendo en cuenta que no consigo ver el trace de mi función atLoadThumb ya no sé muy bien por donde tirar. Podrías echarme un cable please?.
Gracias de antemano por tu tiempo.
tsk.
RobertoAbril
Perdon, olvidemonos del porque no puedo acceder a la funcion atLoadThumb. Se me olvidó referenciar el evento a contentLoaderInfo y no al propio objeto. -_-
Ochionet
Sigues usando un for, olvidate de él, el for es un bucle que como te comentaba se realiza en una fracción de segundo.
Te comentaba que usaras un contador que al fin y al cabo controlas tu asi y que te permitirá secuenciar la carga.
Saludos,
RobertoAbril
Ok, así lo haré.
Gracias!.