Archived

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

TheBaker

Creating Bullets

Recommended Posts

TheBaker    122
How do you create bullets (and other objects that there can be a very large and variable number of) in a game? Say you create a Bullet class to hold location and direction, wouldn''t you need to declare a seperate instance for each bullet, meaning you''d have to declare them all before you started a level, using up a lot of memory. Could some one explain how they''d do it efficiently?

Share this post


Link to post
Share on other sites
siaspete    208
I think you basically answered your question. You can either allocate them when you need them and have a lower memory usage or you can allocate them in the beginning and take up more memory than you''ll actually need.

I''d give the std::vector class a go, or std::deque if you''re going to be adding and removing them all the time.

Perhaps you could store a bool in your Bullet class that says whether it''s actually being used or not. That way you can hold them in a vector and search for an unused one when you need one.

Or whatever.


Why you shouldn''t use iostream.h - ever! | A Good free online C++ book

Share this post


Link to post
Share on other sites
evolutional    1393
What you can do is make a std::list

and as you create a new CBullet instance, simply add it onto the list.

Make sure you remove the old ones after they expire!



(Pseudocode)

class CBullet
{
....
....
... static std::list<CBullet*> firedbullets;
};


FireBullet()
CBullet *bullet = new CBullet;
CBullet::firedbullets.push_back(bullet);

DoStuffWithBullets()
... recurse CBullet::firedbullets
if bullet == expired
{
CBullet::firedbullets.remove(bullet);
}



Hope this helps

Share this post


Link to post
Share on other sites
CodeMunkie    805
I use a hybrid technique. When I need to create one new bullet I just go ahead a create a block of 10 bullets but only set the active flag of one. Then when I need another new bullet, I just look through the inactive pool and set one to active. If the inactive pool is empty, then I create a new block of 10 bullets. It cuts down on the allocation overhead.

Share this post


Link to post
Share on other sites
JohnBolton    1372
quote:
Original post by TheBaker
... using up a lot of memory ...



How many bullets are you talking about? 100? 1000? 10,000?

Suppose there are 1000 bullets and each has a position, a velocity, and an age. Allocating space for 1000 bullets would require 28k, which doesn''t seem like a lot of memory to me.

Share this post


Link to post
Share on other sites
Thunder_Hawk    314
I agree with JB there, but do remember that that 28k comes out of your cache space, and just that little bit extra could really mess things up. I tend to use a small array and a boolean alive variable in my bullet class. Of course, I have a tight reign over my bullets. If there was a lot more action going on on the screen, I''d consider using a std::vector or std::deque as already mentioned.

______________________________________________________________
The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ
MySite
______________________________________________________________

Share this post


Link to post
Share on other sites
starstriker1    245
In my game, I decided to declare all the bullets beforehand. I used a single global variable (could have been local, I guess) to keep track of them all. This variable, bulletcount, tells me how many bullets I have to process. Every time I need a new bullet, I initialize bullet[bulletcount+1].

Every loop, bullets[1] to bullets[bulletcount] are processed.

Every time I need a bullet destroyed, I use a routine that lowers all bullets above it in the list (bullet[5] becomes bullet[4] and so on) then decrease bulletcount. Some might call it inefficient and slow, but in the end I don''t think the slight slowdown really effects anything, since it only comes into play when the bullet is destroyed.

Hope that helps.

Share this post


Link to post
Share on other sites
Tron3k    660
quote:
Original post by starstriker1
Every time I need a bullet destroyed, I use a routine that lowers all bullets above it in the list (bullet[5] becomes bullet[4] and so on) then decrease bulletcount. Some might call it inefficient and slow, but in the end I don''t think the slight slowdown really effects anything, since it only comes into play when the bullet is destroyed.
That''s ridiculously inefficient. Let''s say you want to delete bullet[5]. Just set bullet[5] equal to the last bullet in the list and decrease the bullet count. In other words:

bullet[5] = bullet[bulletcount];
bulletcount--;

Share this post


Link to post
Share on other sites
CheeseWeaver    122
i'm hardly any authority on this matter, but i've been advised that new/delete is kind of slow, and that allocating/deallocating memory on the fly as each bullet is fired/destroyed might not be the most efficient way to do it performancewise.

personally i handle it like the particles in my particle system, i initialize a rather big buffer with bullets, that are either live==true or live==false. each frame i loop the buffer until currentbulletnum is reached and blit all that are (live). when i need to add a new bullet the buffer is searched until an instance with live==false is found. (which is initialized and live=true, obviously.)
not sure whether this is a good solution.

i suppose it depends on the situation, allocating memory on the fly for each bullet might not be a problem with muzzleloaders, but might get tricky when dealing with MG42's or GAU-8's.

edit: stupid typo

[edited by - CheeseWeaver on August 17, 2003 1:17:27 PM]

Share this post


Link to post
Share on other sites