Resolving bounding box collision detection

Posted by ndg on Game Development See other posts from Game Development or by ndg
Published on 2012-08-27T15:56:40Z Indexed on 2012/08/27 21:57 UTC
Read the original article Hit count: 246

I'm working on a simple collision detection and resolution method for a 2d tile-based bounding box system. Collision appears to work correctly, but I'm having issues with resolving a collision after it has happened.

Essentially what I'm attempting to do is very similar to this approach. The problem I'm experiencing is that because objects can be traveling with both horizontal and vertical velocity, my resolution code causes the object to jump incorrectly.

I've drawn the following annotation to explain my issue. In this example, because my object has both horizontal and vertical velocity, my object (which is heading upwards and collides with the bottom of a tile) has it's position altered twice:

  • To correctly adjust it's vertical position to be beneath the tile.
  • To incorrectly adjust it's horizontal position to be to the left of the tile.

Collision issue

Below is my collision/resolution code in full:

function intersects(x1, y1, w1, h1, x2, y2, w2, h2)
{
    w2 += x2;
    w1 += x1;
    if (x2 > w1 || x1 > w2) return false;
    h2 += y2;
    h1 += y1;
    if (y2 > h1 || y1 > h2) return false;
    return true;
}

for(var y = 0; y < this.game.level.tiles.length; y++)
{
    for(var x = 0; x < this.game.level.tiles[y].length; x++)
    {
        var tile = this.game.level.getTile(x, y);
        if(tile)
        {

            if(
                this.velocity.x > 0 &&
                intersects(this.position.x+dx+this.size.w, this.position.y+dy, 1, this.size.h, x*tileSize, y*tileSize, tileSize, tileSize)
            )
            {
                this.position.x = ((x*tileSize)-this.size.w);
                hitSomething = true;
                break;
            }
            else if(
                this.velocity.x < 0 &&
                intersects(this.position.x+dx, this.position.y+dy, 1, this.size.h, x*tileSize, y*tileSize, tileSize, tileSize)
            )
            {
                this.position.x = ((x*tileSize)+tileSize);
                hitSomething = true;
                break;
            }
            if(
                this.velocity.y > 0 &&
                intersects(this.position.x+dx, this.position.y+dy+this.size.h, this.size.w, 1, x*tileSize, y*tileSize, tileSize, tileSize)
            )
            {
                this.position.y = ((y*tileSize)-this.size.h);
                hitSomething = true;
                break;
            }
            else if(
                this.velocity.y < 0 &&
                intersects(this.position.x+dx, this.position.y+dy, this.size.w, 1, x*tileSize, y*tileSize, tileSize, tileSize)
            )
            {
                this.position.y = ((y*tileSize)+tileSize);
                hitSomething = true;
                break;
            }
        }
    }
}

if(hitSomething)
{
    this.velocity.x = this.velocity.y = 0;
    dx = dy = 0;

    this.setJumping(false);
}

© Game Development or respective owner

Related posts about 2d

Related posts about collision-detection