Copy link to clipboard
Copied
I have some code for an RPG battle system where, when the menu's attack button is pressed, the code goes through all the stages children, determines which are linked to the class Enemy, and then adds an event listener to each one.
function targetParse():void{
for(var i:uint = 0; i < stage.numChildren; i++){
var enemy:Object = stage.getChildAt(i);
trace('enemy identified')
if(enemy is Enemy){
trace('its an enemy')
enemy.addEventListener(MouseEvent.MOUSE_OVER, arrowControl);
trace('listener added')
}
else{}
}
}
All these trace statements are for debugging. It gets to 'enemy identified' but doesn't seem to be running the if statement.
I think it's probably my syntax.
I got it now.
function targetParse():void{
menu.alpha = 0.5
menu.attackBtn.removeEventListener(MouseEvent.CLICK, playerTurn);
for(var i:uint = 0; i < numChildren; i++){
var enemy:Object = getChildAt(i);
if(enemy is Enemy){
enemy.addEventListener(MouseEvent.MOUSE_OVER, arrowControl);
trace('enemy' + i);
}
}
}
The enemy variable had to be redefined every time, it used to be above the for loop. It works like a charm now.
Copy link to clipboard
Copied
Get rid of stage. in both places. So code is now:
function targetParse():void{
for(var i:uint = 0; i < numChildren; i++){
var enemy:Object = getChildAt(i);
trace('enemy identified')
if(enemy is Enemy){
trace('its an enemy')
enemy.addEventListener(MouseEvent.MOUSE_OVER, arrowControl);
trace('listener added')
}
else{}
}
}
Copy link to clipboard
Copied
Ok, I did that.
Now it puts the event listener on one of the enemies on screen (there are 2) and doesn't do anything for the other. I need it to add to every Enemy on screen.
If there's another way to do this that would be great.
Copy link to clipboard
Copied
The code will work fine if all your enemies are placed in the UI and they are all in the same container. If they are not, and you're placing with code, then you will need to getChildAt and numChildren on the proper container. Put in more traces and see how many numChildren are being reported.
Also, if you try what you had before, just for learning, and do stage.numChildren you will see there is just 1 - the MainTimeline object.
If I stick 10 instanced of a clip onto the stage in the Flash UI and run that function, all of them get assigned properly.
Copy link to clipboard
Copied
I don't know what I'm doing, then. All my enemies are placed through the UI on their own layer. Maybe it's the function that the event listener sends to.
function arrowControl(evt:MouseEvent):void{
arrow.x = evt.currentTarget.x
arrow.y = evt.currentTarget.y - 20
trace('complete')
}
arrow points to a MovieClip that is an indicator arrow with animation.
Maybe this makes the arrow stuck the first time it's activated, so I don't see it when I mouse over the other enemy?
If that didn't make sense, here's whats happening:
The attack button is clicked, and that runs through the child list, picks out the Enemy class, and adds mouse over event listeners to all of them, which point to the function arrowControl. arrowControl changes the location of a MovieClip arrow to the x and y of the current moused-over enemy.
Copy link to clipboard
Copied
Just tried with the arrowControl function and it still works fine - arrow moves to all clips properly. The only way it didn't was when I had the arrow and enemies on the same layer - and had enemies placed after the arrow - so that the arrow was now 'under them'. Is you arrow on a separate layer above all the enemies?
Copy link to clipboard
Copied
Yes, it is...
Is your function which activates targetParse() on the same layer as the arrow? Mine is, and it probably has nothing to do with this, but who knows?
Copy link to clipboard
Copied
I didn't mean function, I meant MovieClip
Copy link to clipboard
Copied
Yeah, that would not matter. It is easier to keep all your code together in a separate actions layer though.
Did you put in traces - does the numChildren in the container your iterating match the number of enemies? I would think it can't...
Copy link to clipboard
Copied
It spits out 4, two enemies, 1 menu, and one arrow.
It also spits out 'keep parsing' which is one of the trace statements under the else statement in targetParse()
So it's detecting two things, an enemy and the menu or the arrow, and doing the right thing about them. It seems like once the code runs once, it breaks the for loop.
Copy link to clipboard
Copied
I got it now.
function targetParse():void{
menu.alpha = 0.5
menu.attackBtn.removeEventListener(MouseEvent.CLICK, playerTurn);
for(var i:uint = 0; i < numChildren; i++){
var enemy:Object = getChildAt(i);
if(enemy is Enemy){
enemy.addEventListener(MouseEvent.MOUSE_OVER, arrowControl);
trace('enemy' + i);
}
}
}
The enemy variable had to be redefined every time, it used to be above the for loop. It works like a charm now.
Copy link to clipboard
Copied
Not really... you had enemy redefined every time even in your initial post. What fixed it was removing stage.