Advertisement

How to get Space Shooter Enemies to avoid bullets fired their way

Started by August 04, 2007 08:54 PM
2 comments, last by Timkin 17 years, 7 months ago
Hello, I wrote a simple side scrolling space shooter game in C# using GDI+ the other day. Anyway, I want to add some intelligence to my bad guys. I was thinking along the lines of looking ahead to see where a bullet's path will go, by extending out the rectangle that I'm using for collision detection. If the enemy "see's the bullet coming" then he can either move up or down to get out of it's way. But the problem is that there might be bullets below or above where the bad guy is. I don't want my enemy to be stupid enough to accidentally move straight up or down into the bullets I fire at it. Anyway, I was just hoping for some direction at algorithms to look at... especially if I'm going about this all wrong, or maybe if there is already an algorithm that describes this idea, then I could just go research that. Any advice would be appreciated. Thanks in advance.
The most basic approach is usually the best method to use. After all, it's the most easier to understand and can be used as a foundation, adding to, and changed later.

The easiest solution is to pick an arbitrary distance that will be based off of when the enemy ship should even start to change paths.

So you would do a distance check. Lets say 100 units or 100 pixels is when you start to begin bullet avoidance. The best way to move the ship would be along the cross product of the vector of the bullet. Then you would have to determine which way on the cross product. You can use the dot product to figure out which direction. Or a generic angle check to decided which way.

To decided when the ship should stop avoiding the bullet (once it decides it safe from that bullet) would be when the bullet is beyond the enemy ship. The only time you would have to check the bullet again, is if the ship is EVER moving backwards in any value.

Now to decided which bullet has the highest priority, would be the closest one.

Now this is basic, but it will work extremely well. Only in some instances will the ship be unable to dodge a bunch of bullets. But basically this will dodge all bullets up to a perfect precision without using prediction paths.

All you simply do is check all bullets within that 100 pixel or unit radius or whatever amount you want, and you only focus on the closest bullet.

And if you think about it, a human usually only worries about the closest bullet as well, but with alot more prediction.

The one situation where this solution can cause a problem, is when avoiding a bullet brings it within detection of another bullet, then it causes the ship to move back to the original avoided bullet, however, it will detect that as the closest bullet, and begin to move away, moving it to the other bullet and so on and so on. If the bullets are in parallel, the ship will move back and forth but stay centered bewteen the bullets and doge them. You can also build a anti-jiggle solution or can be solved by only moving the ship out of the bullet vector just enough (only move it by the width of the ship, once done, ignore the bullet)

The other way of doing it which is a little more complex is to detect all bullet vectors and make a system to move the ship to the closest safe zone. This would pretty much make the AI unbeatable as it would never make a mistake and the only way it would die is if there are no safe zones on the screen. That's of course if you have it detecting and avoiding at all times.

There are other solutions but I'm sure people will reply with them.

(these are the only 2 i can think of which I believe are most practical for a 2D shooter. Anything beyond this would be over kill but can still be done)
Black Sky A Star Control 2/Elite like game
Advertisement
Create a set number of possible moves(4 or 8 directions all a set distance from the current position). Calculate the danger at each position as the sum of all bullets that will collide with the ship at that point with each bullet weighted by distance(higher distance = lower weight). Use those danger ratings in coordination with other steering behaviors to dodge bullets while also doing other things. If needed a graph type search can be done where spaces are rated by their own danger and the nearby spaces danger in the future, but that gets a good bit more involved. I used a system like this for an eskiv type game where the AI would dodge while moving towards the goal. It did significantly better then any human player I've seen, even before I implemented the graph search. I'm not sure how fast it is though since in all my tests I was only using the AI on one unit.

edit: on second thought, if you just want them to move up and down to dodge that is probably way overkill. It would probably be sufficient to count the number of bullets above and below(maybe weight on distance along x axis) and then move in the direction with the lowest danger rating.
ViperG: the OP said 'side scroller', so we can assume 2D (hence the cross product is meaningless).

Personally, I'd use a simple, yet tried and trusted method, such as a potential function for steering. The simplest potential functions are inversely proportional to an integer power of the separation distance. For example, the Lenard-Jones function U = -A/rn(t) + B/rm(t). Differentiating w.r.t r gives the force, F = -An/rn+1(t) + Bm/rm+1(t). The first term is an attractive force, the second a repulsive force. Choose the constants A and B so as to balance these two forces (in most applications, one of A or B is zero, giving purely attractive or repulsive forces).

This force is a radial force, acting along the line connecting the two bodies at the present time (call that the vector r). For your application, you would presumably want to constrain the force to restrict the motion of your enemies; for example, purely vertical motions on the screen. If that is the case, then simply multiply F by the vertical component of the unit vector along r and apply that to your ship (it will be either a positive or negative value now, indicating forcing up or down the screen... depending on your coordinate axes).

Presumably you're using discrete time in your game. Set the acceleration a to a constant proportion of the force and the vertical velocity vy=adt, where dt is your physics timestep. Cap this value to prevent absurd speeds in your game and you're done.

The only thing left to do is choose the values of A,B,n & m to tune the system to the performance you want.

Cheers,

Timkin

This topic is closed to new replies.

Advertisement