2
\$\begingroup\$

I've got a collision response/resolution function that does the same for any pair of two entities. It's is in the World class right now.

But right before that function is invoked, I have some entity-specific logic:

  1. A specific pair of entities should never have their collisions resolved (this is literally to keep the player from hitting itself with a carried object)
  2. When two specific entities collide, an event should be triggered

Because of this, I'm starting to wonder if I should move the collision resolution function as a method into Entity, that'd allow me to use polymorphism. However, this sound very messy to me: If both entities involved in a collision can resolve it, how can I figure out which one should do it?

Is there another way to move these special cases out of World?

\$\endgroup\$
  • \$\begingroup\$ I would move this entire system into PhysicsEngine and let World be just the data storage & IO. Regardless, perhaps you could create a CollisionCallback class store a multi-map indexed by canonical pairs of entities. \$\endgroup\$ – MickLH Feb 3 '14 at 14:59
3
\$\begingroup\$

What you need is a separation of the collision resolution and specific logic steps, so the collision process is broken up into three separate steps, each of which is well-defined. Here's a simple diagram to show how it would work:

                    Contacts         Reduced Contacts
Collision Detection -------> [Logic] ---------------> Collision Resolution

So really, you now have a collision pipeline, with two fixed-function steps (detection and resolution) and a programmable step (logic). First, the collision detection step takes a set of entities and spits out a set of collision contacts. The entity-specific logic removes contacts that should not be applied, and reacts accordingly to contacts that should be. Finally, the collisions are resolved.

Instead of calling two virtual methods for each contact pair, I'd build a table mapping predicates and events to a pair of collision types (which are stored in the contact data). For example, if you wanted to have an item that disabled collisions between the player and certain walls, you could add a predicate to the table that always returned False (destroying the contact in the process) for contacts between Players and PassThroughWalls. If you needed it, adding scripting support to this contact modification table would be quite easy.

\$\endgroup\$
  • \$\begingroup\$ I ended up doing something similar to what you suggest, however, the most important part of this answer is that collision detection and resolution are not entity-specific, just the logic between the two. That's what I ended up with, and it's as flexible as I need it to be. \$\endgroup\$ – futlib Feb 4 '14 at 22:15

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.