In this post, I’m going to describe the method I used in my DevSta entry to get the enemy vehicles to avoid the rocks (and each other). The technique is pretty simple, and isn’t actually all that “intelligent” as far as “artificial intelligence” goes, but it does give pretty good results, I think.
First thing’s first. If you compile my entry with the “SHOWLINES” conditional compilation symbol defined (go into the project’s Properties, then on the “Build” tab, the conditional compilation symbols are the first text box – in Debug builds, it also defines TRACE and DEBUG. Just add SHOWLINES to the end), my code will render so extra “lines” around each of the vehicles to help give you an idea of what they’re “thinking". It was just a convenient way for me to debug and so on. Here’s a screen-shot:
Ignore the black boxes for the time-being (I might post on the details there at a later time), there’s three main lines that are interesting here. The first is the blue line, which represents the current “heading". This is the direction the vehicle is currently moving in. The red line represents the “goal” or the direction in which the vehicle wants to be moving in, and the short yellow line is the “steering” vector (which I’ll get to in a second).
The first step for us to work out is the position of the red “goal” line. When the vehicle starts off, the goal is randomly chosen to be either one of your rocket launchers, or a space in between your rocket launchers. Half the enemy vehicles will go straight for a rocket launcher and half will try to “slip past” between your rocket launchers. So we start off with a “goal” line that points off the bottom of the screen.
Next, each game loop, the vehcile will look for the closest obstacle - either a rock or another vehicle (also the edge of the screen) - and if the closest obstacle is within a certain distance, the “avoidance” logic will kick in. Basically, that just means we modify the goal line to point directly away from that obstacle. You can see in the screenshot above, if you trace the goal line towards the rock, it actually points right at the middle and that the two vehicle’s goal lines points to a spot that is directly away from the rock.
Now, if the goal line and the blue “heading” line don’t match up, we calculate the yellow “steering” vector you can see. Basically, the steering vector is simple a line that is perpendicular to the heading line, and in the same direction as the goal line. The length of the line is proportional to how far we are from the obstacle. You can see the right-hand vehicle is a bit closer, so it’s steering vector is slightly longer (it’s trying harder to avoid the rock, basically).
So all we do then is add the steering vector to the vehicle’s “heading” line each game loop and the vehicle will turn towards the goal.
Once the vehicle is far enough away from the nearest obstacle, the goal line will go back to the original goal it was at the start (i.e. one of your rocket launchers or whatever) and it’ll continue to travel down the screen.
As I said, the logic is actually pretty simple - there’s certainly room for improvement - but it does end up looking pretty good (I hope!) and it even works quite well for the “friendly” vehicle which sometimes makes his way up the screen.