1

I am from a php jquery background and i am currently getting to grips with flash as3 just not sure how to pass values to eventlistner function say i have the following.

for (var i:uint = 0; i < asteroids.length; i++)
{                   
    asteroids[i].x = Math.random() * 450;
    asteroids[i].y = Math.random() * 450;
    asteroids[i].addEventListener(MouseEvent.MOUSE_UP, changeValue);            
}

public function changeValue(event:MouseEvent):void
{
    playSound(anote);
    trace(event.currentTarget);
}

each asteroid that i addeventlistner in the loop i need to pass a different value to the function the var anote?

jquery i would do.

$(".asteroids").click(function() {

     // or something similar 
     var anote = $(this).attr('href');
     playSound(anote);

     return false;

});

Can someone point me in the right direction.

DCHP
  • 1,111
  • 6
  • 29
  • 53

3 Answers3

3

I suggest making a class for your Asteroid instances (assuming that's what's in the asteroids array). Each of those Asteroids could have an anote property with different values (this closely reflects your .asteroids elements href attribute.

public class Asteroid extends Sprite
{
    public var anote:String = "";
}

And then:

for each(var i:Asteroid in asteroids)
{                   
    i.x = Math.random() * 450;
    i.y = Math.random() * 450;
    i.addEventListener(MouseEvent.MOUSE_UP, changeValue);            
}

public function changeValue(event:MouseEvent):void
{
    playSound((event.currentTarget as Asteroid).anote);
}

Ideally, your Asteroid class would also contain the code in your example and reference whichever class deals with the playSound() method.


The other option is to create your own event class with the anote property that you can set at dispatch and work with. The process is quite lengthy, so here's a link to one of my previous answers with an in-depth explanation of implementing that:

Community
  • 1
  • 1
Marty
  • 39,033
  • 19
  • 93
  • 162
2

The simplest way I've found is to create a function in the addEventListener line:

for (var i:uint = 0; i < asteroids.length; i++)
{

     asteroids[i].x = Math.random() * 450;
     asteroids[i].y = Math.random() * 450;
     asteroids[i].addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent){
         changeValue(e, otherArguments);
     });

}



public function changeValue(event:MouseEvent, otherArguments:Object):void
{

    playSound(anote);
    trace(event.currentTarget);

}

Basically you create a wrapper function that can pass any arguments you need into the event listener function.

The other way to achieve this is to create your own class that extends MouseEvent and use that, but this is more complicated.

annonymously
  • 4,708
  • 6
  • 33
  • 47
  • That anonymous function you're creating there makes me feel really uneasy. Also `Object` needs a capital `O` :) – Marty Apr 24 '12 at 07:27
  • This is a bad practice because you will get additional memory usage for holding wrappers, Marty Wallace suggest better way. – Yarg Apr 24 '12 at 07:27
  • @Yarg I know this isn't such a great way to achieve the desired outcome, but it requires the least modification to the original code. I just thought the op would want to have a solution that fits in with the code he has, without having to make new classes or redesign. – annonymously Apr 24 '12 at 07:29
  • It's good to know you can do what you've done in your answer, so there's valuable and relevant information there. I just wanted to note that it's not a good approach from a memory consumption angle - which combined with your answer provides a great avenue of information for a newbie in ActionScript :) – Marty Apr 24 '12 at 07:30
  • Hi guys thanks for the replies i think ill try and write a class as i kinda want to stay away from bad practise, cause once i start ill always do it. Not sure how to do this ill try with the question below :) – DCHP Apr 24 '12 at 07:45
0

It's cumbersome to write a new class for the object or the event everytime, and it's unstable to use an anonymous function either. Just grab it in a variable:

var listeners:Object = new Object();

for (var i:uint = 0; i < asteroids.length; i++) {
  asteroids[i].x = Math.random() * 450;
  asteroids[i].y = Math.random() * 450;
  listeners[i] = changeValue(asteroids[i].anote);
  asteroids[i].addEventListener(MouseEvent.MOUSE_UP, listeners[i]);
}

public function changeValue(anote:Sound):Function {
  return function(event:MouseEvent):void {
    playSound(anote);
    trace(event.currentTarget);
  }
}

Then, to remove the listeners later:

for (i = 0; i < asteroids.length; i++) {
  //trace("asteroid" + i + " (before): " + asteroids[i].hasEventListener(MouseEvent.MOUSE_UP));
  asteroids[i].removeEventListener(MouseEvent.MOUSE_UP, listeners[i]);
  //trace("asteroid" + i + " (after): " + asteroids[i].hasEventListener(MouseEvent.MOUSE_UP));
}

See this answer on that issue too.

Community
  • 1
  • 1