Skip to main content
gamedev.net
🔒 Locked 🎮 Unity

Weapon/Ammo system

Started by mcguile25 5 replies 1.9k views
Original Post
mcguile25
mcguile25
Hi there. I am in the process of implementing a weapon/ammo system for my 3D game. I just wanted to ask some questions and give my thoughts about how I'm thinking of doing this. I want it to be as clean as possible. This is in C++. Any suggestions/advice is gladly welcome: 1) I'm going to have several types of weapons in the game, from simple pistols to machine guns, to grenades, to melee weapons like lead pipes, etc. So I was thinking of having a CWeapon base class for _all_ weapons. This class would have virtual functions for Fire(), Reload(), Shoot(), etc. Probably make this an abstract base class. Then, for each weapon, make a new class derived from CWeapon and implement the virtual functions and any specific data needed. Any comments on this design? Pretty self-explanatory, right? 2) Now also, different weapon types have different ammo types. Pistols have a simple bullet, while a grenade actually throws a grenade :), etc. So should I go the same route as above by having an abstract base class called CAmmo or something and derive a new specific class for each ammo type? 3) Lastly, and this is where I need the most advice. When the player shoots a pistol, for example, bullets go off into the distance. When the player throws a grenade, a grenade is launched into the world. Obviously, I have to alert the class that handles the map that there is a new bullet or grenade in the world. Who handles what here? Do I simply have a dynamic vector of bullets/grenades/whatever that are currently in the map? So in my pistol's shoot method, I would have to tell the map class to add a new bullet into the world? So then the map class probably loops over all active bullets/whatver and calls its Update() method? Thanks.
JohnBolton
JohnBolton
1. That sounds reasonable. However, be careful about creating classes whose only difference is data. For example, it would be wrong to have two pistol classes if the only difference between them was the type of ammo.

2. Same thing about the ammo. There is no need to have a 9 mm bullet class and a .38 calibur bullet class.

3. Yes. That's basically how you would do it. It depends on the behavior of the various types of ammo and guns. There also are things you can do to make it more efficient, if necessary.

I suggest you make the "map" class and the "world" class be two different things. The map describes the initial static objects and geometry in the world, but the world contains everything. It is created from the map (or perhaps contains the map).
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
pcwlai
pcwlai
To me, I will have the design like this from your way of thinking:

1. With the abstract base class defining all the possible functions of all the weapons. Even with the same weapon but can only use different bullets.

2. With the abstract base class defining all the possible functions of all the bullets. Which includes collision callbacks between different types of objects (base classes)

3. A main manager / loop for all the functions you need to perform on all types of objects currently in world (instantiated and inserted into the world objects list).

Another approach would be entirely data driven. With a large class that can perform every possible operations according to data. So, you just have 1 weapon class, 1 bullet class and 1 world manager.

The third option is to combine the 2 methods. Use classes for weapons and data driven for simular types of bullats as described by JohnBolton.

I personally will choose first method for cleaniness if simular types of bullets is not much. Otherwise, the third method.

For me, managing instances of objects is the best way. So, inserting every live objects into the world manager is my favourite. Then, perform all the possible combination of operations on all the living objects. Call there respective base functions on events.
The poorest programmer in the game industry!!
haphazardlynamed
haphazardlynamed
I'm going to toss this comment in, since I'm also having to deal with it...

For your dynamic bullet/grenade vector approach, consider if you have a weapon that is instantaneous instead of firing a projectile? For example a laser beam, rather than have it put a projectile into the world, it would be an instant line test...
How would you generalize that to also fit in the same weapon handling model?
mcguile25
mcguile25
haphazardlynamed -- good question :)

I'm not trying to avoid the question, but I wanted to bring up another topic of discussion here -- using new and delete in-game with the weapon class. Let's say I have an stl vector of Weapon class pointers. Whenever the player picks up a weapon in the game world, we have to add it to the player's inventory, most likely by creating a 'new' instance of CWeapon and sticking it into the back of the vector. Then we'd have to create the actual 3D model to display in the FPS view, etc from that weapon.

I'd rather not do all this at runtime for every weapon the player picks up. Seems like a lot of overhead to do new/delete when the player is duking it out in a match. Is there an approach I can take during initialization to avoid this?
BertS
BertS
Well simply load your weapon models/sounds at load of your level (ie check what items/weapons are needed while reading the map and load these). Each weapon stores only a pointer to the 3D mesh and not the mesh itself. That way you can have 20 guns in a level, but only need to load 1 mesh for them.
bnadland
bnadland
You don't have to do new's or delete's in the loop. For instance, you can have a vector with usable objects and link to them. So you just have to allocate the memory once on loading the map and deleting them afterwards.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.