resolving collisions

Apr 9, 2011 at 5:05pm
Hi all,

When making games in the past, I had stored pointers to base class entities in my world and to determine the type of entity when a collision occured I just gave each of my entites such as player, enemy, bullet etc. a type variable, represented by an enum.

This works but once you have a large number of types of entities you end up with a huge function with multiple switch statements in order to decide what to do when two entities collide, there must be a more elegant solution.

Any tips?
Danke x

EDIT - I forgot one thing, I know you can use dynamic_cast to solve this but I'm trying to avoid that since I'm working on GP2X and my code needs to be as fast as possible
Last edited on Apr 9, 2011 at 5:15pm
Apr 9, 2011 at 5:17pm
closed account (D80DSL3A)
Sounds like a good job for virtual functions. Are all colliding entities derived from a common base class? If so, write a custom onHit() for each one.
Apr 9, 2011 at 5:28pm
@fun2code

the problem is that what needs to happen to an entity when it collides depends on what it is colliding with, and we dont know the type of the entities as they're base class pointers.
Apr 9, 2011 at 5:39pm
Have a virtual (type of entity) function.

Or you could just have layers of collisions, that's what I'm doing =)
Apr 9, 2011 at 5:48pm
@ultifinitus

can you explain what you mean by layers of collision?
Apr 9, 2011 at 5:48pm
closed account (D80DSL3A)
How complex is a typical interaction? Could you give an example or two?
EDIT: When I use dynamic_cast I always feel like I'm working around a design flaw.
Last edited on Apr 9, 2011 at 5:49pm
Apr 9, 2011 at 6:05pm
@fun2code

the complexity doesn't matter, my point was that a single OnHit() function for each entity wouldn't work
Apr 9, 2011 at 6:26pm
closed account (D80DSL3A)
I realized that from your last response. I asked for an example so I could better picture the situation and maybe come up with an idea. Having been dismissed I'll leave it to your other respondents then. Good luck.
Apr 9, 2011 at 7:13pm
Sorry for my late response.

When I say layers of collision, I have a collision manager class that handles everything for me, all of my objects have simple properties, and when I declare them I have my manager add them into their queue to check for collisions. I have multiple managers, and when I want to have certain objects collide with certain other objects, but not with another set, I'll add them into separate managing instances. You can, of course, add an object to each manager.

The problem comes with your system in the fact that different objects react differently to different objects. While an ID would be fine, it would require a lot of hard coding. Perhaps you should have some simple properties, like BOUNCE STICK SLIDE SLOPEMOVE and things of that nature, so when the manager asks the object to respond to a situation, it can pass in the opposing object as immovable or whatever and the objects with virtual methods can then tell the manager how they intend to move. The manager can then resolve any conflicts.

overall
not a bad system, I've tried several methods of collision detection and resolution in the past, and this has been the best working system yet.

You have billions of permutations of options. If you need some other methods, I have tons.

edit: got rid of the dang "now"s
Last edited on Apr 9, 2011 at 8:21pm
Apr 9, 2011 at 7:16pm
@fun2code

well someone's on their period today aren't they, get out of your huff.

I've thought up a solution now anyway but thanks for the response untifinitus
Last edited on Apr 9, 2011 at 7:17pm
Apr 9, 2011 at 7:36pm
No problem, glad you came up with one. Just realized I said "now" like thrice in that thing.. Dang textual communication.
Apr 9, 2011 at 8:11pm
quirkyusername wrote:
the problem is that what needs to happen to an entity when it collides depends on what it is colliding with, and we dont know the type of the entities as they're base class pointers

Double dispatch to the rescue! -> http://www.cplusplus.com/forum/general/33296/#msg179194

EDIT:

I know this is solved, but I thought this option should be mentioned too.
Though, ultifinitus' way sounds more sophisticated...
And I'd like to know what your current solution looks like.
Last edited on Apr 9, 2011 at 8:17pm
Apr 9, 2011 at 9:15pm
I've made my derived entities inherit from another class as well as the base entity class, CollidableObject.

CollidableObject has a series of pure virtual methods, one that takes the base entity as an argument, and one for each other type of entity, like so:

1
2
3
4
virtual void ResolveCollision(CEntity&) = 0;
virtual void ResolveCollision(CPlayer&) = 0;
virtual void ResolveCollision(CEnemy&) = 0;
// ....and so on 


Consider the case where a player collides with an enemy, we call the overloaded method which
takes a base class entity, in this case this will be in the player class.

1
2
3
4
void CPlayer::ResolveCollision(CEntity& other)
{
    other.ResolveCollision(*this);
}


which would call CEnemy::ResolveSolution(CPlayer&)

it's perhaps a bit messy as you have to overload every one of the methods in every derived class, so you'll have CEnemy::ResolveCollison(CPlayer&) as well as CPlayer::ResolveCollision(CEnemy&) which is duplication of a method that does that the exact same thing, but it's simple.

EDIT - Your solution is impressive roshi, nice work. I'm not clever enough to come up with something like that

Last edited on Apr 9, 2011 at 9:20pm
Apr 9, 2011 at 9:45pm
By the way quirky. In your collision resolution, are you separating the axis?
what order are you checking collision with the objects around you?
Have you noticed any bugs?

@r0shi: I like your double dispatching stuff
Apr 9, 2011 at 10:17pm
@quirkyusername: Ah, right. This is the brute force approach to double dispatching.

quirkyusername wrote:
I'm not clever enough to come up with something like that

Neither am I; I copied most of it from a book xD

ultifinitus wrote:
I like your double dispatching stuff

Read Modern C++ Design ASAP, then!
Last edited on Apr 9, 2011 at 10:18pm
Apr 9, 2011 at 10:35pm
@ultifinitus

since I'm not far into the project there is currently no space partitioning, every object is checked against every other object every loop, but I'm going to implement a quad tree soon. No bugs yet, it's not all that complicated yet.
Topic archived. No new replies allowed.