@@ -292,9 +292,6 @@ const map = (function(els) {
|
|||||||
let allStartingEdges;
|
let allStartingEdges;
|
||||||
init();
|
init();
|
||||||
|
|
||||||
const b = map.edges.map(({ edge }) => getEdgeCollisionBoundary(edge, shipRadius));
|
|
||||||
b.forEach(b => drawLine(b.xa, b.ya, b.xb, b.yb, "orange"));
|
|
||||||
|
|
||||||
function distance(x1, y1, x2, y2) {
|
function distance(x1, y1, x2, y2) {
|
||||||
return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
|
return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
|
||||||
}
|
}
|
||||||
@@ -543,28 +540,23 @@ function isLandable(edge) {
|
|||||||
// return Object.is(slope(edge), +0);
|
// return Object.is(slope(edge), +0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEdgeCollisionBoundary(edge, dist) {
|
function detectEdgeCollision([xc, yc], [x, y], radius) {
|
||||||
const { xa, ya, xb, yb } = edge;
|
|
||||||
const length = distance(xa, ya, xb, yb);
|
|
||||||
const rise = yb - ya;
|
|
||||||
const run = xb - xa;
|
|
||||||
|
|
||||||
const riol = rise / length * dist;
|
|
||||||
const ruol = run / length * dist;
|
|
||||||
|
|
||||||
return { xa: xa + riol, ya: ya - ruol, xb: xb + riol, yb: yb - ruol};
|
|
||||||
}
|
|
||||||
|
|
||||||
function detectEdgeCollision([xc, yc], [x, y], radius, gearDown = false) {
|
|
||||||
return ({ edge, wall }) => {
|
return ({ edge, wall }) => {
|
||||||
if (xc === x && yc === y) return;
|
if (xc === x && yc === y) return;
|
||||||
|
|
||||||
const dist = edge.x3 < edge.x4 && edge.y3 === edge.y4 && gearDown ? radius + 2 : radius;
|
const { xa, ya, xb, yb } = edge;
|
||||||
const edgeSeg = getEdgeCollisionBoundary(edge, dist);
|
const length = distance(xa, ya, xb, yb);
|
||||||
const positionSeg = { xa: x, ya: y, xb: xc, yb: yc };
|
const rise = yb - ya;
|
||||||
|
const run = xb - xa;
|
||||||
|
|
||||||
let { xa: x1, ya: y1, xb: x2, yb: y2 } = positionSeg;
|
const riol = rise / length * radius;
|
||||||
let { xa: x3, ya: y3, xb: x4, yb: y4 } = edgeSeg;
|
const ruol = run / length * radius;
|
||||||
|
|
||||||
|
const positionSeg = { xa: x, ya: y, xb: xc, yb: yc };
|
||||||
|
const edgeSeg = { xa: xa + riol, ya: ya - ruol, xb: xb + riol, yb: yb - ruol};
|
||||||
|
|
||||||
|
const { xa: x1, ya: y1, xb: x2, yb: y2 } = positionSeg;
|
||||||
|
const { xa: x3, ya: y3, xb: x4, yb: y4 } = edgeSeg;
|
||||||
|
|
||||||
// https://en.wikipedia.org/wiki/Intersection_(geometry)#Two_line_segments
|
// https://en.wikipedia.org/wiki/Intersection_(geometry)#Two_line_segments
|
||||||
// https://en.wikipedia.org/wiki/Cramer%27s_rule#Explicit_formulas_for_small_systems
|
// https://en.wikipedia.org/wiki/Cramer%27s_rule#Explicit_formulas_for_small_systems
|
||||||
@@ -626,12 +618,12 @@ function detectCornerCollision([xc, yc], [x, y], radius) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function detectCollision(currentPos, intendedPos, velocity, radius, { edges, corners }, gearDown) {
|
function detectCollision(currentPos, intendedPos, velocity, radius, { edges, corners }) {
|
||||||
const { x: xc, y: yc } = intendedPos;
|
const { x: xc, y: yc } = intendedPos;
|
||||||
const [x, y] = currentPos;
|
const [x, y] = currentPos;
|
||||||
// edges oriented clockwise with ship
|
// edges oriented clockwise with ship
|
||||||
const fwdEdges = getForwardEdges(edges, { x, y })
|
const fwdEdges = getForwardEdges(edges, { x, y })
|
||||||
const edgeColl = fwdEdges.find(detectEdgeCollision([xc, yc], [x, y], radius, gearDown));
|
const edgeColl = fwdEdges.find(detectEdgeCollision([xc, yc], [x, y], radius));
|
||||||
|
|
||||||
if (edgeColl) return edgeColl;
|
if (edgeColl) return edgeColl;
|
||||||
|
|
||||||
@@ -677,16 +669,12 @@ function cornerContactPosition(xc, yc, x, y, corner, cLength) {
|
|||||||
return intxnSeg.getPointAtLength(bLength);
|
return intxnSeg.getPointAtLength(bLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
function edgeContactPosition(xc, yc, x, y, edge, radius, gearDown) {
|
function edgeContactPosition(xc, yc, x, y, edge, radius) {
|
||||||
const baseSlope = slope(edge);
|
const baseSlope = slope(edge);
|
||||||
|
// if (Object.is(baseSlope, 0)) s.isLanded = true;
|
||||||
let { xa, ya, xb, yb } = edge;
|
let { xa, ya, xb, yb } = edge;
|
||||||
const positionSeg = { x1: x, y1: y, x2: xc, y2: yc };
|
const positionSeg = { x1: x, y1: y, x2: xc, y2: yc };
|
||||||
// const edgeSeg = { x1: xa, y1: ya, x2: xb, y2: yb };
|
const edgeSeg = { x1: xa, y1: ya, x2: xb, y2: yb };
|
||||||
const dist = isLandable(edge) && gearDown ? radius + 2 : radius;
|
|
||||||
const b = getEdgeCollisionBoundary(edge, dist);
|
|
||||||
const edgeSeg = { x1: b.xa, y1: b.ya, x2: b.xb, y2: b.yb };
|
|
||||||
|
|
||||||
console.log("DIST", dist, "edge", edge, "edgeSeg", edgeSeg);
|
|
||||||
|
|
||||||
const baseNrmlIntxn = perpIntxn(baseSlope, xa, ya, x, y);
|
const baseNrmlIntxn = perpIntxn(baseSlope, xa, ya, x, y);
|
||||||
const basePosIntxn = lineIntxnPt(edgeSeg, positionSeg);
|
const basePosIntxn = lineIntxnPt(edgeSeg, positionSeg);
|
||||||
@@ -695,7 +683,7 @@ function edgeContactPosition(xc, yc, x, y, edge, radius, gearDown) {
|
|||||||
const normalSegLength = distance(baseNrmlIntxn.x, baseNrmlIntxn.y, x, y);
|
const normalSegLength = distance(baseNrmlIntxn.x, baseNrmlIntxn.y, x, y);
|
||||||
|
|
||||||
const theta = Math.atan(normalSegLength / baseSegLength);
|
const theta = Math.atan(normalSegLength / baseSegLength);
|
||||||
const h = dist / Math.sin(theta);
|
const h = radius / Math.sin(theta);
|
||||||
|
|
||||||
const cl = document.createElementNS(namespaceURIsvg, 'line');
|
const cl = document.createElementNS(namespaceURIsvg, 'line');
|
||||||
cl.setAttribute('x1', basePosIntxn.x);
|
cl.setAttribute('x1', basePosIntxn.x);
|
||||||
@@ -746,7 +734,7 @@ function updateShip(s, elapsed) {
|
|||||||
const p = { x: pDelta.x + px, y: pDelta.y + py };
|
const p = { x: pDelta.x + px, y: pDelta.y + py };
|
||||||
current = s.collision;
|
current = s.collision;
|
||||||
|
|
||||||
s.collision = detectCollision([px, py], p, s.velocity, shipRadius, map, s.gearDown);
|
s.collision = detectCollision([px, py], p, s.velocity, shipRadius, map);
|
||||||
if (s.collision) console.log("COLLISION", s.collision);
|
if (s.collision) console.log("COLLISION", s.collision);
|
||||||
|
|
||||||
legs.style.display = s.gearDown ? "initial" : "none";
|
legs.style.display = s.gearDown ? "initial" : "none";
|
||||||
@@ -756,13 +744,13 @@ function updateShip(s, elapsed) {
|
|||||||
// edge is facing up or down? compare xs?
|
// edge is facing up or down? compare xs?
|
||||||
|
|
||||||
// const baseSlope = slope(s.collision.edge);
|
// const baseSlope = slope(s.collision.edge);
|
||||||
|
// if (Object.is(baseSlope, 0) && s.gearDown) s.isLanded = true;
|
||||||
// s.isLanded = true;
|
// s.isLanded = true;
|
||||||
let posP;
|
let posP;
|
||||||
if (s.collision.corner) {
|
if (s.collision.corner) {
|
||||||
posP = cornerContactPosition(p.x, p.y, px, py, s.collision.corner, shipRadius);
|
posP = cornerContactPosition(p.x, p.y, px, py, s.collision.corner, shipRadius);
|
||||||
} else if (s.collision.edge) {
|
} else if (s.collision.edge) {
|
||||||
if (isLandable(s.collision.edge) && s.gearDown) s.isLanded = true;
|
posP = edgeContactPosition(p.x, p.y, px, py, s.collision.edge, shipRadius);
|
||||||
posP = edgeContactPosition(p.x, p.y, px, py, s.collision.edge, shipRadius, s.gearDown);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s.velocity = { x: 0, y: 0 };
|
s.velocity = { x: 0, y: 0 };
|
||||||
@@ -771,7 +759,7 @@ function updateShip(s, elapsed) {
|
|||||||
} else if (current && s.collision) {
|
} else if (current && s.collision) {
|
||||||
s.velocity = { x: 0, y: 0 };
|
s.velocity = { x: 0, y: 0 };
|
||||||
} else {
|
} else {
|
||||||
if (s.isLanded && s.velocity.y < 0) {
|
if (s.isLanded) {
|
||||||
s.gearDown = false;
|
s.gearDown = false;
|
||||||
s.isLanded = false;
|
s.isLanded = false;
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 32 KiB |
Reference in New Issue
Block a user