Friday, October 21, 2005

And an RTS was born!

I think I should introduce myself. I am J Kuhl. I make games, flash animations, and fool around with fun and fancy programs. Unfortunately, I have never finished a game. I came close once. Stronghold. A very simple game, a very serious bug. I couldn't fix it. So I have abandoned it. I will go back some day though. Anyways, I am anonymous_alcoholic at 3d Gamestudio's forums and at the forums at 3dgsuv.com and if you need any help, I'll be floating around the forums.

One of my goals with 3d Gamestudio was to make a RTS (Real Time Stratagy) game. It would take what I liked best about Galactic Battlegrounds and Empire Earth and combine them into an uber RTS game. So I started some work. I have unit selection half created. Selection will have multiple parts: click to select one unit, double click to select all visible units of the same type, ctrl+click to select multiple units, drag+click to lasoo units. Once a unit is selected, the player can move it or send it to attack by rightclicking. ctrl+rightclick allows player to attack allies because sometimes the computer needs retribution!

Currently, I have ctrl+click selection working. It is the easiest of them all. My plan of attack on single unit selection has failed so far. Fortunately, Grimber, on the Forums, may have come to my aid. Arrays. He has an idea with arrays.

My movement is also comming along. The code is erratic, but its a start. I need to tinker with it more. The unit doesn't stop at its defined stopping point yet, but he moves towards it. Multiple unit movement is not working yet but I haven't put my heart and soul into that part of the operation, I haven't worked real hard on it yet.

An RTS game is not as simple as it appears to be. Selection should be one of the simpler codes. Right now, I am in fright of the time when I get to do AI . . .

Ah, but that is the fun of it!

This RTS is my primary project right now. But I'll be popping into Stronghold now and then to try to fix/finish it. Before leaving, I wanted to show off my favorite part of Stronghold's code, the MG42 gunners and the sniper towers, well, the MG42 gunners specifically, but the towers work the same way.


action mg42Gunner
{
var gunnerHandle;
var mgScan;
my.mg42 = on;
my.pan = 180;
my.metal = on;
my.enable_detect = on;
my.lightrange = 100;
while(1)
{
mgScan.pan = 360;
mgScan.tilt = 360;
mgScan.z = 2000;
scan_entity(my.x,mgScan);
if(mgTargSw != null)
{
if(mgTargSw.health > 0)
{
gunnerHandle = ent_playsound(my,mg42SND,1000);
while(snd_playing(gunnerHandle) == 1)
{
if(mgTargSw == NULL) { break; }
vec_set(temp,mgTargSw.x);
vec_diff(temp,temp,my.x);
vec_to_angle(my.pan,temp); //turn to target
trace_mode = ignore_me + ignore_passable + ignore_maps + activate_shoot;
trace(my.x,mgTargSw.x);
wait(1);
}
sleep(random(1) + 2);
}
}
wait(1);
}
}

The great thing about this code was that it was a stroke of genius on my part! I was having trouble making these work and then this solution came to me, and to my surprise, it worked the way I wanted it to.

First it sets up two variables, gunnerHandle, which deals with sound, and mgScan, which is a vector that deals with the scan cone. The next line is a way around dealing with pointers. Pointers are very tricky to work with and I find that it is best to avoid them. This method won't work in all situations, but it was awesome in this one. Then the next two lines set the object's properties; it faces to the left of the screen and it's set to look metallic. It can sense scans. Now that I think about it, I'm not sure if I need enable_detect . . . I'll play with it tommorrow. Then it sends out light. Light made it look better. The mg42 is in the window of a building. It was dark and ugly. Now it isn't.

Then there is the main while loop. This loop keeps running until the game ends. The mg42 cannot be removed once created. mgScan is set in the next three lines and the forth line after performs the scan. It scans for enemy entities in a full sphere with a radius of 2000 quants. Another function ensures that only enemies are sensitive to this scan. That other function sets the pointer mgTargSw to the target that detected the scan. (Odd point here: mgTargSw stands for Machine Gunner Target Sword, so as a note of history, I obviously planned to set new pointers for each type of target and realized that I was overcomplicating things. I became lazy, and didn't change the pointer name.)

Then, there is that if statement, if(mgTargSw != null). Once a target has been set, it goes to the next if statement which simply makes sure that the mg42 doesn't fire on a dead guy. If the guy isn't dead yet, a sound is fired, one from Saving Private Ryan, I believe. I don't have an mg42 at home that I can record, unfortunately.

Then a new while. As long as the sound is playing, the gun is firing. The next bunch of lines are simple; Break out of the loop if mgTargSw has died (it'll remove itself when dead and therefore become null), turn to the target, trace the target. That same function that assigned the target the pointer, also kills him. The trace hits the target, his event_shoot event is triggered and his health is diminished until at last, he dies and disappears. Once the mg42 stops playing the gun sound, it stops shooting for about a second. In that time the player is suppose to pretend that it is reloading.

This is the fun in programming. Breaking things apart in reality and rebuilding them little by little in virtual reality. I can easily say: find target, turn, shoot and killl in english. Hell, I can do it in french! cherchez votrez cible, tourez, tirez, et tuez-la! But to speak in C-Script is much more complicated. C++ can be worse!

while(thisCodeWontWork)
{
smashComputer(); //take out some pent out anger
throwDartsAtBoss(); //take out more anger
sleep(6*60*60); //sleep six hours
}

No comments: