PDA

Volledige versie bekijken : variabelen doorgeven via addEventListener


Sjeiti
%Europe/Berlin %933 %2007, 23:24
Ik loop nu al een aantal keer tegen het volgende probleem aan.

Ik heb een x aantal sprites die allemaal op onclick dezelfde functie moeten aanroepen maar elk een andere variabele moeten doorgeven.

vroeger in as2 deed ik zoiets met:sprite1.onClick = Relegate.create(instance,functie,var1,var2);Waarbi j Relegate een extend op Delegate was zodat je variabelen mee kon geven.

Nu werkt het dus zo:
sprite1.addEventListener("click", instanceofstatic.functie );ofsprite1.addEventListener("click", function(e:Event):void{ instanceofstatic.functie(23) } );

maar dit werkt natuurlijk niet:for (var i:int=0;i<23;i++) {
var mSprite:Sprite = new Sprite();
mSprite.addEventListener("click", function(e:Event):void{ instanceofstatic.functie(i) } );
}

Heeft iemand een oplossing? (Sprite extenden en met e.currentTarget.myvar werken is geen optie)

gr..

Ron

TheDutch
%Europe/Berlin %958 %2007, 00:00
Waarom wil je variable meegeven?

Sjeiti
%Europe/Berlin %986 %2007, 00:40
Waarom niet? :-P

Ik ben bezig met de editor voor dit spel (http://sjeiti.com/test/pv3d/cubejunky/). Daarin zit een 3d blokjes menu waarmee je blokjes neer kan zetten. Alle typen blokjes hebben een bepaalde id. In het blokjes menu wil ik dus Hud.addBlock(1) of 2 of 3 doen... afhankelijk van het type.

Verder krijg in de editor je bij het laden van jouw levels een lijst met namen en id's terug. Dat zijn dus een onbekend aantal id's die niet opvolgend kunnen zijn. Hierbij maak ik een zooitje sprites met textfields (naam level) waarbij onclick het level moet laden met het id van dat level.

...en ik zal dit probleem waarschijnlijk nog wel vaker tegenkomen.

TheDutch
%Europe/Berlin %273 %2007, 07:34
Laat eens duidelijk in pseudocode zien wat jij graag wilt bereiken. Dan kunnen wij een eventueel alternatief bedenken.

Sjeiti
%Europe/Berlin %407 %2007, 10:46
nouja... wat ik daarboven als laatste schetste...
dus iets als:var aLevels:Array = result.serverInfo.initialData; // [[1,"asdf"],[3,"qwer"],etc...]
for (var i:int=0;i<aLevels.length;i++) {
var mLabel:TextField= new TextField();
mLabel.iLevelId = aLevels[i][0];
mLabel.iLevelName = aLevels[i][1];
mLabel.text = "aLevels[i][1]";
mLabel.y = i*20;
mLevels.addChild(mLabel);
// dus dit eigenlijk... maar dit kan niet
mLabel.addEventListener("click", loadMyLevel(i) );
// of dit... maar dat werkt niet
mLabel.addEventListener("click", function(e:Event){loadMyLevel(i)} );
}
Op zich zou ik in dit geval natuurlijk TextField kunnen extenden en met Event.currentTarget een variabele eruit vissen. Maar ik heb ergens anders hetzelfde probleem alleen kan ik daar de Sprite (in dat geval) niet extenden omdat de Sprite een return waarde is van een Class waar ik niet aan kan komen.
Ik heb overigens wel een flex voorbeeld kunnen vinden over custom events (http://www.darronschall.com/weblog/archives/000191.cfm) (hoewel ik in flex niet zo thuis ben). Maar volgens mij kan je met dat voorbeeld alleen waarden doorgeven, geen variabelen. Bovendien kan je waarden ook gewoon zo doorgeven: addEventListener("click", function(e:Event){loadMyLevel(234)} );

gr...

Ron

TheDutch
%Europe/Berlin %343 %2007, 09:14
Waarom maak je "mLabel" niet dynamisch aan met scope["mLabel_"+i]? Dan kan je via: event.currentTarget.name.split("_")[1] opvragen welk getal van "i" eraan gekoppeld is.

Dus zoiets:

var aLevels:Array = result.serverInfo.initialData; // [[1,"asdf"],[3,"qwer"],etc...]
for (var i:int=0;i<aLevels.length;i++)
{
var myObject:Object= new Object();

myObject["mLabel_"+i] = new TextField();
myObject["mLabel_"+i].iLevelId = aLevels[i][0];
myObject["mLabel_"+i].iLevelName = aLevels[i][1];
myObject["mLabel_"+i].text = "aLevels[i][1]";
myObject["mLabel_"+i].y = i*20;

mLevels.addChild(myObject["mLabel_"+i]);

myObject["mLabel_"+i].addEventListener("click", loadMyLevel);
}

private function loadMyLevel(event:MouseEvent):void
{
trace(event.currentTarget.name.split("_")[1]);
}

AAD
%Europe/Berlin %344 %2007, 09:16
Misschien kun je zelf een event maken.

Hier staat het beter uitelegd dan ik zou kunnen :)
http://www.darronschall.com/weblog/archives/000191.cfm

TheDutch
%Europe/Berlin %349 %2007, 09:23
Dat gaat niet werken in dit geval AAD (buiten het feit dat het hier niet om Flex gaat) :).

Bij MXML tags is de addEventListener al gedaan door Flex (zie code Darron) en wordt de action die je opgeeft bij bijvoorbeeld het attribute "click" uitgevoerd door de functie die is opgegeven bij de addEventListener door Flex.

Sjeiti voegt een eigen event listener toe via ActionScript en daar kan alleen een functie referentie aan meegeven worden. Het zou volgensmij alleen kunnen op mijn manier hierboven omschreven of wanneer hij TextField extend en bij de instantiatie ervan de waarde van "i" meegeeft zodat het beschikbaar kan zijn in het "click" event van de subclass van TextField.

Sjeiti
%Europe/Berlin %358 %2007, 09:36
Ik gebruik in sommige gevallen nu idd deze:package flash.display {
import flash.display.Sprite;
public class VarSprite extends Sprite {
public var obj:Object;
public function VarSprite() {
super();
}
}
}...zodat ik zo'n beetje alles kan doorgeven wat ik wil. Maar het is wel een beetje een noodoplossing, niet echt elegant.

AAD
%Europe/Berlin %402 %2007, 10:40
Dat gaat niet werken in dit geval AAD (buiten het feit dat het hier niet om Flex gaat) :).

Bij MXML tags is de addEventListener al gedaan door Flex (zie code Darron) en wordt de action die je opgeeft bij bijvoorbeeld het attribute "click" uitgevoerd door de functie die is opgegeven bij de addEventListener door Flex.

Sjeiti voegt een eigen event listener toe via ActionScript en daar kan alleen een functie referentie aan meegeven worden. Het zou volgensmij alleen kunnen op mijn manier hierboven omschreven of wanneer hij TextField extend en bij de instantiatie ervan de waarde van "i" meegeeft zodat het beschikbaar kan zijn in het "click" event van de subclass van TextField.

Zowel Sprite als alle flex componenten zijn subclasses van EventDispatcher. Anders zou je geen addEventListener aan een sprite kunnen hangen. De click attribute van de MXML tag in Darron's voorbeeld is in principe hetzelfde als de clickHandler die je aan de sprite toevoegd.
In de clickHandler kun je de sprite het customEvent laten dispatchen.
De volgende code zou prima met de IncrementEvent custom event class van Darron moeten werken.



import IncrementEvent;

var sprite1 = new Sprite();
draw(sprite1);
addChild(sprite1);

sprite1.addEventListener("click", spriteClickHanler );
sprite1.addEventListener(IncrementEvent.INCREMENT_ TYPE, spriteIncrementHandler);

function spriteClickHanler(e:Event):void{
sprite1.dispatchEvent(new IncrementEvent(10));
}

function spriteIncrementHandler(ie:IncrementEvent):void{
trace(ie.amount); // traces 10
}

function draw(sprite:Sprite):void {
sprite.graphics.beginFill(0xFFCC00);
sprite.graphics.drawRect(0, 0, 100, 100);
sprite.graphics.endFill();
}

TheDutch
%Europe/Berlin %406 %2007, 10:45
Je begrijpt me verkeerd, ik ligt het vanavond wel even toe :).

AAD
%Europe/Berlin %459 %2007, 12:01
Ja je hebt gelijk. Ik zie dat het idd niet de oplossing voor het probleem in de topic start is.
Al kun je wel variabelen met een event meesturen op deze manier. Ik was gister toevallig met een soortgelijk probleem bezig, daardoor was ik wat te snel met reageren na het zien van de topic titel. Sjeiti had de post zelf ook al gevonden.
Mijn excuus, slecht begin voor een firstpost op dit forum :P

TheDutch
%Europe/Berlin %701 %2007, 17:50
Al kun je wel variabelen met een event meesturen op deze manier.
Dat is de standaard manier (custom events) in AS 3, werkelijk niets speciaals aan. Echter was het november 2005 nog allemaal zo nieuw dat alles speciaal en fantastisch was ;).

Hoe dan ook, fijn om weer een nieuwe enthousiaste Flex programmeur op het forum te hebben. Welkom! :).