Autor Zpráva
tapies
Profil
Dobrý den,

měl bych prosím takový dotaz. Vytvořil jsem třídu LoadImagesTexts.as, která provede nahrání obrázků a textů pomocí XML souboru.
V frame skriptu mám volání této třídy a chci, aby frame skript pokračoval až po dokončení "práce" třídy, tedy až budou obrázky a texty nahrány.

Jsem začátečník, napadají mě dvě možnosti :
- ve třídě LoadImagesTexts.as, po dokončení, vyvolat Event, a ve frame skriptu přidat Listener na tuto událost
- ve třídě LoadImagesTexts.as nastavit po dokončení návratovou hodnotu, tu pak ve frame skriptu testovat
Nejspíš existuje lepší řešení, můžete mi prosím poradit?

Děkuji.

frame skript:
var imagesArray:Array = new Array(); var textsArray:Array = new Array();
var myLoader:LoadImagesTexts = new LoadImagesTexts(imagesArray, textsArray);
// zde bych chtěl čekat, dokud nebudou obrázky/texty kompleně nahrány
// zde pracovat s už nataženými obrázky/texty
 
..::DXH::..
Profil *
Toto je nejspis nejschudnejsi reseni: "- ve třídě LoadImagesTexts.as, po dokončení, vyvolat Event, a ve frame skriptu přidat Listener na tuto událost" ale zalezi jak je trida LoadImagesTexts napsana.
tapies
Profil
Děkuji za Vaši odpověď. Dělám to poprvé, mohl byste mi prosím poradit, jak vyvolat vlastní událost ve třídě, a jak ji pak ve frame skriptu zpracovat?
Událost by se vyvolala úplně na konci třídy tam, kde je teď trace ("HOTOVO");


takto třída vypadá (pro zjednodušení jsem vyhodil část, která natahuje texty):
public class LoadImagesTexts {
	var imagesArray:Array = new Array();
	var textsArray:Array = new Array();
	var xmlRequest:URLRequest = new URLRequest("myXML.xml");
	var xmlLoader:URLLoader = new URLLoader(xmlRequest);
	var xmlData:XML;
	var xmlImageNum:uint;   //počet obrázků, které se mají načíst
	var imageLoader:Loader;
	var imgNum:uint = 0;	//počet načtených obrázků
	
	public function LoadImagesTexts(imagesArray, textsArray):void{
		this.imagesArray = imagesArray;
		this.textsArray = textsArray;
		xmlLoader.addEventListener(Event.COMPLETE, xmlLoaded);
	}
	
	function xmlLoaded(event:Event):void {
		xmlData = new XML(event.target.data);     
		xmlImageNum = xmlData.*.length();             
		loadImage();
	} 
	
	function loadImage():void{
		imageLoader = new Loader;
		imagesArray.push(imageLoader);
		imageLoader.load(new URLRequest(xmlData.image[imgNum].imgURL));     
		imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,imageLoaded);
	}
	
	function imageLoaded(event:Event):void{
		imageLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE,imageLoaded);
		imgNum++; 
		
		if (imgNum < xmlImageNum) {         
			loadImage(); 
		}
		else {		
			trace ("HOTOVO"); 
		}
	}
}
embee
Profil
Ja takoveto veci resim pomoci anonymni funkce... v tride definuji promennou typu funkce:

public var lodedFct:Function;

v konstruktoru ji priradim prazdnou hodnotu (aby nedoslo k erroru):

this.loadedFct = function():void {}

a ve tride nadefinuji jeji spusteni:

function imageLoaded(event:Event):void{
imageLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE,imageLoaded);
imgNum++;

if (imgNum < xmlImageNum) {
loadImage();
}
else {
this.loadedFct();
}
}


taktovato funkce se da pak definovat odkukoli. V tomto pripade tedy:

var myLoader:LoadImagesTexts = new LoadImagesTexts(imagesArray, textsArray);
this.myLoader.loadedFct = function():void {
//telo funcke
}

Jen je potreba mit na pameti, ze pokud ma tato anonymni funkce volat nejakou funkci na hlavni casove ose, tak:

- musi ta instance tridy s anonymni funkci byt bud zanesena do dispalyObjectListu (addChild) a pak cesta k funkci na hlavni TL je napr. this.parent.parent.funkceNaHlavniTL(); (zelazi na tom, kde je instance tridy vnorena)

- nebo se musi tride do konstruktoru predat odkaz na hlanvi casovou osu, aby se pres tuto referenci pak mohla funkce na hlavni casove ose zavolat.

Mozna se to volani da vyresit i jinak, ale nevim jak :)

jinak jeste poznamka - jestli to dobre chapu, pouzivas synchronni nacitani (nacitas obrazky po jednom). Z toho, co jsem cetl, je udajne lepsi pouzivat nacitani asynchronni, tzn. zadat prikaz k nacteni vsech obrazku najednou. Melo by to byt rychlejsi, ale osobne jsem to nestestoval, jen jsem to cetl.
..::DXH::..
Profil *
Tam kde je trace("HOTOVO"); staci volat dalsi funkci ktera je na hlavni casove ose (frame script). A nebo vytvorit vlastni udalost takto (tak to delam ja):
package {
	
	public class LoadImagesTexts {
		
		public const HOTOVO:String = "hotovo";
	
	
		var imagesArray:Array = new Array();
		var textsArray:Array = new Array();
		var xmlRequest:URLRequest = new URLRequest("myXML.xml");
		var xmlLoader:URLLoader = new URLLoader(xmlRequest);
		var xmlData:XML;
		var xmlImageNum:uint;   //počet obrázků, které se mají načíst
		var imageLoader:Loader;
		var imgNum:uint = 0;	//počet načtených obrázků
	
		public function LoadImagesTexts(imagesArray, textsArray):void{
			this.imagesArray = imagesArray;
			this.textsArray = textsArray;
			xmlLoader.addEventListener(Event.COMPLETE, xmlLoaded);
		}
	
		function xmlLoaded(event:Event):void {
			xmlData = new XML(event.target.data);     
			xmlImageNum = xmlData.*.length();             
			loadImage();
		} 
	
		function loadImage():void{
			imageLoader = new Loader;
			imagesArray.push(imageLoader);
			imageLoader.load(new URLRequest(xmlData.image[imgNum].imgURL));     
			imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,imageLoaded);
		}
	
		function imageLoaded(event:Event):void{
			imageLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE,imageLoaded);
			imgNum++; 
			
			if (imgNum < xmlImageNum) {         
				loadImage(); 
			}
			else {		
				trace ("HOTOVO");
				dispatchEvent(new Event(HOTOVO));
			}
		}
	}

}



Po skonceni trida odesle do toku udalodti pomoci metody dispatchEvent() udalost s konstantou "hotovo", kterou zachyti listener, v hlavni casove ose (frame scriptu).

function mojeFunkce(e:Event):void {
   //...
}
myLoader.addEventListener("hotovo", mojeFunkce);


http://www.flash.cz/portal/clanek.aspx?id=1420
tapies
Profil
Čisté, perfektní řešení, díky moc!

(jen jsem musel použít extends: public class LoadImagesTexts extends EventDispatcher )

_____________________________________________________________________________
Ještě jeden dotaz, prosím.

Uvádíte:
function mojeFunkce(e:Event):void {
   //...
}
myLoader.addEventListener("hotovo", mojeFunkce);


zdá mi logičtější toto pořadí:
myLoader.addEventListener("hotovo", mojeFunkce);
function mojeFunkce(e:Event):void {
   //...
}


Všiml jsem si toho "obráceného" pořadí již několikrát. Má to nějaký vliv na provádění kódu?

Děkuji.
..::DXH::..
Profil *
Vliv to nema. Ale mela by se nejprve deklarovat funkce a potom listener. Protoze listener vola funkci a pokud by funkce nebyla deklarovana drive a listener by ji zavolal tak by se nic nestalo a to je chyba. Ale nejspis si Flash pri kompilaci udela vlastni poradek ve scriptu takze se to nemusi resit.
tapies
Profil
Děkuji.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0