Advice On Handling Collisions

Started by
3 comments, last by furiousuk 17 years, 10 months ago
I know this is ANOTHER collisions post but... I'm wanting advice on the best way to handle a collision between two objects (called Entities). All of the entities in my game world are stored in a list, as CEntities. My EntityManager class can ascertain which two entities have collided with each other but I'm wanting to know the best way to handle what happens next. I can apply forces to my entities to give them new velocities and this is fine but all of my entities are infact derived classes. For the sake of an example, whats the best way of handling the collision between a projectile (CProjectile) and a vehicle (CVehicle). The behaviour I want it for the projectile to explode, the vehicle to take damage the vehicle to have a slight force applied to it from the impact. The best way I can think of is casting the entities back to their derived form and then handling the data from there i.e. if objectA is projectile and objectB is vehicle then handle. But surely, as the amount of derived classes increases, the amount of possible combinations of colliding objects will become larger and eventually unmanageable. I have other basic ideas but am struggling to flesh them out so they'll work correctly. Somebody must know how to do this? It seems like a stock problem.
Advertisement
Why do you need to cast your Entities back to the derived (parent class) form?
Can't you just use Virtual Functions for the collision response handler?

Why do different combinations of collision entities need to be handled differently? Can't you simply take all collisions in terms of relative object size and momentum (ignore entity subtype); then calculate damage and impulse on that basis alone?

If you insist on specific different responces based on different combos, what makes it become 'unmanageable' in the future? Couldnt you just do a n^2 size combo table to lookup responces?
What I'm worried about is the different data stored in each derived class. A CBullet class would have a damage factor and a damage type variable but there is no need for a CAsteroid class to have these data members as they aren't designed to be offensive weapons so if a bullet collides with a ship then fine, just look up the damage factor and assign it but what if an asteroid collides with the ship, if I try and look up a damage factor that doesnt exist then i'll come unstuck.

A table of entries looks like a good idea, but again, won't this require carrying around a variable within the base CEntity class that tells the program what derived class it is? I guess there's nothing wrong with doing that but its doesn't feel entirely polymorphic somehow. Maybe I'm just being vain.
Double dispatch is common and interesting way to handle collisions (and a good term to google for to get more information), take a look at this snippit:

//Base class for all collidable objectsclass Entity{    virtual void DoCollision (Entity& object) = 0;    virtual void CollideWith (Vehicle& object) = 0;    virtual void CollideWith (Asteroid& object) = 0;    virtual void CollideWith (Bullet& object) = 0;};class Vehicle : public Entity{    //Double dispatch the process    void DoCollision (Entity& object)    {        object.CollideWith(*this);    }    //Two cars crashing    void CollideWith (Vehicle& object)    {        this->Crash();        object.Crash();        AddSparks();    }    //Asteroid hits a car    void CollideWith (Asteroid& object)    {        this->Dent();        object.Destroy();        AddFire();    }    //Bullet hits a car    void CollideWith (Bullet& object)    {        this->Damage(object.GetDamageModifier());        object.Ricochet();    }};class Asteroid : public Entity{    //Double dispatch the process    void DoCollision (Entity& object)    {        object->CollideWith(*this);    }    //Asteroid hits a car    void CollideWith (Vehicle& object)    {        //Can either do:        object.CollideWith(*this);   //Let the vehicle handle the collision        //or do similar collision code again here:        object.Dent();        this->Destroy();        AddFire();    }    /*         Implement other collision routines    */};void PerformCollision(){   Entity* first_entity;   Entity* second_entity;    //for each colliding entity pair in collision list        first_entity->DoCollision(*second_entity);}


Hopefully you can see how that works.
Basically the entities handle collision between themselves and the different types of collision are handled in separate methods rather than one huge switch statement or if/else nest. This makes it easier to manage new entity types and avoids any nasty casting or RTTI.

Ideally you would have a more complex hierarchy (or use an aggregation system but thats another story). A hierarchy that separates entities into behavioural concepts such as 'projectiles, characters, vehicles, etc' would be better than 'bullet, car, truck, asteroid, etc' and would simplify writting collision code.

[Edited by - dmatter on June 10, 2006 11:40:18 AM]
I love that double dispatch idea, very neat and effective, also very extensible.

Cheers muchly

This topic is closed to new replies.

Advertisement