View Full Version : help with push method?
zwemg
10-15-2008, 03:49 AM
Hey all,
Im having some difficulties with a menu Im creating.
Im looping through an xml and creating movieclip instances for its length.
This all works fine and it adds the movieclips to the stage however when I create functions for those buttons I keep getting null reference errors.
If I create for example, MouseEvent functions inside the for loop it works but I want to be able to reference the movieclips outside of the for loop.
Im thinking maybe I need to create an array to hold the movieclips but I dont know how to push movieclip instances into an array??
If anyone can help me out that'd be great :)
var swfBtn:AnimationButton;
var myURLLoader:URLLoader = new URLLoader();
var myURLRequest:URLRequest = new URLRequest("swfData.xml");
myURLLoader.load(myURLRequest);
myURLLoader.addEventListener(Event.COMPLETE, onLoaded);
function onLoaded(e:Event):void {
var xmlData:XML = new XML(myURLLoader.data);
var a:Number = xmlData.swf_name.length();
for (var i:Number = 0; i < a; i++) {
swfBtn = new AnimationButton();
swfBtn.x = i * swfBtn.width;
addChild(swfBtn);
}
}
zwemg
10-15-2008, 04:15 AM
So I tried again by creating an array to hold the swfBtn instances but still no luck. I cannot access the array outside of my onLoaded function....
PLease someone help..
var swfBtn:AnimationButton;
var buttonList:Array = new Array();
var myURLLoader:URLLoader = new URLLoader();
var myURLRequest:URLRequest = new URLRequest("swfData.xml");
myURLLoader.load(myURLRequest);
myURLLoader.addEventListener(Event.COMPLETE, onLoaded);
function onLoaded(e:Event):void {
var xmlData:XML = new XML(myURLLoader.data);
var a:Number = xmlData.swf_name.length();
for (var i:Number = 0; i < a; i++) {
swfBtn = new AnimationButton();
buttonList.push(swfBtn);
swfBtn.x = i * swfBtn.width;
addChild(swfBtn);
}
// functions I create here work for swfBtn instances
}
// functions I create here Dont work for swfBtn instances and I cannot reference the buttonList array values.
jmparsons
10-15-2008, 04:27 AM
for (var i:Number = 0; i < a; i++) {
buttonList.push(new AnimationButton());
buttonList[i].x = i * buttonList[i].width;
addChild(buttonList[i]);
}
zwemg
10-15-2008, 04:45 AM
Thanks jmparsons, not sure what your code is solving but Im still unable to access array items outside of the onLoaded function which is what Im trying to do.
for (var i:Number = 0; i < a; i++) {
buttonList.push(new AnimationButton());
buttonList[i].x = i * buttonList[i].width;
addChild(buttonList[i]);
}
Mazoonist
10-15-2008, 05:11 AM
You've got to consider the order in which your statements are going to be executed. Every statement that you write that's outside of a function is going to be executed BEFORE your xml file is loaded, regardless of whether the statement comes before or after your onLoaded function.
You can access the contents of your array from inside another function, but that function would have to be called AFTER your xml has loaded. I hope the following will help clarify things a bit:
var swfBtn:AnimationButton;
var buttonList:Array = new Array();
var myURLLoader:URLLoader = new URLLoader();
var myURLRequest:URLRequest = new URLRequest("swfData.xml");
myURLLoader.load(myURLRequest);
myURLLoader.addEventListener(Event.COMPLETE, onLoaded);
function onLoaded(e:Event):void {
var xmlData:XML = new XML(myURLLoader.data);
var a:Number = xmlData.swf_name.length();
for (var i:Number = 0; i < a; i++) {
swfBtn = new AnimationButton();
buttonList.push(swfBtn);
swfBtn.x = i * swfBtn.width;
addChild(swfBtn);
//added the following statement:
swfBtn.addEventListener(MouseEvent.CLICK, doSomething);
}
}
//the following function will not cause an error, because
//by the time the button is clicked on, the onLoaded function
//has obviously already run (otherwise there wouldn't even BE
//a button to click on!):
function doSomething(event:MouseEvent):void {
trace(buttonList[0]);
}
//the following statement is going to generate an error
//because it will execute BEFORE the XML has a chance to load:
trace(buttonList[0]);
zwemg
10-15-2008, 05:32 AM
thanks Mazoonist, now that does make sense. I was looking at a heap of for loops and was wondering why programmers always put event listeners inside them. Now I know why :)
One last question, with the altered code below how can I access the individual instances of the buttonList array now from within my functions.
You will see in the code below I have just some effects on the over and up states but it isnt targeting the correct instance in the array.
Could you help me out with this one please.
var swfBtn:AnimationButton;
var buttonList:Array = new Array();
var myURLLoader:URLLoader = new URLLoader();
var myURLRequest:URLRequest = new URLRequest("swfData.xml");
myURLLoader.load(myURLRequest);
myURLLoader.addEventListener(Event.COMPLETE, onLoaded);
function onLoaded(e:Event):void {
var xmlData:XML = new XML(myURLLoader.data);
var a:Number = xmlData.swf_name.length();
for (var i:Number = 0; i < a; i++) {
swfBtn = new AnimationButton();
buttonList.push(swfBtn);
swfBtn.x = i * swfBtn.width;
addChild(swfBtn);
swfBtn.addEventListener(MouseEvent.MOUSE_OVER, onOver);
swfBtn.addEventListener(MouseEvent.MOUSE_OUT, onOut);
}
}
function onOver(event:MouseEvent):void {
/* need to target individual instance here */.filters = [new GlowFilter(0x0169AC, .50, 20, 20, 5, 5, false, false)];
}
function onOut(event:MouseEvent):void {
/* need to target individual instance here */.filters = null;
}
Mazoonist
10-15-2008, 05:41 AM
use event.currentTarget:
function onOver(event:MouseEvent):void {
event.currentTarget.filters = [new GlowFilter(0x0169AC, .50, 20, 20, 5, 5, false, false)];
}
It's kind of like saying "whichever button you are" do this or that.
zwemg
10-15-2008, 05:48 AM
Cheers mate, I thought that might have been the answer. I tried it right after I posted :)
Thanks for ur help, much appreciated
use event.currentTarget:
function onOver(event:MouseEvent):void {
event.currentTarget.filters = [new GlowFilter(0x0169AC, .50, 20, 20, 5, 5, false, false)];
}
It's kind of like saying "whichever button you are" do this or that.
Mazoonist
10-15-2008, 05:54 AM
I realize in that last example, the array didn't even come into play. But if you needed to do different things for different buttons, then you'd have to detect which button is being moused over or whatever:
function onOver(event:MouseEvent):void {
switch (event.currentTarget) {
case buttonList[0] :
//action
break;
case buttonList[1] :
//action
break;
case buttonList[2] :
//action
break;
}
}
Of course, if you use something like the above, you'd have to know ahead of time how many elements are in the array, which kind of goes against the idea of a flexible system, but this is just an example, to kind of give you something for further thought.
zwemg
10-15-2008, 06:05 AM
Yeah the array wasn't really used was it.
The xml file Im loading in has a heap of nodes so I will be building on this quite a bit. I striped out all the other push methods to clean it up to post on here and simplify it.
Cheers for the case methods also. Never really use this type of approach but it does come in handy when catching keyboard events.
As far as accessing my elements in the arrays now does this mean I will have to create all future event listeners within that onLoaded function so as it becomes available ( loaded in order)?
zwemg
10-15-2008, 06:31 AM
ok, last question.
Say I had the following code below. I've added another array to push values into. How can I get the elements name into my textfield.
var swfBtn:AnimationButton;
var buttonList:Array = new Array();
var titleList:Array = new Array();
var myURLLoader:URLLoader = new URLLoader();
var myURLRequest:URLRequest = new URLRequest("swfData.xml");
myURLLoader.load(myURLRequest);
myURLLoader.addEventListener(Event.COMPLETE, onLoaded);
function onLoaded(e:Event):void {
var xmlData:XML = new XML(myURLLoader.data);
var a:Number = xmlData.swf_name.length();
for (var i:Number = 0; i < a; i++) {
swfBtn = new AnimationButton();
titleList.push(xmlData.title[i]);
buttonList.push(swfBtn);
swfBtn.x = i * swfBtn.width;
addChild(swfBtn);
swfBtn.addEventListener(MouseEvent.MOUSE_OVER, onOver);
swfBtn.addEventListener(MouseEvent.MOUSE_OUT, onOut);
}
}
function onOver(event:MouseEvent):void{
event.currentTarget.filters = [new GlowFilter(0x0169AC, .50, 20, 20, 5, 5, false, false)];
titleTxt.text = /* this text needs to be pulled from the titleList array but needs to correspond with the target element */
}
function onOut(event:MouseEvent):void {
event.currentTarget.filters = null;
}
jmparsons
10-15-2008, 07:47 AM
try this:
var buttonList:Array = new Array();
var titleList:Array = new Array();
var myURLLoader:URLLoader = new URLLoader();
myURLLoader.load(new URLRequest("swfData.xml"));
myURLLoader.addEventListener(Event.COMPLETE, onLoaded);
function onLoaded(e:Event):void {
var xmlData:XML = new XML(myURLLoader.data);
var a:int = xmlData.swf_name.length();
for (var i:int = 0; i < a; i++) {
titleList.push(xmlData.title[i]);
buttonList.push(new AnimationButton());
buttonList[i].x = i * buttonList[i].width;
buttonList[i].id = i;
addChild(buttonList[i]);
AnimationButton(buttonList[i]).addEventListener(MouseEvent.MOUSE_OVER, onOver);
AnimationButton(buttonList[i]).addEventListener(MouseEvent.MOUSE_OUT, onOut);
}
}
function onOver(event:MouseEvent):void {
event.currentTarget.filters = [new GlowFilter(0x0169AC, .50, 20, 20, 5, 5, false, false)];
titleTxt.text = titleList[event.target.id];
}
function onOut(event:MouseEvent):void {
event.currentTarget.filters = null;
}
zwemg
10-15-2008, 11:07 AM
Thanks jmparsons,
Works like a charm :)
Thanks also to everyone for ur help on this one.
Special mention to Mazoonist!
Happy scripting everyone!
|
vBulletin® v3.8.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.