|
Collision detection and multiple inheritence |
23yrold3yrold
Member #1,134
March 2001
|
Okay. Here's the deal; some objects in my game have different manners for detecting collision than others. Right now everything's a bounding box, but for the next iteration of this game engine I need 3D. I might throw in bounding spheres later too, but anyway. Now, here's an idea of my current class hierarchy: BaseClass |----------------------------->GameEntity | |-->Player |--->GamePlatform |-->Enemy | |-->SpritePlatform |-->EnemyType1 | |-->3DVectorBasedPlatform |-->EnemyType2 | |-->Tilemap |-->etc. | |-->ParticleSystem |-->etc. Now some of these objects (like SpritePlatforms, some enemies and particles, and maybe the player) can and are represented by sprites using my 2D animation class, which carries the bounding box data with it. This 2D animation storage is currently built into the base class. Some of the objects I would like to represent using 3D polygons and rotatable bounding polys, which I can't do right now. Here's a system I thought of: remove the animation system from BaseClass. In fact, remove all the graphics and collision handling code from all those objects! Mua ha ha ha ha ha! In its place, I would create (in this case) two classes for handling this stuff; one would be a C2DObject with the current sprites and boxes, and the other would be a C3DObject with 3D model and animation data, and whatever I decide is a good method for checking collision detection. Obviously, 2D objects can collide with 3D ones (this being a 2D game engine, that's easy ). So now here's the wild idea; I would declare some of those classes above in this manner now: class SpritePlatform: public Platform, public C2DObject class VectorBasedPlatform: public Platform, public C3DObject class EnemyType1: public GameEntity, public C2DObject class EnemyType2: public GameEntity, public C3DObject And now, when two objects get in each other's personal elbow space, the game can check the object type and call the correct collision detection code. In fact, I may have to check this since I've never done it, but I could probably just make some overloaded collision functions that take pointers to C2DObject's and C3DObject's, and then just call those functions with wild abandon since the right function would get called by the object's type! I'm giddy just thinking of it! Any thoughts? Just brainstorming here, but it sounds pretty solid to me ... EDIT: C'mon, relevant posts >_< I'm trying to keep this forum alive, dammit ... we can go OT around post 50, I promise ... -- |
Thomas Fjellstrom
Member #476
June 2000
|
I thought basing you layout on one main "base" class was a no-no... Well, what do I know. -- |
damage
Member #3,438
April 2003
|
Nice ascii graphics there. Leaves Visio for dead I actually developed a sector-map template which uses nifty template stuff to make collision detection generic . It's probably not the best choice for a platformer, but I'm hoping to use it in a 2D strategy game one day. but I could probably just make some overloaded collision functions that take pointers to C2DObject's and C3DObject's, and then just call those functions with wild abandon since the right function would get called by the object's type! Unfortunately, overloaded functions don't work that way. Overloaded functions are resolved at compile-time, so they don't perform run-time type checking. There's no elegant (read: symmetric) way to do collision detection really. But a new idea in C++ (but an old idea in other languages) is "multimethods" which are like virtual functions but they are related to two or more classes instead of just one. Collision detection is a perfect application for them, realy. ____ |
X-G
Member #856
December 2000
|
I'm thinking more along the lines of aggregating bounding box types ... You could implement something like a bounding box handler with a base class and two children; one for 2D collision and one for 3D collision. Make it like a functor if you want. Then keep a pointer in a base class like CCollidable and some handy functions for setting the collision type. Would allow for fast and easy switching between collision types without cluttering it up with extra classes you can't multiple-inherit from ... plus you could easily have box detection for some enemies, and then quickly change to pixel-based without having to mess with all the classes - just change the collision type to C2DPixel (or whatever you call it). Just an idea ... -- |
23yrold3yrold
Member #1,134
March 2001
|
The idea behind the multiple inheritence is that some enemies need this 2D functionality, and some need the 3D functionality. I can add both to the base class so all cases are covered (yuck) or I can add them to the later base classes (still not so great) or I can just make classes out of them and have whatever inherit their properties (yay!) I think it's the better idea, and it lets me call collision detection functions by type to boot. damage: I'll look into that "multimethods" thing; someone is encouraged to post a good link if they know one ... -- |
X-G
Member #856
December 2000
|
What about my aggregation suggestion? A pointer to a CBaseCollisionHandler in the base class doesn't do much harm ... -- |
23yrold3yrold
Member #1,134
March 2001
|
Well if two objects have a pointer to a function for handling collision detection, which one gets called? Maybe be more specific, not sure I get you ... -- |
X-G
Member #856
December 2000
|
Not to a function - to an object. And it shouldn't matter which one gets called - if object A and B collide, both A.collidesWith(B) and B.collidesWith(A) should be true. -- |
23yrold3yrold
Member #1,134
March 2001
|
Right now I only use one collision check. If the player punches an enemy, the enemy is informed that it has been hit and the player is informed that it has hit something. So it's not just general collision; I have Hit_By and Has_Hit functions. -- |
X-G
Member #856
December 2000
|
But it's not really just collision detection, is it? How do you know if the enemy rushed into your fist or you actually punched it? -- |
23yrold3yrold
Member #1,134
March 2001
|
The active "fist" bounding box is only present during the punch animation -- |
X-G
Member #856
December 2000
|
There you go - if the monster collides with something that classifies itself as such a bounding box, let it do nothing, and let that entity call GetsHit and HasHit as appropriate. -- |
Korval
Member #1,538
September 2001
|
Really, C++ inhieritance is a bad idea for a generic collision system. The fundamental problem is that the collision function needs access to the private members of both objects, as well as some understanding of how to collide the two objects together. Rather than take a C++ approach, you should take a C approach. Construct a table. For each type of collision primitive, there is both a row and a column. Each collidable object type (box, sphere, etc) is derived from the same base class; that class only implements a GetType function. Then, someone registers a collision function between two of these primitives (say, sphere and box). When given collidable objects, all you need to do to collide them is get the types, look them up in the table, and call that function. |
23yrold3yrold
Member #1,134
March 2001
|
The table idea already occured to me; I just didn't feel like doing that for only four possible collision scenarios But I can work that in; those functions can be friends. I'm going to write a little demo to see if I can get that working; thanks. -- |
|