Skip to main content
GameDev.net gamedev.net
🔒 Locked

Code design problem, OOP(?)

Started by BauerGL Aug 10, 2002 at 7:07 AM 4 replies 400+ views
Original Post
BauerGL
BauerGL
Hi I''ve been working on this 3D Raptor wannabe, except it''s not going to be anything as good as the original, but it might turn up kinda good. But now I have a code design problem which mainly consists of inheritance and the like. The classes involved are theese: CNode - a linked list class CModel - a model class for loading/displaying/animating MD2 models CObject - member vars position, velocity, some functions for Updating/Rendering/Collision Detection etc. CTerrain - a class for loading and displaying a terrain using either a heightmap or rand height values Right now the inheritance looks like this: CNode | CModel - this is kinda useless cause CModel don''t need CNode | CObject - need CModel for calculating bounding box, and CNode for game object hierarchy | CTerrain - needs the functions from CObject and also needs to be a CNode because the terrain is to be the game world parentobject. But it doesn''t need anything from CModel so some memory will be unused. I also have a CPlayer/CEnemy/CBullet derived from CObject and they are all MD2 models. I know that I can inherit both CNode and CModel directly into CObject, but the problem with CTerrain still remains. So the question is, should I go with this and just forget the memory being unused and that the code may look like sh*t? Or have you got a better way? Please come with tips/advices cause I really think this is an interesting side of programming. My site, My work, My thrashcan.
@mikaelbauer Super Sportmatchen - A retro multiplayer competitive sports game project!
nicba
nicba
Another problem with your proposed hierachy is that you would have many simultaneous intances of CBullet & CEnemy in your game. But even though you have a hundred bullets and ten enemy spaceships at once, you would only want to load one bullet MD2 model and one enemy spaceship MD2 model (assumed that all the enemies are the same type, of course).

I Would suggest that you make two hierachies instead:


      
CNode
|
CObject
_______|_______
| | |
CTerrain CBullet CEnamy ....


...and:


      
CModelManager
|
CModel


The CModelManager class would be a container for all the loaded MD2 models in the game. There would only be one instance of CModelManager in the game, ever. But as many as you need of CModel.

When you need to create a new object in the game, for example a bullet, the constructor for CBullet would then query the CModelManager for a bullet model. The CModelManager would then search its collections of models for the right model type and return a pointer to it to the newly created CBullet class. CBullet would then store the pointer in a private member variable

(if no bullet model was loaded yet, CModelManager would load first create a new CModel, load it into the CModel class and add it to the collection).

This way, MD2 models would only be loaded and stored once in your game. Furthermore the only memory lost in CTerrain would be the memory to hold a single pointer.

Even that could be avoided by either moving the physics calculation routines up into CNode and make CTerrain inherit directly from here (but that's not very intuitive). Or by re-arranging the hierachy to something like this:


  
CNode
|
CPhysicsObj
| |
CTerrain CGameObject
_______|_______
| | |
CBullet CEnemy CPlayer


This is a little more intuitive. The CPhysicsObj class would hold the physics-related methods shared by both the terrain and the "game object" classes (the old CObject). I'm not sure I would do it this way, however. I actually think I would chose the first hierachy I proposed instead. It's simpler, and since you would most likely have only one terrain in your game, the lose of memory for one unused pointer wouldn't matter a bit anyway. The more complex hierachy with the CPhysics node would quickly grow in depth as you added more enemy types (inheriting CEnamy), more bullet types (inheriting CBullet) ect.

Regards

Nicolai

[edited by - nicba on August 10, 2002 10:25:32 AM]

[edited by - nicba on August 10, 2002 10:31:38 AM]
BauerGL
BauerGL
Wow! Thanks a billion million times for that advice! I'll definetely try that first method with CModelManager etc, it seems really cool.

Just one thing, the CObject class needed the CModel class to calculate the bounding box.. but I guess I could do that in CPlayer/CBullet etc.. or I could do it in the CModel class.

Well anyway thanks alot!

My site, My work, My thrashcan.

[edited by - BauerGL on August 10, 2002 9:10:39 PM]
@mikaelbauer Super Sportmatchen - A retro multiplayer competitive sports game project!
AeroBLASTER
AeroBLASTER
you referring to raptor as in the classic DOS top-down scrolling shooter (hmm, that''s a bit long of a description... I suppose I could just say "fighter game"...)?

If so, how''s it going to work in 3d? You going to make it like an extremely ''arcade'' flight sim or something?

Sorry, just my curiousity getting the better of me :D
---DirectX gives me a headache.
Oluseyi
Oluseyi
Some of your classes don''t need to inherit from each other. If there is no common intrinsic property and only common process, then you might want to look into generic algorithms. For example, rather than having a pure "interface" class IDrawable that all visible object derive from and overload it''s Draw method, you could have a generic algorithm that calls Draw on each distinct class/object''s visible properties:

// DrawableObject is just an alias for whatever class is actually
// substituted at runtime
template <typename DrawableObject>
void DrawAll(const std::vector<DrawableObject> & d)
{
std::vector<DrawableObject>::iterator it, end;
it = d.begin(), end = d.end();
while(it != end)
Draw(it->GetSprite(), it->GetPosition()), ++it;
}
 
void Draw(const Sprite & s, const Position & p)
{
// draw sprite s at position p
}

Now all you class has to do is provide GetSprite and GetPosition methods to be usable by Draw, DrawAll or any other similar function. This cuts down on inheritance dependency and allows you to use composition instead. Using a system like this, your tangled web of CNodes and CModels suddenly becomes much cleaner.
BauerGL
BauerGL
Hehe wow Oluseyi, that looked... smooth Although I think it''s too hard/advanced for me right now. I can''t really see how it will work and interact with all objects etc.. But if you want to explain a bit more and give some examples as to how I would implement it I would be more than happy.

AeroBLASTER: Hmm well I''m sorry if I misslead you by saying Raptor, what I really meant was "top-down-fly-dodge-kinda-shooter". I just had Raptor as an example (since it rocks!) Oh and the view isn''t going to be top-down, it''s more like a little over the player and a little behind. So the player can see the depth of the ground and incoming enemies.
@mikaelbauer Super Sportmatchen - A retro multiplayer competitive sports game project!

Topic Locked

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

Sign in to reply to this topic.