Archived

This topic is now archived and is closed to further replies.

fixxorion

Space Battle!!

Recommended Posts

Hi all! I'm trying to create the effect of ships fighting against each other. I can get the spaceships to follow after each other, but I'm having a little problem makin it look good. Sometimes, when the ships swing around to make another shot at their target, they just snap around...instead of swerving around like a "real" spaceship would do. :D Right now, I'm just taking ship A's position and subtracting that from ship B's position, and then adding the resulting vector to ship A's velocity. How would I go about actually making the spaceships perform more realistically...like having limits on how fast it can swerve, how fast it can move, etc. I've tried looking through GameDev for a solution, but I'm not sure what to look for. I've seen people recommend Craig Reynolds steering behavior, and I've checked it out. However, my problem is a bit different. Any help on this would be GREATLY appreciated! I'm desperate! Thanks, fixxorion [edited by - fixxorion on October 6, 2003 6:56:08 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by fixxorion
Right now, I''m just taking ship A''s position and subtracting that from ship B''s position, and then adding the resulting vector to ship A''s velocity. How would I go about actually making the spaceships perform more realistically...


First of all, you''d be better off working with the velocity vector of ships A and B, rather than the position vectors. Deduct A''s velocity vector from B''s to get the relative velocity of A with respect to B.

To limit the amount that a ship can turn in a given frame update, apply a fractional time step to the thrust vector. Let''s say that a given ship can turn at 90 degrees per second. Then, if your frame rate is 60 fps, that ship can turn 1.5 degrees per frame. Get the idea? To make use of this with your current computation, you can do one of two things.

1) Compute the angle between the heading of B and the direction to A. i.e., how much does B need to turn by to be heading toward A''s last position. Work out how much of that can be turned in the next frame and adjust the heading of B accordingly.

2) Simply add a small left or right thrust vector to the ships velocity at each frame and rotate the ship so it is facing in the direction of its motion. This left or right thrust should cause the same angular displacement as the turn rate of the ship if it is to give the correct results.

Try these out and see which one is faster computationally and which one you like better.

If you need any more help, let us know.

Cheers,

Timkin

Share this post


Link to post
Share on other sites
Thanks for the quick response!

I think I see what you mean. However, I don''t understand what you mean by not using their position vectors. Here''s some pseudocode of the little I have now:

//---------------------------------------

Vector vecTarget = new Vector(target.x, target.y, target.z);
Vector vecShip = new Vector(ship.x, ship.y, ship.z);

Vector displacement = vecTarget - vecShip;

ship.velocity += displacement;

//---------------------------------------


Do you mean I would need to find the rotation needed in X, Y, and Z to be pointing at the target? And then, over time, increment the rotation until it reaches that point?

Thanks again for the help,

fixxorion

Share this post


Link to post
Share on other sites
quote:
Original post by jack_1313
I had an example I was going to send you, but apparently you''ve blocked your email adress.


Hey jack_1313, I would love an example as well! Could you please email it to me at jasoo24 [at] hotmail.com?

Thanks!

Share this post


Link to post
Share on other sites
Wait... before everyone gets excited I should point out a few things:

The example is 2D, overhead, and features two teams of Fighters,Bombers, and and a Cruiser dueling it out. However, the AI could eaisly be transfered to 3D.
The example is an exe, but I intend to explain how it works with another post a little later.
This AI is simple - the whole example took me about 30 minutes to create, but is efficiant. It is intended as a base from which to work off. When I made this, I wanted to keep it simple so I could have 100''s of ships fighting at once.

So I will send it, and if you are interested, please say and I will state exactly how the AI works, and offer suggestions on how to make it better. Also, I the example plays kind of like a move - because the AI has no random elements the battle is the same every time. If interested, I could make it so that you could lay down ships, and then run custom battles.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Hi all

jack_1313, I am interested in this topic could you please post how the Fighters and AI works.

i would be grateful if you can send the example, this is my email

the_moon_warrior@yahoo.com

thankx

Share this post


Link to post
Share on other sites
What I''m still unsure about is the method for getting the ship to turn around. As I understand it, you add a vector perpendicular to the current vector. In other words, you would need to do something like the following:

Vector ship;
Vector target;

// basically find a perpendicular vector of ship that points in
// the general direction of the target
ship += ship.perpendicularVector(target) / 5

Is this the right way to do it? If so, how would I do this in 3D?

Thanks,

fixxorion

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Can you send me the example as well, please?
I would really appreciate it - I am working on a star control type melee game and am still strugling with the AI.

mail: 13436740@sun.ac.za

thanks,
neil

Share this post


Link to post
Share on other sites
Ok, I've sent the example - twice, because I sent it... then decided to improve it so that you can create your own custom battles etc. The second version is much better. Anyhow... for how the AI works
In the main loop for the game, we do the AI for every spaceship:

Set our target to point at nothing (target being a pointer)
If any enemy spaceships exists, we find the closest one and set our target to it.
Now we ask if target still equals nothing, and if it doesnt, then we do this:

Take the direction to our target and call it P.
Take the distance to our target and call it D.
Note: When I say direction, I refer to directly right as 0, up as 90, left as 180 etc in an anti-clockwise circle
Take the difference between the current direction that our ship is facing and P, and call this A
Note: At this point I will metion that each spaceship has the following variables describing its cababilities - acceleration, max-speed and turnspeed
We now ask if D is bellow a certain number (I use 30 in the example, buy this number will differer depending on the scale of the spaceships and the range of the weapons) and if it is, we do this:
if(A<80)direction+=turnspeed;
if(speed<maxspeed)speed+=acceleration;
Thus, if we are too close to our enemy we will turn away to our left (or right, it doesnt mater).
We now ask if A is above 5, and if it is, we turn toward our target. You may notice that this contradicts the lines of code above, but suprisingly, it works well - you have the effect of 'swerving' while an enemy craft tails.
If a is not above 5, however, we are staring straight at our target. So in this case, we ask if D<100(this nuber will vary depending on scale/ weapon range), and if it is, we fire our guns (provided our guns are ready to be fired).
The last part is this:
if(A>30){if(speed>1)speed-=acceleration/2;}
else{if(speed<maxspeed)speed+=acceleration;}
This is a very important part: if we are facing our target, or near facing our target, we will speed up. Otherwise, we will be turning, so we should slow down.

Now this AI is not without flaws - often you will see two oposing fighters flying alongside, both swerving - they are on eachother's tail, or so they both think. But this situation is resolved withing a few seconds.

There is something I strongly suggest when programming AI. You should give each ship variables such as:
int accel;
int turndir;
What these do is stop conflicts between different parts of the AI script. After the script is executed, change the ship's position, direction, speed based on the variables.
direction+=turnspeed*turndir.
if(accel==1)speed+=acceleration; else if(accel==-1) speed-=accelaration/2;
Each loop, set these variables to 0, then executed the script, then update the spacecraft based on new information. Instead of this:
if(A>30){if(speed>1)speed-=accel/2;}
else{if(speed<maxspeed)speed+=acceleration;}
do this:
if(A>30){if(speed>1)accel=-1;}
else{if(speed<maxspeed)accel=1;}
Then if the speed changes later on in the script it doesn't mess everything up. Also, I makes it extreamely easy to take player input. Take a look at this (executed for each ship every loop):

accel=0;
turndir=0;
shooting=0;
if(control=0) //human

TakePlayerInput();
else
AIScript();
//Now update the ship based on new info

direction+=turnspeed*turndir.
if(accel==1)speed+=acceleration; else if(accel==-1) speed-=accelaration/2;
if(shooting)//make bullet etc


This gives also gives the feel that the AI is 'piloting' the ship, and makes sure that AI ships follow the same physics as you do.

Man, this post is getting really long... I feel like I writing a tutorial or something. Oh well, next part: improvements.

While the AI I have described works well enough for simuating large space battles (suitable for stratergy games etc), I the player is going to be flying against these ships, I'm not sure how the AI would react. So the AI needs to be improved. Note that I perousfully kept it simple, so I could have many ships in the air at the same time.
The first improvement that comes off the top of my head involves this:
If any enemy spaceships exists, we find the closest one and set our target to it.
Obviously, the closest target is not always the best one. Targest should be chosen from a combination of information - mainly distance and difference between our direction and the direction the the enemy, but also take into account things like a ship's health, and a really smart thing to do would be to take into account how many enemy ships are nearby the possible target compared to how many friendly ships are nearby our possible target... we dont want to willingly fly into an ambush. However, this sort of this has a heavy proscessor cost. When pick a target, you must go through each enemy, give the enemy a value based on all the stuff, and then pick the best one (normally the lowest valued one). Or, you could simply chose the closest enemy, if you want to keep it simple.
Another way of doing things would be to calculate the best target for each ship, then calculate the ships into small groups (based on distance between ships), then, for each group, you could go through each ships target, pick the best one for the group (using the groups average xy position, direction, health etc), and then assign the target to the entire group. I have never tried this, but it would make for some interesting squad-based combat - quite enteratining to watch I would think.
Another way to improve your ship's AI is to create more realistic flight tactics - using more ifs and else's, and a lot of testing.
An obvious way to improve the ships AI (ecspecially when facing human pilots) is to have the AI aim at a point a ahead of a moving target based on the target's direction/velocity. However, this involves some complicated mathamatics so I'm not going to go into that here.

I feel that I should metion that I have chosen not to include vector movement (I think that is what it is called). Ie, ships simply fly straight forward in whatever direction they are facing, as apposed to difting like something would were he in space.

Anyhow... now that I have finished writing this book... ah... post, I certainly hope that you have benifited from it, considering it has taken half an hour to explain. lol.

Edit: I have put everything in source tags because for some reason the text turned out wrong if I didn't...

[edited by - jack_1313 on October 7, 2003 7:58:33 PM]

Share this post


Link to post
Share on other sites
Great example, bud!

Out of curiosity, I ran the sim several times and the same outcome occurred everytime. Do you use the same random seed or did you just not use any random numbers?

Share this post


Link to post
Share on other sites
Hi JasonA. The AI uses no random numbers, which causes the same result every time you run the same battle. Did you get my second mail, where I have changed the program so that you lay down the ships, then run the battle? I sent it, but the got a message back from the hotmail ppl saying that the mail could not be sent. Is you inbox full? If you want the newer program, say so and I will send it again. It is quite a lot of fun just to test different formations of spaceships against eachother.

Share this post


Link to post
Share on other sites