Time to spit out tutorial number 2…
:: Distance AI ::
Out of all the Ai’s you’d less suspect to be one would be this. Why would this be an AI, how to use this AI and what are some of the advantages and disadvantages of this AI system will be discussed below.
The first thing we need to know is what exactly is distance AI and how does it work? Well…
Distance AI : Is an AI system that uses locations relative to the player character (PC) and then decides on a set number of actions based on how far away the character is.
It’s typically found in most beat em up games like Double Dragon and Final Fight. It can prove to be very useful in other situations as well…
Finding Distance
The easiest and best method for finding diatance is the system of relativity.
PC._x - Enemy._x;
PC._y - Enemy._y;
That would find the distance between the PC and the enemy in both the x and y directions… Notice though… That sometimes one of these values can be negative or can be positive. We can take care of that later then.
So we have ourselvs a set of equations finally… But what use are they and how would we use this to our advantage… Well… There are two different methods we could use to change the 2 equatiosn above into something useful…
The first way is relative math.
xdistance = pc._x - enemy._x;
ydistance = pc._y - enemy._y;
distance = (xdistance + ydistance) / 2;
That would give us a well rounded number that could equal the distance… But what’s wrong with this picture… Well if you think about it, if we take the pc and the enemy… And draw a line in between them… The line probably won’t be horizontal or vertical all the time. It’ll be angled… So the number this system spits out will be a rounded off number. It’s very useful for those types of games where getting faster is better instead of getting exact…
The next system is the exact math version…
xdistance = pc._x - enemy._x;
ydistance = pc._y - enemy._y;
distance = Math.sqrt(Math.abs((xdistance*xdistance)+(ydistance*ydistance)));
Wow… That’s a bigger chunk of code… But why… And what?! Huh? hehehe… I’ll explain now…
When you have an angled line you can use the Pythagorean Theorum to figure out how long that line is exactly. By taking the two sides that we know… a(x) and b(y) and popping them in the following equation. We can figure it out then…
c2 = a2+b2;
-= or =-
c = Square Root((a * a) + (b * b));
Allright. Well that’s not so difficult looking then right? Well. Squareroot only deals wiht positive numbers so… We then have to use the Math.abs function… Also… We needthe actual square root fucntion that we will be using.
Math.abs() : Takes the number in its argument and gives you the absolute value of it…
-20 would be 20
20 would still be 20
Math.sqrt() : Takes the number in its argument line and returns th square root of that number.
25 would be 5
100 would be 10
So… Then to get the entire equations right…
distance = Math.sqrt(Math.abs((xdistancexdistance)+(ydistanceydistance)));
Now… we have two basic methods for finding out the distance from your player character to the enemy… Which is the best one to choose for your game… Well unless you are trying o find “exact” locations. I’d suggest just using the relative equation. It’ll be alot faster running and it’ll save a lot of testing hassle in the long run.
Let’s use the relative one for our example. Now… We have something that will give us the distance… Woohooo… That’s what we wanted right?.. Right! So let’s continue on.
We can use this number to tell us how far away the enemy might be and we can also use the xdistance and ydistance values to determine if he’s north, south, east or west of my character. 
Now say I wanted my enemy to do the following actions at these distances.
Far : Throw Rocks
Mid : Defend
Close : Punch
Easy enough. Let’s think about how we would do that… Well… If the distance was over 200 pixels. That would be pretty far… And if it was between 100 and 200 that could be classified as mid range… And then the rest would be close range… Let’s write a quick algorithm to see if we can figure this out.
xdistance = player x location - enemy x location;
ydistance = player y location - enemy y location;
distance = (xdistance + ydistance)/2;
if(distance is far ranged (200 pixels+))
{
have enemy perform the rock throw;
} else if (distance is mid range (100 px to 200 px))
{
have the enemy go into defensive position;
}
else
{
have the enemy punch your guy;
}
Now that looks fine and dandy to most people… But then… What do we wanna do if say… the player is on the right and the guy is punching or throwing rocks on the left… Well… We need to determine which way the player is in relation to the enemy.
If xdistance is a negative number. That means that the enemy’s x location was higher than the players. xdistance = 200 - 300; That means that the enemy is to the right of the character.
If xdistance is a positive number. That means that the enemy’s x location was lower than the players. xdistance = 200 - 100; That means that the enemy is to the left of the character.
If ydistance is a negative number. That means that the enemy’s y location was higher than the players. ydistance = 200 - 300; That means that the enemy is to the bottom of the character.
If ydistance is a positive number. That means that the enemy’s y location was lower than the players. ydistance = 200 - 100; That means that the enemy is to the top of the character.
Well… Now that we know how to find out where the enemy is direction wise. We can figure out which way to have the enemy throw rocks or punch. Let’s throw this in the algorithm we created above. We won’t have to check y locations because we don’t care whether the enemy throws it up or down right now. We just wanna have the enemy throw it either left or right. Your game may need to use top and bottom and for those cases please use the above diagrams to help you out.
xdistance = player x location - enemy x location;
ydistance = player y location - enemy y location;
distance = (xdistance + ydistance)/2;
if(distance is far ranged (200 pixels+))
{
if(xdistance is positive)
{
have enemy perform the rock throw to the right;
}
else
have enemy perform the rock throw to the left;
}
} else if (distance is mid range (100 px to 200 px))
{
have the enemy go into defensive position;
}
else
{
if(xdistance is positive)
{
have enemy throw a punch to the right;
}
else
have enemy throw a punch to the left;
}
}
Well This code surely is developing… But like my random Ai example before. This is just an algorithm to get use where we want. The Real Code
Let’s break this up and run by with the real code.
xdistance = player x location - enemy x location;
ydistance = player y location - enemy y location;
distance = (xdistance + ydistance)/2;
I think I can just jump over this one seeing as how we discussed this over. Place either the relative distance or exact distance equations here.
xdistance = pc._x - enemy._x;
ydistance = pc._y - enemy._y;
distance = (xdistance + ydistance) / 2;
Now onward.
if(distance is far ranged (200 pixels+))
{
if(xdistance is positive)
{
have enemy perform the rock throw to the right;
}
else
have enemy perform the rock throw to the left;
}
}
We would writie this up as…
if(distance > 200)
{
if(xdistance >= 0)
{
enemy.performAttack("rockthrow", "right");
}
else
{
enemy.performAttack("rockthrow", "left");
}
}
Easy enough… Just a couple of simple if statements and some function calls. 
else if (distance is mid range (100 px to 200 px))
{
have the enemy go into defensive position;
}
Now into real code.
else if(distance > 100 && distance <= 200)
{
enemy.performDefense();
}
Now… Onto the last bit of code.
else
{
if(xdistance is positive)
{
have enemy throw a punch to the right;
}
else
have enemy throw a punch to the left;
}
}
Easy enough… This almost looks like the first one cept with an else…
else
{
if(xdistance >= 0)
{
enemy.performAttack("punch", "right");
}
else
{
enemy.performAttack("punch", "left");
}
}
And… That leads us to throwing it all together into one nice little happy family.
xdistance = pc._x - enemy._x;
ydistance = pc._y - enemy._y;
distance = (xdistance + ydistance) / 2;
if(distance > 200)
{
if(xdistance >= 0)
{
enemy.performAttack("rockthrow", "right");
}
else
{
enemy.performAttack("rockthrow", "left");
}
}else if(distance > 100 && distance <= 200)
{
enemy.performDefense();
}
else
{
if(xdistance >= 0)
{
enemy.performAttack("punch", "right");
}
else
{
enemy.performAttack("punch", "left");
}
}
Well everyone… That’s the final piece of code… Not too bad huh? It’s funny how something so advanced can amount to around 20-40 lines of code… Funny huh? Well… Like the Random AI you can use this in many different ways. You can use this in a function or you can just plop this in your code like it is. Either way, please comment me back with as much info as possible 
Thanks and Good Day
Marz
mentalconcepts@hotmail.com