Zurück   Flashforum > Flash > ActionScript > ActionScript 3

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 27-10-2009, 13:34   #1 (permalink)
Neuer User
 
Registriert seit: Jul 2009
Beiträge: 22
Variable aus Schleife in EventListener übergeben

Hallo Leute,

ich häng mal wieder und AS3 bringt mich langsam zur Verzweiflung.

dataHolder ist ein Array, der bestimmte Daten vorhält:
Array( Array(posx, posy, url), ... Array( ... ) );

PHP-Code:
function loadItems():void {

    for(var 
i:int 0dataHolder.lengthi++)
    {
        var 
ld:Loader = new Loader();
        var 
urlr:URLRequest = new URLRequest();
        
urlr.url dataHolder[i][2];
        
ld.contentLoaderInfo.addEventListener(Event.COMPLETE, function() {
            var 
sp:Sprite = new Sprite();
            
sp.int(dataHolder[i][0]);
            
sp.int(dataHolder[i][1]);
            
sp.addChild(ld);
            
addChild(sp);
        });
        
ld.load(urlr);    
        
    }


Ich müsste das aktuelle i in den EventListener bringen, damit es die richtige Zeile aus dataHolder anzeigt. Da das Laden aber ja einige Zeit dauert entspricht i ja immer dataHolder.length (weil die Schleife ja schon komplett durchgelaufen ist, wenn der EventListener ausgeführt ist.

Ich bräuchte also sowas:
PHP-Code:
[...]
ld.contentLoaderInfo.addEventListener(Event.COMPLETEevtComplete(i));

function 
evtComplete(dataHolderLine:int)
{
    var 
sp:Sprite = new Sprite();
    
sp.int(dataHolder[dataHolderLine][0]);
    
sp.int(dataHolder[dataHolderLine][1]);
    
sp.addChild(ld);
    
addChild(sp);
}
[...] 
Da man in den EventListener keine Parameter übergeben kann, bin ich momentan ratlos.

Kann mir jemand helfen?

Danke und viele Grüße,
Jay
Jay84 ist offline   Mit Zitat antworten
Alt 27-10-2009, 14:23   #2 (permalink)
Certified dump
 
Registriert seit: Aug 2001
Beiträge: 969
Doch, kann man - ist nur nicht so einfach wie oben
durch einfaches Anhängen versucht.

Mal so googlen, dann kommen viele hinweise dazu:
AS3 Custom Event for Passing Parameters

Man kann aber auch in "sp" ne Variable platzieren, kann man
sehr einfach drauf zugreigen, z.B.:

function evtComplete(e:Event)
{
trace(e.currentTarget.parent.parent.variable);
rudi66 ist offline   Mit Zitat antworten
Alt 27-10-2009, 14:26   #3 (permalink)
Neuer User
 
Registriert seit: Sep 2009
Ort: Freiburg
Beiträge: 18
Hallo,

Im contentLoaderInfo-Objekt steht dir auch die URL des soeben geladenen Objekts zur Verfügung. Die hast du ja auch in deinem Array stehen und kannst darüber die x- und y-Position erfragen.

Hier mal der ungetestete Code, wie ich es versuchen würde:

Code:
function loadItems():void { 

    for(var i:int = 0; i < dataHolder.length; i++) 
    { 
        var ld:Loader = new Loader(); 
        var urlr:URLRequest = new URLRequest(); 
        urlr.url = dataHolder[i][2]; 
        ld.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete); 
        ld.load(urlr);       
    } 
}  


function onComplete (evt:Event):void
{
        var tempURL:String = evt.target.url;
        
        for (var i:int = 0; i < dataHolder.length; i++)
        {
            if (dataHolder[i][3] == tempURL)
            {
                var sp:Sprite = new Sprite(); 
                sp.x = int(dataHolder[i][0]); 
                sp.y = int(dataHolder[i][1]); 
                sp.addChild(ld); 
                addChild(sp); 
                i = dataHolder.length; 
            }
         }
}
Liebe Grüße
Christine
XaRen ist offline   Mit Zitat antworten
Alt 27-10-2009, 14:34   #4 (permalink)
Neuer User
 
Registriert seit: Jul 2009
Beiträge: 22
ich google schon seit 2 stunden und hab auch hier im forum einiges gefunden.
custom event, delegates... aber ich bin noch am anfang und versteh das nicht. muss aber dringend was für nen kunden fertig machen, hab also auch keine zeit mich da jetzt reinzufuchsen. hab ich aber vor ;-)

daher hab ich hier auf eine lösung gehofft.

das problem beim speichern in einer variablen ist, folgendes:
ich lade mit einer schleife 100 bilder (gleichzeitig, nicht hintereinander).
jeder loader bekommt einen eventlistener, der gefeuert wird, wenn das bild fertig geladen ist.
in einem array in einem array sind bestimmte informationen zum bild gespeichert:
[0] => Array(100, 50, "images/bild1.png", "Deutschland");
[1] => Array(200, 50, "images/bild2.png", "Österreich");
[2] => Array(120, 30, "images/bild3.png", "Frankreich");
usw.

Der Eventlistener muss jetzt die Bilder entsprechend Positionieren und mit Titeln versehen. Dazu muss er wissen, auf welchen Index im Array er zugreifen muss.

Daher muss ich jedem Eventlistener eine Zahl übergeben, damit der weiß, was er tun muss.

vereinfacht als code
PHP-Code:
for(var i:int 0100i++)
{
    
// bild laden
    
...addEventListener(Event.COMPLETEBildEinrichten(i));
}

function(
bildnummer:int):void
{
    
// ich weiß welche bildnummer ich bearbeiten muss

Jay84 ist offline   Mit Zitat antworten
Alt 27-10-2009, 14:37   #5 (permalink)
Neuer User
 
Registriert seit: Jul 2009
Beiträge: 22
hallo christine,

du hast geschrieben, während ich rudi geantwortet habe.

danke für deine hilfe! ja, so könnte man es machen. das hilft mir fürs erste.
EDIT: ld ist in der funktion undefiniert. jetzt weiß ich nicht wie ich das bild dem sprit hinzufüge. as3 ist doch echt zum ...

aber ich bin da schon öfter gehangen und ich hab nicht immer einen dataHolder der einen string enthält, das der Event vorhält.
ich bin also auch an einer allgemeinen lösung interessiert.



schreibt man denn bei custom events für jeden event den man braucht eine eigene klasse? (tween event, timer event, loader complete event)? ist das nicht irgendwann total unübersichtlich?!

Geändert von Jay84 (27-10-2009 um 14:47 Uhr)
Jay84 ist offline   Mit Zitat antworten
Alt 27-10-2009, 14:52   #6 (permalink)
Neuer User
 
Registriert seit: Sep 2009
Ort: Freiburg
Beiträge: 18
Hallo Jay,

wenn du den Loader vor der loadItems Funktion deklarierst, kannst du auch in der anderen Funktion drauf zugreifen. Würd dann auch gleich den URL-Loader außerhalb deklarieren.

Code:
var ld:Loader = new Loader(); 
var urlr:URLRequest = new URLRequest(); 

function loadItems():void { 

    for(var i:int = 0; i < dataHolder.length; i++) 
    { 
        urlr.url = dataHolder[i][2]; 
        ld.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete); 
        ld.load(urlr);       
    } 
}
Liebe Grüße
Christine

Geändert von XaRen (27-10-2009 um 14:54 Uhr)
XaRen ist offline   Mit Zitat antworten
Alt 27-10-2009, 15:10   #7 (permalink)
Neuer User
 
Registriert seit: Nov 2005
Beiträge: 548
Klassen kann man machen, lohnt sich in meinen Augen aber nicht wenn es nur um eine weitere Eigenschaft wie eine ID geht.

Die Lösung von Christine ist ein Weg, eleganter wäre noch, die URL nicht in einer Schleife zu suchen, sondern als Schlüssel in einem Objekt zu haben, dann kann man direkt darauf zugreifen.

Und da wären wir auch schon bei einer allgemeinen Lösung, die ich recht praktisch finde: wenn man keine eindeutige Eigenschaft im Listener-Objekt hat wie z.B. .url oder .name, dann nimmt man einfach das Objekt selbst als Schlüssel (Dictionary) und speichert darin alles Zusätzliche, was man später im EventHandler benötigt, z.B. auch eine eindeutige id.

Hier ein Beispiel mit mehreren Buttons, die alle denselben EventHandler benutzen und darin eindeutig zugewiesene Eigenschaften abfragen müssen, die das eigentliche Listener-Objekt nicht enthält. Ist im Prinzip dasselbe Problem.

ActionScript:
  1. var buttons=new Dictionary();
  2.  
  3.  
  4. //Buttons erstellen
  5. for(var i=0;i<5;i++){
  6.    
  7.     //nur die Eigenschaften des listenerObject stehen später im EventHandler direkt zur Verfügung:
  8.     var listenerObject=new Sprite();
  9.     listenerObject.graphics.beginFill(0xCCCCCC);
  10.     listenerObject.graphics.drawCircle(0,0,20);
  11.     listenerObject.x=30;
  12.     listenerObject.y=i*50+30;
  13.     listenerObject.addEventListener(MouseEvent.MOUSE_DOWN,mdown);
  14.     this.addChild(listenerObject);
  15.  
  16.     //Das listenerObject wird im Dictionary registriert, zusätzliche Eigenschaften können angehängt werden:
  17.     buttons[listenerObject]=new Object();
  18.     buttons[listenerObject].id=i;
  19.     buttons[listenerObject].specialname="button"+i;
  20.     }
  21.    
  22.  
  23. //ein Listener für alle Buttons
  24. function mdown(event:MouseEvent){
  25.    
  26.     //Eine Eigenschaft des ListenerObjects auslesen
  27.     trace("y-Position: "+event.target.y);
  28.    
  29.     //Zusätzliche Eigenschaften aus dem Dictionary auslesen
  30.     trace("id: "+buttons[event.target].id);
  31.     trace("specialname: "+buttons[event.target].specialname);
  32.     trace();
  33.     }
joeydee ist offline   Mit Zitat antworten
Alt 27-10-2009, 15:34   #8 (permalink)
Neuer User
 
Registriert seit: Nov 2005
Beiträge: 548
Zitat:
Zitat von Jay84 Beitrag anzeigen

Ich bräuchte also sowas:
PHP-Code:
[...]
ld.contentLoaderInfo.addEventListener(Event.COMPLETEevtComplete(i));

function 
evtComplete(dataHolderLine:int)
{
    var 
sp:Sprite = new Sprite();
    
sp.int(dataHolder[dataHolderLine][0]);
    
sp.int(dataHolder[dataHolderLine][1]);
    
sp.addChild(ld);
    
addChild(sp);
}
[...] 
Sähe dann konkretisiert so aus (ungetestet):

ActionScript:
  1. var ids=new Dictionary();
  2.  
  3. ids[ld]=i;
  4. ld.contentLoaderInfo.addEventListener(Event.COMPLETE, evtComplete);
  5.  
  6. function evtComplete(event:Event)
  7. {
  8.     var dataHolderLine:int =ids[event.target];
  9.     var sp:Sprite = new Sprite();
  10.     sp.x = int(dataHolder[dataHolderLine][0]);
  11.     sp.y = int(dataHolder[dataHolderLine][1]);
  12.     sp.addChild(ld);
  13.     addChild(sp);
  14. }

Geändert von joeydee (27-10-2009 um 15:36 Uhr)
joeydee ist offline   Mit Zitat antworten
Alt 27-10-2009, 15:52   #9 (permalink)
Neuer User
 
Registriert seit: Jul 2009
Beiträge: 22
das mit dem dictionary klingt ganz gut. das probier ich mal. danke

Geändert von Jay84 (27-10-2009 um 16:14 Uhr)
Jay84 ist offline   Mit Zitat antworten
Alt 27-10-2009, 16:14   #10 (permalink)
Neuer User
 
Registriert seit: Jul 2009
Beiträge: 22
hm, habs getestet...
PHP-Code:
var ids = new Dictionary();

function 
loadItems():void {

    for(var 
i:int 0dataHolder.lengthi++)
    {
        
trace("loadItems() " i);
        var 
ld:Loader = new Loader();
        var 
urlr:URLRequest = new URLRequest();
        
ids[ld] = i;
        
urlr.url dataHolder[i][2];
        
ld.contentLoaderInfo.addEventListener(Event.COMPLETEinitAndShowItem);
        
ld.load(urlr);    
    }

}

function 
initAndShowItem(e:Event):void {
    
    var 
dataHolderLine:int ids[e.target];
    
trace("initAndShowItem() " dataHolderLine);


die ausgabe gibt
loadItems() 0
loadItems() 1
initAndShowItem() 0
initAndShowItem() 0
zurück.
(dataHolder enthält momentan für den Test 2 Einträge).

... warum? :-(



muss ich für 100 bilder die gleichzeitig geladen werden nicht vielleicht 100 loader-objekte instanziieren?

---
christines idee hab ich getestet, aber die url im loader ist anders gespeichert (absolut) als im dataHolder. das müsste man parsen und das wäre doch ziemlich umständlich :-/

Geändert von Jay84 (27-10-2009 um 16:18 Uhr)
Jay84 ist offline   Mit Zitat antworten
Alt 27-10-2009, 19:03   #11 (permalink)
Neuer User
 
Registriert seit: Sep 2009
Ort: Freiburg
Beiträge: 18
Dictionary kannte ich als Klasse in Flash noch gar nicht. Wieder was gelernt

Jay, ich hab mir deinen Code mal getestet. Dabei ist mir aufgefallen, dass du mit

Code:
  ids[ld] = i;
dem Dictionary ein Loader-Objekt zuweist. In deiner zweiten Zuweisung verwendest zu zum Suchen allerdings ein contentLoaderInfo-Objekt:

Code:
 var dataHolderLine:int = ids[e.target];
Wenn du in der Funktion loadItems statt dem Loader auch das contentLoaderInfo-Objekt zuweist, bekommst du die richtigen Indexe für das DataHolder Array:

Code:
ids[ld.contentLoaderInfo] = i;
Hoffe, damit kommst du weiter

Liebe Grüße
Christine
XaRen ist offline   Mit Zitat antworten
Alt 28-10-2009, 08:17   #12 (permalink)
Neuer User
 
Registriert seit: Nov 2005
Beiträge: 548
Ja, da hab ich nicht aufgepasst, danke :-)
Es muss natürlich genau das Objekt als Schlüssel verwendet werden, dem der Listener zugewiesen wird und welches somit auch als target im Eventhandler ankommt.
joeydee ist offline   Mit Zitat antworten
Alt 29-10-2009, 13:05   #13 (permalink)
Neuer User
 
Registriert seit: Jul 2009
Beiträge: 22
also das mit dem dictionary hat mich gerettet danke ;-)

jetzt wo das projekt erst mal durch ist, kann ich mich mal mit klassen beschäftigen
Jay84 ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
for-Schleife, um EventListener zuzuordnen benicio ActionScript 3 3 26-04-2009 23:50
Variable aus Schleife an MC außerhalb übergeben ? thbrueck ActionScript 2 14 14-04-2009 13:07
[Flash CS4] i-Variable aus der for-Schleife übergeben... lukasdiehl Flash Einsteiger 1 21-03-2009 17:56
Parameter an eventListener-Funktion übergeben pauledde Flash CS3 Professional 8 18-05-2008 06:06
variable aus php-schleife an flash übergeben?? altes-kind PHP und MySQL 9 28-10-2003 14:33


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:39 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2012 Marc Thiele