
Passing variable to function in as3?
Hi FlashKit one and all.
Trying to create a random movement for fish MCs:
//
var deg2rad:Number = Math.PI / 180;
var speed:Number = 1;// set to speed you want
var numFish:Number = 4;
for (var i:int=1; i<=numFish; i++) {
main.swim["fish_"+i].addEventListener(Event.ENTER_FRAME, move_me(my_angle));
main.swim["fish_"+i].rotation = Math.random() * 360;
var my_angle:Number = main.swim["fish_"+i].rotation * deg2rad;
}
function move_me(e:Event, my_angle) {
for (var i:int=1; i<=numFish; i++) {
e.target.x = speed * Math.cos(my_angle);
e.target.y = speed * Math.sin(my_angle);
}
}
//
Problem I have is that they all move to the same angle (the last one created).
How do I pass the different "my_angle" values to the "move_me" function...?
Hopefully this is simple, and I've just missed something as I'm relatively new to AS3.
Thanks indeed!

First, please put your code in [code] tags.
Second, that code won't work at all, since move_me does not return a function suitable to be an event listener. I don't know what you're actually doing that you get them to move at all, but it's not the code you posted.
Third, you are adding your enter frame to each fish, but then you are also looping in the handler. Each fish will move once per fish. The more fish you have, the faster each moves. Don't do that.
Fourth, you cannot send extra information as a parameter to your event listener, but you can fake it. The event listener function must take a single parameter of type Event (or an appropriate subclass). You can create a function which builds such a function using an extra parameter you pass, but be aware that you will have to be smart about removing that listener later.
Or you could set the my_angle property on the fish itself, then use that value in the function.
You should also put your fish in a real array, but I'll leave that out for now.
Setting the property on the instance:
Code:
for (var i:int=1; i<=numFish; i++) {
var fish:MovieClip = main.swim["fish_"+i];
fish.rotation = Math.random() * 360;
fish.my_angle = fish.rotation * deg2rad;
fish.addEventListener(Event.ENTER_FRAME, move_me);
}
function move_me(e:Event):void {
var fish:MovieClip = MovieClip(e.currentTarget);
fish.x = speed * Math.cos(fish.my_angle);
fish.y = speed * Math.sin(fish.my_angle);
}
Using a function to build an anonymous listener function:
Code:
for (var i:int=1; i<=numFish; i++) {
var fish:MovieClip = main.swim["fish_"+i];
fish.rotation = Math.random() * 360;
var my_angle:Number = fish.rotation * deg2rad;
fish.addEventListener(Event.ENTER_FRAME, move_me(my_angle));
}
function move_me(my_angle:Number):Function {
return function(e:Event):void{
var fish:MovieClip = MovieClip(e.currentTarget);
fish.x = speed * Math.cos(my_angle);
fish.y = speed * Math.sin(my_angle);
}
}
In this case, I highly recommend the property way.
Last edited by 5TonsOfFlax; 02212011 at 01:55 PM.

Fantastic  thanks very much. And, yes you're right, the code I posted was a state that I'd been tinkering with, and didn't work.
What you suggested makes a lot of sense, I'm going to build my array now.
How would you alter the path of the fish too, so that they vary slightly from swimming in a straight line?
Thanks again!

To vary the fishes paths, create a small random offset on the angle in the event handler. Generate a random value between PI/8 and PI/8 and add that to the local my_angle before doing the cos and sin. Don't change the value of my_angle attached to the fish, or errors will be cumulative. A small random value should average out to near 0 over many iterations so your fish will continue on in the right general direction, but not exactly on it. Play with the denominator of the fraction to alter the amount of deviation.

Been looking at this, and not entirely sure of solution. This is as far as I've got... the fish swim in little circles....
Code:
var deg2rad:Number = Math.PI / 180;
var speed:Number = 4;// set to speed you want
var numFish:Number = 4;
var angles:Array = [];
for (var i:int=1; i<=numFish; i++) {
var fish:MovieClip = main.swim["fish_" + i];
fish.rotation = Math.random() * 360;
fish.my_angle = fish.rotation * deg2rad;
fish.addEventListener(Event.ENTER_FRAME, move_me);
}
function move_me(e:Event):void {
var fish:MovieClip = MovieClip(e.currentTarget);
var high:Number = Math.PI / 8;
var low:Number =  Math.PI / 8;
var varyPath:Number = Math.random() * (1+highlow)+low;
fish.my_angle += varyPath;
fish.x = speed * Math.cos(fish.my_angle);
fish.y = speed * Math.sin(fish.my_angle);
if (fish.x <= 0) {
fish.x = 1920;
}
if (fish.x > 1920) {
fish.x = 0;
}
if (fish.y <= 0) {
fish.y = 1080;
}
if (fish.y > 1080) {
fish.y = 0;
}
}
Thanks!

I see two major errors there, one of which I specifically warned you about.
Code:
var varyPath:Number = Math.random() * (1+highlow)+low;
What is that 1 doing there? You want the value to be between high and low, not between low and high+1.
Code:
fish.my_angle += varyPath;
This is the one I warned you about:
Don't change the value of my_angle attached to the fish, or errors will be cumulative.
Code:
var my_angle:Number = fish.my_angle + varyPath;
then use my_angle rather than fish.my_angle later in the function.

Thanks for your help. Now have this working as a package too, which is useful, and better practice.
One thing I still need to figure out, is how to change the direction the fish is pointing in according to the direction it is going in. Any ideas?

Convert the new my_angle back to degrees and set the fish's rotation property accordingly.
It baffles me why rotation is in degrees but cos and sin work in radians.
Posting Permissions
 You may not post new threads
 You may not post replies
 You may not post attachments
 You may not edit your posts

Forum Rules

Click Here to Expand Forum to Full Width
