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\$
  • \$\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 '14 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\$ – mrobinson7627 Feb 24 '14 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 '14 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 '14 at 14:22
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\$
  • \$\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\$ – mrobinson7627 Feb 24 '14 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 '14 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 '14 at 10:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.