Attached is a movie that uses a modified version of the script you posted.
I’m assuming your script was a frame script, and not attached to a button.
I renamed your fish movie to fish_mc, and added a movie point_mc so that the target can be visualized.
There were two problems that made it not work:
a) The onLoad() handler was not being called. In my version, the fish was
already on the stage, so this handler didn’t get loaded. I changed the script to simply generate the first point directly.
b) In the onEnterFrame() handler, the variables associated with the fish were being referred to as _x and _y. In a script attached to a frame, you must consistently use this._x and this._y to refer to properties of the object executing the function. Otherwise, you are referring to _root._x and _root._y, which you don’t want.
once those issues were solved, there was one problem that made it work poorly:
c) The function that tracked the point moved at constant X speed, and varied the y speed to suit, rather than moving at a constant speed. If
the speed was too large, it could oscillate around the target point and never hit it.
changeX and changeY are the distance on each axis to the target point.
You can use Pythagoras’ law to determine the distance to the target point:
dist = Math.sqrt(changeXchangeX + changeYchangeY);
Once you know the distance you can use it to modulate your speed more
effectively. The ‘unit vector’ (a vector whose length is one) to the target is
given by:
uX = changeX/dist;
uY = changeY/dist;
And you can travel in the direction of the target at any speed by using:
x = x + uXspeed;
y = y + uYspeed;
I’ve modified your script to use this kind of arithmetic - it computes the
distance to the target, and then adjusts the speed by using a
unit vector calculation:
speedX = speedchangeX/dist
speedX = speedchangeY/dist
This way, you are moving the fish at a constant speed, regardless of
the angle of travel.
This also eliminates the need to have condiitions to check for positive or negative motion. Whenever I see this kind of thing:
if (x < y)
// move in positive direction
else
// move in negative direction
I know it can be simplified, as I’ve done here.
Here’s the modified script:
// got rid of this
//
// fish_mc.onLoad = function()
// {
// trace('onload');
// generatePoint();
// }
//
fish_mc.onEnterFrame = function() {
changeX = pointX-this._x;
changeY = pointY-this._y;
// figure out 'unit vector'
dist = Math.sqrt(changeX*changeX+changeY*changeY);
goX = changeX*speed/dist;
goY = changeY*speed/dist;
this._x += goX;
this._y += goY;
if (this.hitTest(pointX, pointY, true)) {
generatePoint();
}
};
function generatePoint() {
pointX = random(Stage.width);
pointY = random(Stage.height);
speed = random(10)+1;
point_mc._x = pointX;
point_mc._y = pointY;
}
generatePoint();
This script can be further shortened by eliminating the variables goX and goY which are only used once - just use the calcuations directly.
Also note that you can eliminate the call to Math.sqrt() by pre-squaring your speed when you change the random point. Since we’re only using the square root like so:
speed/dist
We can also use
speedSquared/distSquared
and we’ll get the same result, avoiding an expensive square root
calculation. Then your onEnterFrame handler is simplified to:
fish_mc.onEnterFrame = function()
{
changeX = pointX-this._x;
changeY = pointY-this._y;
distSquared = changeX*changeX+changeY*changeY;
this._x += changeX*speedSquared/distSquared;
this._y += changeY*speedSquared/distSquared;
if (this.hitTest(pointX, pointY, true)) {
generatePoint();
}
};