Random shots and Movement

Started by
6 comments, last by randomDecay 22 years, 5 months ago
I am using C++ and want to know how to make my enemy ships shoot at a random time, and for that matter, make them move in a cool pattern, maybe a sine wave or a circular path.
Advertisement
random shots:

in your enemies structure define a variable that keeps the amount of frames to pass until you shoot a bullet...

then you initilize it like this..

bullet_launch = 100+rand()%500;

then each frame you decrease that variable and when it reaches 0 you shoot a bullet and initialize it again with the same formula..

that''s frame based... you can also make it time based, and use seconds/miliseconds based launches, so initialize bullet_launch with random value which represents the number of seconds to pass before shooting the bullet...

bullet_launch = GetTickCount() + (100+rand()%400);

the bullet will be launched in between 100-500ms

then each frame you compare the current time with the time to launch

if (bullet_launch < GetTickCount())
{

// time to shoot the bullet

}

=====================================

Now to the sine movement of the ships....


ship.x = SCREEN_WIDTH
ship.center_line = rand() % SCREEN_HEIGHT
ship.amplitude = 5+rand()%5

thats your initialization for the ship..it will come from right to left..

center line reprsents the center line around which the ship is going to move in sinusoidal pattern

the amplitude is how high/low the ship will go above and underneath the center line (which is a y-coordinate)

then each frame you do this...

(1) ship.x -= 5
(2) ship.y = ship.center_line+(ship.amplitude*sin(ship_angle*PI/180))

(1) first line you simply move the ship right to left in 5 pixel increments

(2) calculate the current ship.y value based on the center line, amplitude, and the ship_angle... ship angle is increased by some value once every frame... for ship angle try increments of 5, 7, 10..etc... see how that works...

Circular movement is pretty much the same but you don''t use center line and amplitude for that... you simply have a center point, a radius, and you increment the ship angle every frame and compute the x and y of the ship for that angle...

so you basically have

ship.x = ship.center_x + ship.radius*cos(ship_angle*PI/180)
ship.y = ship.center_y + ship.radius*sin(ship_angle*PI/180)

(center_x, center_y) is the point around which the ship will rotate in a distance of "radius"

btw, ship_angle is in degrees...you can always change that to radians..

Well, if you need more help with it let me know..

Later!
Hey Thanks. I am trying to calculate a random shot using the ms/seconds example you gave me and it isn''t working for some reason.
Paste the code that''s concerned with your random shots, and I''ll see what I can do.
I'd rather code it myself, so I'll just explain it to you. Basically, in your example, you wrote this:
---------------------------------------------------------------bullet_launch = GetTickCount() + (100+rand()%400);

the bullet will be launched in between 100-500ms

then each frame you compare the current time with the time to launch

if (bullet_launch < GetTickCount())
{

// time to shoot the bullet

}

---------------------------------------------------------------
bullet_launch is an int type right? And what does GetTickCount() do exactly? Thanks man


Edited by - randomDecay on November 6, 2001 2:42:59 AM
Hello!

The variable bullet_launch must be an unsigned long (a window''s DWORD). This is the type that GetTickCount returns.

GetTickCount returns a DWORD whith the number of miliseconds that have elapsed since the computer was started. The formal declaration of that function is :

DWORD GetTickCount(void);





"If you''''re gonna die, die with your boots on"
"If you''re gonna die, die with your boots on"
Okay, bullet_launch is of type DWORD (that''s the type GetTickCount() function returns).

GetTickCount() basically returns the number of milliseconds elapsed since you turned on your machine -- take a look at the Win32 API help file for more info.

And yes, bullet_launch should be in your enemy struct.

So you basically have this:

struct ENEMY
{
...
DWORD bullet_launch;
...
};

////////// MAIN PROGRAM ////////////

// before entering main loop initialize the first time to shoot the bullet

enemy.bullet_launch = GetTickCount() + (100+rand()%400);

while (in main loop)
{

... do stuff here...

// after you process enemy movement you do this

if (enemy.bullet_launch < GetTickCount())
{

EnemyShootBullet(.....);

enemy.bullet_launch = GetTickCount() + (100+rand()%400);

} // end if bullet launched

} // end if main loop

////////////////////

I suggest you make the bullet_launch wait for a few seconds before shooting a bullet since you will have quite a bit of processing to do inside your main loop with all the objects in your game, and also if you are locking your display to vsync(vertical synchronization) then it will spend some amount of time there too, so your game will be slowed down a little.

That''s why when you assign the bullet launch time make it for a few seconds, but it all depends on your type of game and how you structure the code so play around with what''s the best timing for you. First try with like a random time between 5 and 10 seconds, and if it''s too slow, then lower the lower/upper limits by some, then test again, and so on.

btw, let''s say you want to make the bullet to shoot in a random time between 1-5 seconds you will have this.

enemy.bullet_launch = GetTickCount() + 1000+(rand()%4000);

Of course GetTickCount() is not the most precise time function, but then again, it depends on the type of game you are making.

If you wanted it to be absolutely accurate you''d want to have a look at QueryPerformanceCounter() and QueryPerformanceFrequency().

But for now, until you get it to work, you can stick with what I gave you above.

Most games actually don''t need to use those high-accuracy timers, and GetTickCount() is pretty much enough in most cases.

If you make a game that needs to be very accurate at timing, then you''d use those functions I mentioned above.

If you need more help, let me know.

Later,
Viktor
Thanks again. That''s all I need, I''ll try it tomorrow, as I''m too tired to start programming again...hehe

This topic is closed to new replies.

Advertisement