Flash Path Finding Tutorial
Path finding, it’s used a lot in games, such as Age of Empires, and involves something getting from point A to point B. Though it’s not as simple as that. It’s got to go around objects, finding the quickest route etc. Well lets start with something small and build our path finding engine up.
I’m using Actionscript (AS) 2, and I’d recommend having you’re frames per second (FPS) at around 30. Sorted? Perfect.
Now firstly lets make our two points, point A and point B. These will be just two circles which we can drag and drop around. So draw two circles, turn them into movie clips and give one the instance name of “pointA” and the other of “pointB”. Now on the frame (it’s a good habit to code on the frame!) put this code:
pointA.onPress = function() {
//when you click on the MC pointA
this.startDrag();
//start dragging :O
};
pointB.onPress = function() {
//same thing for pointB
this.startDrag();
};
function onMouseUp() {
//when the mouse is up
pointA.stopDrag();
pointB.stopDrag();
//stop the dragging of both MCs
}
Now so long as you gave the two Movie Clips the correct instance names it should be working. Notice how instead of stopping the drag using an onRelease method we have onMouseUp? Well that’s so if you’re moving your mouse too fast when you release the dragging won’t continue. Now create our first path!
We’re going to use some API here, if you don’t know much about it I’d suggest researching it before continuing. Now we want to draw a line between pointA and pointB. Lets make an empty movie clip which will be used for the line, and a function of it drawing.
this.createEmptyMovieClip(”path”, 1);
//create a movie clip with the instance name of “path”
function drawLines() {
path.lineStyle(5, 0xFF0000, 100);
//give it a line style. You can change the colour if you want to
path.moveTo(pointA._x, pointA._y);
//move to pointA’s position
path.lineTo(pointB._x, pointB._y);
// move to pointB’s position
}
drawLines();
pointA.onPress = function() {
//when you click on the MC pointA
this.startDrag();
//start dragging :O
};
pointB.onPress = function() {
//same thing for pointB
this.startDrag();
};
function onMouseUp() {
//when the mouse is up
pointA.stopDrag();
pointB.stopDrag();
//stop the dragging of both MCs
}
So we’ve made a new movie clip named “path” and we’ve given it a line style. In our function we moved “path” to “pointA”’s position and we’ve drawn a line to “pointY”’s position. Now if you test that you find the lines are connecting to your circle’s top left hand corner. That’s because we need to center our circles on the little +. Go inside your circle and move it so that the + is in the middle. Great, now it works fine!
However when we drag our circles the line stays still. Well that’s why we put it in a function, so we can update the line’s position at any time. However we don’t want to update it all the time, only when the circles move. Now if you think about it we can just add that function whenever we release our circles, or when the mouse is up (!). The only problem now is that we’ll be drawing a new line, but the old one will still be there! We’ll have to clear it when we click on our circles. So our code should now be:
this.createEmptyMovieClip(”path”, 1);
//create a movie clip with the instance name of “path”
function drawLines() {
path.lineStyle(5, 0xFF0000, 100);
//give it a line style. You can change the colour if you want to
path.moveTo(pointA._x, pointA._y);
//move to pointA’s position
path.lineTo(pointB._x, pointB._y);
// move to pointB’s position
}
drawLines();
pointA.onPress = function() {
//when you click on the MC pointA
this.startDrag();
//start dragging :O
path.clear();
//clear our current line
};
pointB.onPress = function() {
//same thing for pointB
this.startDrag();
path.clear();
//clear our current line
};
function onMouseUp() {
//when the mouse is up
pointA.stopDrag();
pointB.stopDrag();
//stop the dragging of both MCs
drawLines();
//our line function
}
Perfect! We’ve just created our first ever path! Now for the hard part – obstacles in the way. Lets a square and give the instance name of “square”. Now we want to see when the line hits the square and then we can draw it. So what we do is
Check if where line would be is colliding with object —> Draw line to object
Simple enough. Though what we’re going to do next isn’t. This is going to drop us right in the deep end, starting with some math. This will be our new function to replace the old one:
function drawLines() {
path.lineStyle(5, 0xFF0000, 100);
//give it a line style. You can change the colour if you want to
var pathAngle:Number = Math.atan2(pointB._y-pointA._y, pointB._x-pointA._x);
//get the angle of the line
for (var i:Number = 1; true; i++) {
//run a for loop for the hit test forever…
var toX:Number = pointA._x+i*Math.cos(pathAngle);
//making a variable gets the x pixel of the line
var toY:Number = pointA._y+i*Math.sin(pathAngle);
//making a variable gets the y pixel of the line
if (square.hitTest(toX, toY, true) || pointB.hitTest(toX, toY, true)) {
//if the path hits either the square or the point at the set pixel
break;
//stop the infinite loop!
}
}
path.moveTo(pointA._x, pointA._y);
//start the line back to where it started
path.lineTo(toX, toY);
//move to where the collision happened
}
Now let me elaborate. We don’t need to draw our original line, because it won’t help us in any way. Then we get the line’s rotation using the coordinates of “pointA” and “pointB”. We then run an INFINTE loop – that’s why the condition is put as true. Don’t worry, this won’t crash Flash because it will be broken eventually. So now we have some math. We get the starting point of the line, then we get the pixel where the line will be because we know its angle. Because of the for loop we get EVERY pixel the line is going on, because unfortunately we can only hit test one pixel at a time. This may sound a little confusing, so I included a diagram to help explain it.

Now we check our new coordinates of where the line could be hit against the square and “pointB”. We check whether when it will hit pointB so that we know when to stop the for loop. Now we draw the line to the coordinates where the path collided with something. Tadaa! Now our whole code should be:
this.createEmptyMovieClip(”path”, 1);
//create a movie clip with the instance name of “path”
function drawLines() {
path.lineStyle(5, 0xFF0000, 100);
//give it a line style. You can change the colour if you want to
var pathAngle:Number = Math.atan2(pointB._y-pointA._y, pointB._x-pointA._x);
//get the angle of the line
for (var i:Number = 1; true; i++) {
//run a for loop for the hit test forever…
var toX:Number = pointA._x+i*Math.cos(pathAngle);
//making a variable gets the x pixel of the line
var toY:Number = pointA._y+i*Math.sin(pathAngle);
//making a variable gets the y pixel of the line
if (square.hitTest(toX, toY, true) || pointB.hitTest(toX, toY, true)) {
//if the path hits either the square or the point at the set pixel
break;
//stop the infinite loop!
}
}
path.moveTo(pointA._x, pointA._y);
//start the line back to where it started
path.lineTo(toX, toY);
//move to where the collision happened
}
drawLines();
pointA.onPress = function() {
//when you click on the MC pointA
this.startDrag();
//start dragging :O
path.clear();
//clear our current line
};
pointB.onPress = function() {
//same thing for pointB
this.startDrag();
path.clear();
//clear our current line
};
function onMouseUp() {
//when the mouse is up
pointA.stopDrag();
pointB.stopDrag();
//stop the dragging of both MCs
drawLines();
//our line function
}
Download Source Files: Mediafire
This tutorial was contributed by Souled of Mindless Games.

(8 votes, average: 4.13 out of 5)
hm, that’s a line of sight algo, not a path finding one.
Im not sure if this is the right Chaz, but the about me matched, its Joe, texmex, whatever, we used to talk on msn all the time, im a graphic designer, either way, it if is you, my new msn is tecks@live.com. To make this at least a bit on topic, very informative tutorial there.
Pretty neat. I’ll have to try this out later on.