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!