views:

98

answers:

3

So my question is simple, and I guess it boils down to how anal you want to be about collision detection. To keep things simple, lets assume we're talking about 2D sprites defined by a bounding box. In addition, let's assume that my sprite object has a function to detect collisions like this: S.collidesWith(other); Finally the scene is moving and "walls" in the scene can move, an object may not touch a wall.

So a simple implementation might look like this (psuedo code):

moveWalls();
moveSprite();
foreach(wall as w) {
    if(s.collidesWith(w)) { 
        gameover();
    }
}

The problem with this is that if the sprite and wall move towards each other, depending on the circumstances (such as diagonal moment). They may pass though each other (unlikely but could happen).

So I may do this instead.

moveWalls();
foreach(wall as w) {
    if(s.collidesWith(w)) { 
        gameover();
    }
}
moveSprite();
foreach(wall as w) {
    if(s.collidesWith(w)) { 
        gameover();
    }
}

This takes care of the passing through each other issue, but another rare issue comes up. If they are adjacent to each other (literally the next pixel) and both the wall and the sprite are moving left, then I will get an invalid collision since the wall moves, checks for collision (hit) then the sprite is moved. Which seems unfair. In addition, to that, the redundant collision detection feels very inefficient. I could give the player movement priority alleviating the first issue but it is still checking twice.

moveSprite();
foreach(wall as w) {
    if(s.collidesWith(w)) { 
        gameover();
    }
}
moveWalls();
foreach(wall as w) {
    if(s.collidesWith(w)) { 
        gameover();
    }
}

Am I simply over thinking this issue, should this just be chalked up to "it'll happen rare enough that no one will care"? Certainly looking at old sprite based games, I often find situations where the collision detection has subtle flaws, but I figure by now we can do better :-P. What are people's thoughts?

A: 

This depends a lot on the frequency you use to check the collision (and the player's input device). When you check often, the case that both move 'at the same time' will become less likely. If it were a rounds-based strategy game, this would be a different question.

That said, I don't know, which model you're using in detail, but if you have one thread, that checks player input, and one that does the movement calculation and collision detection, then both will have to be synchronized (read/write locks) anyway. In that case, it's clear, what happened first. Same thing, if you're using just one thread.

Depending on the physics model, input could steer the acceleration, which would determine the speed, which in turn determines the position. If the line of the object's movement from the previous position to the (possible) next position crosses the wall's position at that time, you have a collision (taking into account the entire outlines that could collide).

The thing that's probably more difficult, is to calculate the effect of the bounce. I found that to be true when I wrote an OpenGL based game, where the walls can't move, but the floor can be tilted: When the bounce isn't strong enough to counter the acceleration against the wall, you'll still be inside the wall after the collision. After investing some effort, I think, it works pretty well (including rolling along the wall, which is yet another issue), but with moving walls, it's even a bit more difficult.

Chris Lercher
A: 

Actually it's even more complicated than you described. Even if the wall is not moving at all, but the sprite is moving fast it will get past the wall in single frame of animation. In this case you need to calculate path of the wall and path of the sprite between each frames an check if those vectors intersect. If they do then you check if there was a collision taking into account speed of both object's.

Michał Piaskowski
+2  A: 

Whether it is worth improving the accuracy is something we can't tell you, but should become evident during playtesting. As for increasing the reliability of your collision detection, you have several choices:

  1. Decrease the simulation step size. If stepsize * (player max velocity + wall max velocity) < (player width + wall width), you won't miss any collisions.
  2. Also check that the player is one the same side of the wall before and after the simulation step.
  3. Rather than only checking for collisions at the end of each simulation step, derive a formula that computes the time at which the wall and the player would collide given their current velocities, and flag a collision if that time is within the current simulation step. This if probably overkill in your case, but can be useful in modeling things such as bouncing off walls.
meriton