0
\$\begingroup\$

I'm thinking about how I should manage collisions in my game. I'm thinking about having a "Collision" class that checks for collision, and in case takes actions to resolve them.

My problem is this:

A and B moving to the other, when they collide they must bounce.

If I resolve the collisions sequentially, like calling:

  1. A.collideWith(B)
  2. B.collidesWith(A)

B will be stuck, because A has already updated his velocity and position, and when will be called B.collideWith(A) there won't be any collision anymore.

So, is it a good idea to use a double buffer pattern?

I'll write the values obtained by the collision resolver in some variables, they will be swapped to the real ones when all the collision has been resolved. In that way all should work fine.

But it is a good software design?

EDIT

I see, yes of course i check only for half. So there should be a class that checks for collisions, and should be like:

checkedpairs.clear();
for( Object a : objects )
{
    for( Object b : objects )
    {
        if( ! a.collideWith( b ) || checkedpairs.contains( a, b ) ) return;

        Object a1 = copyf( a );
        Object b1 = copyOf( b );

        a.collideWith( b1 );
        b.collideWith( a1 );

        checkedpairs.add( a, b );
    }
}

Instead of putting the logic for the swap in the objects themselves...

But that way, I'm creating two objects for each collision, isn't too much overhead?

The problem is that I don't need only the position, but al lot of physics stuff like velocity, acceleration, mass... Should I pass them? Isn't it too hard-coded?

\$\endgroup\$
  • \$\begingroup\$ What you're example is showing is more like no buffering. Single buffering would be fine, just store a cache of collisions, resolve them into a temporary velocity buffer, and then copy that buffer back to your objects. \$\endgroup\$ – BWG Feb 16 '15 at 14:43
1
\$\begingroup\$

Yeah, it's not necessary. When you detect a collision between A & B you should do something like:

if (detectCollision(A, B)) {
  A.resolveCollision(B);
  B.resolveCollision(A);
}

This may not be how you do it, but you get the idea!
If it is a problem that A has had it's values changed after resolving collision with B you could store the variables before calling A's resolve method and then pass them as arguments into B's resolve method.

\$\endgroup\$
  • \$\begingroup\$ you could also expand the detectcollision with a collisionresultobject that stores the relevant info. Like collisionresult cr = detectcollision(A,B); if (cr.collisionoccured){A.resolveCollision(cr);B.resolveCollision(cr);} The collisionresult would contain relevant info on each of the collided objects such as velocity and even the point where collision occured. \$\endgroup\$ – Felsir Dec 15 '15 at 10:48
0
\$\begingroup\$

If A.collidesWith(B) then you don't need to check B.collidesWith(A). You only need to check for half of the collisions.

If you have 3 objects A,B,C you only need to check collisions of

  • A & B
  • A & C
  • B & C

You should have a separate pass that checks collisions and calls both A and B's collision callback if a collision has occurred with a copy of A and B's positions before adjustments.

In some cases you can avoid buffering the state of all objects this way.

\$\endgroup\$

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.