meh?2
This commit is contained in:
@@ -89,6 +89,7 @@ ctx.imageSmoothingEnabled = false;
|
|||||||
|
|
||||||
// player is an AABB (top-left corner + size)
|
// player is an AABB (top-left corner + size)
|
||||||
const player = { x: 40, y: 40, w: 12, h: 12 };
|
const player = { x: 40, y: 40, w: 12, h: 12 };
|
||||||
|
window.player = player;
|
||||||
|
|
||||||
// walls: a border plus a few interior blocks to slide against
|
// walls: a border plus a few interior blocks to slide against
|
||||||
const T = 8; // border thickness
|
const T = 8; // border thickness
|
||||||
@@ -101,7 +102,7 @@ const walls = [
|
|||||||
{ x: 0, y: H - T, w: W, h: T }, // bottom
|
{ x: 0, y: H - T, w: W, h: T }, // bottom
|
||||||
{ x: 0, y: 0, w: T, h: H }, // left
|
{ x: 0, y: 0, w: T, h: H }, // left
|
||||||
{ x: W - T, y: 0, w: T, h: H }, // right
|
{ x: W - T, y: 0, w: T, h: H }, // right
|
||||||
{ x: 150, y: 30, w: 16, h: 90 }, // a pillar
|
{ x: 144, y: 30, w: 12, h: 82 }, // a pillar
|
||||||
{ x: 96, y: 96, w: 60, h: 16 }, // a bar
|
{ x: 96, y: 96, w: 60, h: 16 }, // a bar
|
||||||
ledge,
|
ledge,
|
||||||
];
|
];
|
||||||
@@ -160,23 +161,56 @@ function penetrationVector(a, b) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function resolveOverlaps(box, walls) {
|
||||||
* moveAndSlide, but immune to the overlap trap: first push `box` out of any
|
const res = {
|
||||||
* wall it is already inside (plus an EPSILON of slack, same idea as the
|
x: box.x,
|
||||||
* backoff in the loop), THEN run the normal sweep loop from the safe spot.
|
y: box.y,
|
||||||
*
|
settled: true,
|
||||||
* Everything you need is penetrationVector above and given.ts.
|
};
|
||||||
*/
|
|
||||||
function safeMoveAndSlide(box, v, walls) {
|
const count = walls.length;
|
||||||
for (const wall of walls) {
|
let index = 0;
|
||||||
const pv = penetrationVector(box, wall);
|
let tries = 0;
|
||||||
|
|
||||||
|
while (index < count) {
|
||||||
|
const pv = penetrationVector(box, walls[index++]);
|
||||||
|
|
||||||
if (pv) {
|
if (pv) {
|
||||||
|
if (pv.x !== 0) {
|
||||||
box.x += pv.x > 0 ? pv.x + EPSILON : pv.x - EPSILON;
|
box.x += pv.x > 0 ? pv.x + EPSILON : pv.x - EPSILON;
|
||||||
|
}
|
||||||
|
if (pv.y !== 0) {
|
||||||
box.y += pv.y > 0 ? pv.y + EPSILON : pv.y - EPSILON;
|
box.y += pv.y > 0 ? pv.y + EPSILON : pv.y - EPSILON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res.x = box.x;
|
||||||
|
res.y = box.y;
|
||||||
|
res.settled = false;
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
tries += 1;
|
||||||
|
} else {
|
||||||
|
res.settled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tries > 7) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
function safeMoveAndSlide(box, v, walls) {
|
||||||
|
const res = resolveOverlaps(box, walls);
|
||||||
|
if (res.settled) {
|
||||||
return moveAndSlide(box, v, walls);
|
return moveAndSlide(box, v, walls);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: box.x,
|
||||||
|
y: box.y,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let then = performance.now();
|
let then = performance.now();
|
||||||
|
|||||||
Reference in New Issue
Block a user