0

This is with respect to a physics engine. Once a collision occurs, it returns me the information that two gameObjects are colliding. All entities, like player, monster, bullet etc are derived (inherit) from GameObject.

What is a good way to identify which specific gameObjects are colliding ?

Enums: I have thought about using enums, but as soon as you start adding more entities, it becomes un-manageable to keep a track of all the possible combinations.

EDIT: I found a potential solution here for C#: http://blogs.msdn.com/b/laurionb/archive/2009/08/13/multimethods-in-c-4-0-with-dynamic.aspx

But still, if I have to do this in C++, how would I do it ?

brainydexter
  • 19,826
  • 28
  • 77
  • 115
  • well, I am right now doing this in c#, but eventually, I will port it over to c++, so I can use that across different platforms. – brainydexter Jan 30 '11 at 01:01

1 Answers1

1

The typical solution is to do two levels of dispatch like this:

class Thing
{
    public abstract void Collide(Thing other);
    public abstract void CollideWithSpaceship(Spaceship spaceship);
    public abstract void CollideWithAsteroid(Asteroid asteroid);
};

class Spaceship : Thing
{
    public override void Collide(Thing other) {
        other.CollideWithSpaceship(this);
    }

    public abstract void CollideWithSpaceship(Spaceship spaceship)
    {
        // Handle Spaceship -> Spaceship collision...
    }

    public abstract void CollideWithAsteroid(Asteroid asteroid)
    {
        // Handle Spaceship -> Asteroid collision...
    }
}

class Asteroid : Thing
{
    public override void Collide(Thing other) {
        other.CollideWithAsteroid(this);
    }

    public abstract void CollideWithSpaceship(Spaceship spaceship)
    {
        // Handle Asteroid -> Spaceship collision...
    }

    public abstract void CollideWithAsteroid(Asteroid asteroid)
    {
        // Handle Asteroid -> Asteroid collision...
    }
}

It gets a bit cumbersome as the number of different classes goes up, but it has some things going for it:

  1. It's fast. It relies on the language's built in dynamic dispatch which is pretty well optimized.
  2. It's typesafe. You'll note there's no casting going on.

The downside is:

  1. It isn't open-ended to extension. Adding a new class requires you to touch all of the others.

A more extensible solution is to build a 2D dispatch table where each cell indentifies a pair of colliding classes. In each cell, you put a function that handles collision between those two class types. That works well too, but it cheats the type system a bit. You'll end up doing some casting and you'll have to come up with a good way to identify a class.

I would not use C#'s dynamic support. My strong hunch is that it will be too slow for a physics engine.

I'll also point out that there's a Game Development Stack Exchange that's much better at answering questions like this. See you there!

Community
  • 1
  • 1
munificent
  • 11,946
  • 2
  • 38
  • 55
  • Isn't this similar to the visitor pattern ? I read about this and dynamic dispatch in the more effective book. But, thanks for such an elaborate reply. As you mentioned, I didn't like cheating the type system on the dispatch table. I'm still searching for a solution, where I wouldn't have to re-compile everything if I add a new class and also, add all the corresponding functions to complete the cartesian product of relations between entities. – brainydexter Feb 05 '11 at 08:21
  • Also, I'm curios to learn how the dynamic system works in the background to resolve objects and map correctly to the right function call with the right argument-type. – brainydexter Feb 05 '11 at 08:22
  • It's very similar to the visitor pattern. It's basically a visitor folded in on itself where the class being visited and doing the visiting is the same class (`Thing`). In other visitor implementations, this isn't always the case. – munificent Feb 05 '11 at 17:07
  • If you're interested in multimethods, take a look at CLOS, the object system in Common Lisp. That's the most well-known multimethod language. – munificent Feb 05 '11 at 17:08