Flash obstacle avoidance prototype
Obstacle avoidance can be very important in Flash gaming because allows designers to create smart enemies.
Obstacle avoidance behavior gives a character the ability to maneuver in a cluttered environment by dodging around obstacles.
In this prototype, I'll try to simulate everyday life.
In everyday life, you walk straight until an obstacle appears in your line of sight.
Then, you slow down, and choose a random direction to cross the obstacle. If necessary, you make two or three steps back and approach the obstacle again.
Well, I hope you don't act this way in your real life but this is what we are going to do in this prototype.
It's up to you to improve it and make a more realistic movement.
In the project there are 20 random obstacles placed in the same way as seen on Create a Flash Game like Nano War, and an object linked as runner running through them.
Runner's behavior is explained in the commented script
-
// movieclip that will host all obstacles
-
createEmptyMovieClip("obstacles", 1);
-
// placing 20 obstacles and the player
-
for (x=1; x<=21; x++) {
-
// can_place = true: I can place the obstacle / false: I can't
-
// initializing it to false to force entering the while loop
-
can_place = false;
-
// while loop to look for an empty space where to place the obstacle
-
while (!can_place) {
-
// setting can_place to true
-
// you can always place an obstacle until you can't...
-
can_place = true;
-
// generating random x and y positions, and random width
-
px = Math.floor(Math.random()*400)+50;
-
py = Math.floor(Math.random()*400)+50;
-
// if I am at the end of the cycle, it's time to place the runner
-
if (x == 21) {
-
w = 20;
-
} else {
-
w = Math.floor(Math.random()*100)+10;
-
}
-
// scanning all already placed obstacles
-
for (y=x-1; y>=1; y--) {
-
// determining the distance between the y-th obstacle and the one I am trying to place
-
dist_x = px-obstacles["sphere_"+y]._x;
-
dist_y = py-obstacles["sphere_"+y]._y;
-
distance = Math.ceil(Math.sqrt(dist_x*dist_x+dist_y*dist_y));
-
// this is the minimum distance I want between two obstacles:
-
// the sum of both radiuses plus 20 pixels
-
min_distance = (w+obstacles["sphere_"+y]._width)/2+20;
-
// if the new obstacle would be too close to an existing one...
-
if (distance<min_distance) {
-
// set can_place to false
-
can_place = false;
-
}
-
}
-
}
-
// I exited the while loop so I can place the unit...
-
// ... or the runner...
-
if (x == 21) {
-
_root.attachMovie("runner", "runner", x, {_x:px, _y:py, _width:w, _height:w});
-
} else {
-
obstacles.attachMovie("sphere", "sphere_"+x, x, {_x:px, _y:py, _width:w, _height:w});
-
}
-
}
-
// this movieclip is used only to visually trace the line of sight
-
createEmptyMovieClip("collisions", _root.getNextHighestDepth());
-
// random starting angle, in radians
-
angle = Math.random(6.28318531);
-
// starting speed
-
speed = 2;
-
// minimum speed, negative to allow runner to make some steps backward
-
min_speed = -2;
-
// maximum speed
-
max_speed = 4;
-
// this is the line of sight
-
forecast = 50;
-
// step, in radians, the runner will turn if it finds an obstacle
-
turning_step = 0.5;
-
// this is the acceleration/deceleration rate
-
speed_step = 1;
-
runner.onEnterFrame = function() {
-
// finding the end point of the line of sight
-
forecast_x = this._x+forecast*Math.cos(angle);
-
forecast_y = this._y+forecast*Math.sin(angle);
-
// drawing the line of sight
-
collisions.clear();
-
collisions.lineStyle(1, 0x00ff00);
-
collisions.moveTo(this._x, this._y);
-
collisions.lineTo(forecast_x, forecast_y);
-
// if an obstacle is in the line of sight
-
if (obstacles.hitTest(forecast_x, forecast_y, true)) {
-
// if the runner still has not turned
-
if (turn == 0) {
-
// decide where to turn
-
turn = Math.floor(Math.random()*2)+1;
-
switch (turn) {
-
case 1 :
-
angle -= turning_step;
-
break;
-
case 2 :
-
angle += turning_step;
-
break;
-
}
-
}
-
// decelerate
-
speed -= speed_step;
-
if (speed<min_speed) {
-
speed = min_speed;
-
}
-
} else {
-
// accelerate
-
speed += speed_step;
-
if (speed>max_speed) {
-
speed = max_speed;
-
}
-
// turn = 0 means "next time I will find an obstacle I will have to decide where to go"
-
turn = 0;
-
}
-
// updating speed
-
x_speed = speed*Math.cos(angle);
-
y_speed = speed*Math.sin(angle);
-
//updating position
-
this._x += x_speed;
-
this._y += y_speed;
-
if (this._x>500) {
-
this._x -= 500;
-
}
-
if (this._y>500) {
-
this._y -= 500;
-
}
-
if (this._x<0) {
-
this._x += 500;
-
}
-
if (this._y<0) {
-
this._y += 500;
-
}
-
};
and here it is
As you can see, sometimes the runner is quite dumb, but it's a good start to develop a more complex AI script for obstacle avoidance
Download the source code and enjoy
Tell me what do you think about this post. I'll write better and better entries.
They can be easily customized to meet the unique requirements of your project.
8 Responses to “Flash obstacle avoidance prototype”
Leave a Reply

(13 votes, average: 4.92 out of 5)
This is pretty cool and I can already see a few games that could be developed around it. The simplicity of it is also great. Good idea
You could always read about backtracking if you want your AI to navigate in a labyrinth.
you can find two backtracking examples in this blog
http://www.emanueleferonato.com/2006/08/27/perfect-maze-generation-with-flash-actionscript/
http://www.emanueleferonato.com/2006/08/20/step-by-step-perfect-maze-generation-with-php/
If you want to make it look a bit slicker and remove some of the apparent dumbness you could make the current runner act as an invisible ’scout’ for another runner who can follow the correct path without the last minute decision making lol.
Just noticed something, theres an ad on your title, don’t know if you want that there?
This is pretty cool, sometimes the runner gets stuck in a rut, you could say, and will never hit any obstacles again, but as long as it has an obstacle in front of it, its cool
A lot of code, but works well. Now how do you get the player to go from one place to another avoiding obstacles?
emanuele i demand you GET OUT OF MY HEAD
im making a zombie game and was pondering how to do this for the past few days, and this just “MAGICALY” appears when i need it, i think not!
reminds me of the opensteer project. Take a look for some good (and opensource) sample code.
http://www.red3d.com/cwr/steer/