0
\$\begingroup\$

I have a pretty simple game engine that I'm making for a 2d platformer game. I don't want it to be super advanced, but it does have some basic properties. Most important to this question is a class called Entity. Entities are basically just objects in the game that are drawn to the screen and move around. They all have a square bounding box aroud them. Each different entity inherits from the class Entity (ex. Player and Ground inherit from Entity).

I want a nice, object oriented way to handle collisions between different entities. I'd like to be able to write rules of what happens when two things collide in such a way that I don't have to do a ton of casts or rewrite a lot of code. I was thinking of doing something like

class Entity {
    public:
        void collide(Entity* ent);
}

But I'm not sure how I would go about getting the type of the argument. Any suggestions on what to do?

\$\endgroup\$
4
  • \$\begingroup\$ I recommend registering callbacks/delegates/events/whatevs with the particular physics actor that is being simulated each frame. Separate the simulation and collision detection code from the game code itself, and trigger delegates when grabbing the results of the simulation. Or, raise a flag & set collision data during the results fetch, and let the actor branch based on the flag during their normal tick sequence. \$\endgroup\$
    – Evan
    Feb 24, 2014 at 1:07
  • \$\begingroup\$ Would you mind expanding on this a little more? I'm still new to this, so I'm not really sure how to implement these callbacks. \$\endgroup\$ Feb 24, 2014 at 6:02
  • \$\begingroup\$ While there are third party libraries that implement this functionality, and I'm sure a thousand different ways to do it, these are the ways I would recommend. You can implement the concept of delegates via C++ functors, std::function, or function pointers. The note here though, is that the behavior I describe has nothing to do with actually detecting the collisions, but rather dispatching based on the results of a collision. \$\endgroup\$
    – Evan
    Feb 24, 2014 at 14:21
  • \$\begingroup\$ Since your question says you are looking for an OO way to handle what happens when a collision occurs, this is the information I gave. Specific designs for the collision detection portion of a physics simulation is a broader topic, that is well documented across the internet. \$\endgroup\$
    – Evan
    Feb 24, 2014 at 14:22

1 Answer 1

1
\$\begingroup\$

It sounds to me like you could make use of a 2D jump table. The idea is to store the identity of each entity as an integer, and use this ID to index into a virtual table of function calls.

class Entity
{
  enum Type
  {
    eAABB,
    eCircle,
    ePolygon
  };

  Type type;
};

bool AABBtoAABB( Entity *a, Entity *b )
{
  AABB *A = (AABB *)a;
  AABB *B = (AABB *)b;

  // ...
}

bool AABBtoCircle( Entity *a, Entity *b );
bool AABBtoPolygon( Entity *a, Entity *b );
bool CircletoCircle( Entity *a, Entity *b );
bool CircletoAABB( Entity *a, Entity *b );
bool CircletoPolygon( Entity *a, Entity *b );
// ...

CollideArray[][] = {
  AABBtoAABB, AABBtoCircle, AABBtoPolygon,
  CircletoCircle, CircletoAABB, CircletoPolygon,
  // ...
};

bool Collide( Entity *a, Entity *b )
{
  return CollideArray[a->type][b->type]( a, b );
}

This style makes you code an N^2 number of functions, where N is the number of different entity types that participate. However some of the entries are just duplicates where the two types are swapped.

This is pretty implementation dynamic dispatch for multiple types, as opposed to how standard C++ often is implemented with a single dimensional jump table for the virtual keyword.

\$\endgroup\$
3
  • \$\begingroup\$ Hmm, that's an interesting idea. My only problem is that this could get a little unwieldy if it ever gets very large (which it most likely will). Plus it seems like a bad idea to have a member designating the type of entity it is. It kind of defeats the 'is a' relationship between Entity and it's derived class. \$\endgroup\$ Feb 24, 2014 at 2:08
  • \$\begingroup\$ @mrobinson7627 As far as collision detection goes, this is how it's done (at least as far as fundamentals go). For more game-logicy stuff you should probably not be using inheritance to dictate your code flow. \$\endgroup\$
    – RandyGaul
    Feb 24, 2014 at 2:41
  • \$\begingroup\$ However some of the entries are just duplicates where the two types are swapped. How about using a bitmask with up to two bits set per collision pair rather than a two dimensional array, that might be tricky to use? Of course, this limits the number of different shapes, but should be sufficient. \$\endgroup\$
    – Mario
    Feb 24, 2014 at 10:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .