Collision detection and correction (Again, Javascript, not Java)

Hey folks,

This is Javascript <— For those that doesn’t read the title all the way through

So I’ve got a working method for detecting collisions and it’s working pretty good™, though the position correction causes weird artifacts, such as:

  • When falling near a wall, you can “walk” towards it, and thus cling to it
  • Walking over an edge and quickly walking the other direction brings you back on top of the platform(sometimes with a little jump).

Here’s the code for collision detection:

var CollisionManager = {};

/**
 * Axis-Aligned Bounding Box collision test
 * @returns {Boolean} Whether there was a collision or not
 */
CollisionManager.boolAABB = function(a, b) {
    if(Math.abs(a.position.x - b.position.x) >= (Math.abs(a.width) + Math.abs(b.width)) / 2) {
        return false;
    }
    if(Math.abs(a.position.y - b.position.y) >= (Math.abs(a.height) + Math.abs(b.height)) / 2) {
        return false;
    }

    return true;
};

/**
 * Axis-Aligned Bounding Box collision test
 * @returns {Boolean|null} The direction of the collision or undefined if no collision
 */
CollisionManager.AABB = function(a, b) {
    if(!CollisionManager.boolAABB(a, b)) {
        return;
    }

    // x and y distances from the center
    var xd = Math.abs(a.position.x - b.position.x);
    var yd = Math.abs(a.position.y - b.position.y);

    // The minimum width to be seperated
    var cw = (Math.abs(a.width) + Math.abs(b.width)) / 2;
    var ch = (Math.abs(a.height) + Math.abs(b.height)) / 2;

    // Amount of overlap
    var ox = Math.abs(xd - cw);
    var oy = Math.abs(yd - ch);

    // Direction of the collision
    var dir = new Vec2D(a.x, a.y);
    dir = dir.sub(b);
    dir = dir.normalize();

    if(ox > oy) {
        return new Vec2D(0, dir.y * oy);
    } else if(ox < oy) {
        return new Vec2D(dir.x * ox, 0);
    }

    return new Vec2D(dir.x * ox, dir.y * oy);
};

So, if there is a collision, it’ll give me the direction and distance to move my object to get out of the collision.

Here’s the code that tries to move my player:


function tryToMove(d) { // d the velocity vector, divided into steps
    move(d);
    for(var i = 0; i < adventure.entities.length; i++) {
        var entity = adventure.entities[i];
        if(entity.isPassable === true) {
            continue;
        }

        var dv = CollisionManager.AABB(_this, entity);
        if(dv !== undefined) {
            entity.hit(dv);
            move(dv); // Move back out of the collision
        }
    }
}

And the bit that cuts the velocity vector and calls tryToMove():


var steps = Math.max(Math.abs(this.velocity.x), Math.abs(this.velocity.y));
var distance = this.velocity.div(steps);

for(var i = 0; i < steps; i++) {
    tryToMove(distance);
}

Sooo, any thoughts on how to fix the above issues?

Cheers! :slight_smile: