@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
95 lines (76 loc) • 2.29 kB
JavaScript
/**
*
* @param {Vector2[]} forces
* @param {Array.<AABB2>} boxes
* @returns {number}
*/
export function resolveBoxOverlapUsingForce(forces, boxes) {
const numBoxes = boxes.length;
// initialize forces
for (let i = 0; i < numBoxes; i++) {
const f = forces[i];
f.set(0, 0);
}
let moves = 0;
for (let i = 0; i < numBoxes - 1; i++) {
const b0 = boxes[i];
const r1Right = b0.x1;
const r1Bottom = b0.y1;
for (let j = i + 1; j < numBoxes; j++) {
const b1 = boxes[j];
//compute overlap
const left = r1Right - b1.x0;
if (left < 0) {
//no overlap
continue;
}
const right = b1.x1 - b0.x0;
if (right < 0) {
//no overlap
continue;
}
const top = r1Bottom - b1.y0;
if (top < 0) {
//no overlap
continue;
}
const bottom = b1.y1 - b0.y0;
if (bottom < 0) {
//no overlap
continue;
}
//pick the smallest overlap value
let dX = left < right ? -left : right;
let dY = top < bottom ? -top : bottom;
//pick smallest axis
if (Math.abs(dX) < Math.abs(dY)) {
dY = 0;
} else {
dX = 0;
}
const f1 = forces[i];
const f2 = forces[j];
//apply separation
if (b0.locked === true && b1.locked === true) {
continue;
} else if (b0.locked === true) {
f2._sub(dX, dY);
} else if (b1.locked === true) {
f1._add(dX, dY);
} else {
f1._add(dX*0.5, dY*0.5);
f2._sub(dX*0.5, dY*0.5);
}
moves++;
}
}
//apply forces
for (let i = 0; i < numBoxes; i++) {
const box = boxes[i];
const force = forces[i];
const dX = force.x;
const dY = force.y;
box.move(dX, dY);
}
return moves;
}