WIP: don't overlap wall on collision
This commit is contained in:
@@ -63,8 +63,12 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
line {
|
line:not(#cannon) {
|
||||||
stroke: red;
|
stroke: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wall {
|
||||||
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wall.inverse {
|
.wall.inverse {
|
||||||
@@ -86,7 +90,8 @@
|
|||||||
</g>
|
</g>
|
||||||
|
|
||||||
<!-- <polygon class="wall" points="20,20 30,20 40,40 20,40" /> -->
|
<!-- <polygon class="wall" points="20,20 30,20 40,40 20,40" /> -->
|
||||||
<polygon class="wall" points="20,20 30,20 40,40 10,40" />
|
<!-- <polygon class="wall" points="20,20 20,10 30,10 30,20 40,40 10,40" /> -->
|
||||||
|
<polygon class="wall" points="-10,20 10,10 10,20" />
|
||||||
<!-- <polygon class="wall" points="20,20 40,20 40,40 20,40" /> -->
|
<!-- <polygon class="wall" points="20,20 40,20 40,40 20,40" /> -->
|
||||||
<!-- <polygon class="wall" points="10,10 20,10 20,20 10,20" /> -->
|
<!-- <polygon class="wall" points="10,10 20,10 20,20 10,20" /> -->
|
||||||
<!-- <polygon class="wall" points="20,-50 -50,-50 -60,-70 -50,-100 80,-100 80,-90 -20,-90 -20,-60 40,-60 40,40 20,40" /> -->
|
<!-- <polygon class="wall" points="20,-50 -50,-50 -60,-70 -50,-100 80,-100 80,-90 -20,-90 -20,-60 40,-60 40,40 20,40" /> -->
|
||||||
@@ -438,6 +443,7 @@
|
|||||||
el.setAttribute('x2', xb);
|
el.setAttribute('x2', xb);
|
||||||
el.setAttribute('y2', yb);
|
el.setAttribute('y2', yb);
|
||||||
svg.appendChild(el);
|
svg.appendChild(el);
|
||||||
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
function slope({ xa, ya, xb, yb }) {
|
function slope({ xa, ya, xb, yb }) {
|
||||||
@@ -450,50 +456,20 @@
|
|||||||
return Object.is(slope(edge), +0);
|
return Object.is(slope(edge), +0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// i need to know the point of collision to position the ship adjacent to it
|
function detectEdgeCollision([xc, yc], { xa, ya, xb, yb }) {
|
||||||
function detectEdgeCollision([xc, yc], edge, { xa, ya, xb, yb }) {
|
|
||||||
const shipRadius = 5;
|
const shipRadius = 5;
|
||||||
// const [[xa, ya], [xb, yb]] = edge.split(' ').map(n => n.split(',').map(n => +n));
|
|
||||||
|
|
||||||
const da = distance(xa, ya, xc, yc);
|
const da = distance(xa, ya, xc, yc);
|
||||||
const db = distance(xb, yb, xc, yc);
|
const db = distance(xb, yb, xc, yc);
|
||||||
// TODO: calculate this one ahead of time
|
// TODO: calculate this one ahead of time
|
||||||
const dc = distance(xa, ya, xb, yb);
|
const dc = distance(xa, ya, xb, yb);
|
||||||
|
|
||||||
const baseSlope = slope({ xa, ya, xb, yb });
|
|
||||||
|
|
||||||
// console.log("slope of base", baseSlope);
|
|
||||||
|
|
||||||
if (baseSlope === -Infinity) {
|
|
||||||
// console.log("foot", xa + shipRadius, yc);
|
|
||||||
} else if (baseSlope === Infinity) {
|
|
||||||
// console.log("foot", xa - shipRadius, yc);
|
|
||||||
} else if (Object.is(baseSlope, 0)) {
|
|
||||||
// console.log("foot", xc, ya - shipRadius);
|
|
||||||
} else if (Object.is(baseSlope, -0)) {
|
|
||||||
// console.log("foot", xc, ya + shipRadius);
|
|
||||||
} else {
|
|
||||||
const foot = perpIntxn(baseSlope, xa, ya, xc, yc);
|
|
||||||
// console.log("foot", foot);
|
|
||||||
// drawLine(foot.x, foot.y, xc, yc)
|
|
||||||
const el = document.createElementNS(namespaceURIsvg, 'line');
|
|
||||||
el.setAttribute('x1', foot.x);
|
|
||||||
el.setAttribute('y1', foot.y);
|
|
||||||
el.setAttribute('x2', xc);
|
|
||||||
el.setAttribute('y2', yc);
|
|
||||||
// this point should be the position of the ship to make it
|
|
||||||
// adjacent to the collision edge without overlapping it
|
|
||||||
console.log(el.getPointAtLength(5));
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://en.wikipedia.org/wiki/Altitude_(triangle)#Altitude_in_terms_of_the_sides
|
// https://en.wikipedia.org/wiki/Altitude_(triangle)#Altitude_in_terms_of_the_sides
|
||||||
// Find altitude of side c (the base)
|
// Find altitude of side c (the base)
|
||||||
const s = (1 / 2) * (da + db + dc);
|
const s = (1 / 2) * (da + db + dc);
|
||||||
const hc = (2 / dc) * Math.sqrt(s * (s - da) * (s - db) * (s - dc));
|
const hc = (2 / dc) * Math.sqrt(s * (s - da) * (s - db) * (s - dc));
|
||||||
|
|
||||||
return +hc.toFixed(2) <= shipRadius;
|
return +hc.toFixed(2) <= shipRadius;
|
||||||
// console.log("hc", );
|
|
||||||
// return hc <= shipRadius;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function detectCornerCollision([xc, yc], [x, y]) {
|
function detectCornerCollision([xc, yc], [x, y]) {
|
||||||
@@ -520,9 +496,9 @@
|
|||||||
// console.log("actual corner", actualCorner);
|
// console.log("actual corner", actualCorner);
|
||||||
// if (corner) console.log("corner collision", corner);
|
// if (corner) console.log("corner collision", corner);
|
||||||
|
|
||||||
const edge = z.find(({ edge: e, node: ee }) => {
|
const edge = z.find(({ edge: pts, node: ee }) => {
|
||||||
const str = `${e.xa},${e.ya} ${e.xb},${e.yb}`;
|
const str = `${pts.xa},${pts.ya} ${pts.xb},${pts.yb}`;
|
||||||
return detectEdgeCollision(position, str, e);
|
return detectEdgeCollision(position, pts);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -573,19 +549,95 @@
|
|||||||
|
|
||||||
let { x, y } = s.position;
|
let { x, y } = s.position;
|
||||||
let position = [positionX, positionY] = restart ? [0, 0] : wrapPos(changeX + x, changeY + y);
|
let position = [positionX, positionY] = restart ? [0, 0] : wrapPos(changeX + x, changeY + y);
|
||||||
|
let [xc, yc] = position;
|
||||||
s.collision = detectCollisions(position, allWallCorners, findAllEdges(allEdgePts, position), getCollisionEdges(edgeszz, position));
|
s.collision = detectCollisions(position, allWallCorners, findAllEdges(allEdgePts, position), getCollisionEdges(edgeszz, position));
|
||||||
|
|
||||||
if (s.collision && !isLandable(s.collision.edge)) {
|
// if (s.collision) {
|
||||||
console.log("a", "position", position, s.position);
|
// find final position of ship
|
||||||
s.velocity = { x: 0, y: 0 };
|
|
||||||
} else if (s.collision) {
|
|
||||||
console.log("b", s.position, s.collision);
|
|
||||||
|
|
||||||
s.velocity = { x: 0, y: 0 };
|
// const baseSlope = slope(s.collision.edge);
|
||||||
s.position.y = Math.trunc(s.collision.edge.ya - 5);
|
// const { xa, ya, xb, yb } = s.collision.edge;
|
||||||
s.isLanded = true;
|
// const baseSlope = slope(s.collision.edge);
|
||||||
s.node.style.transform = `translate(${s.position.x}px, ${s.position.y}px)`;
|
|
||||||
|
// console.log("slope of base", baseSlope);
|
||||||
|
|
||||||
|
// if (baseSlope === -Infinity) {
|
||||||
|
// (↤) Vertical, normal left
|
||||||
|
// console.log("foot", xa + shipRadius, yc);
|
||||||
|
// } else if (baseSlope === Infinity) {
|
||||||
|
// (↦) Vertical, normal right
|
||||||
|
|
||||||
|
// console.log("foot", xa - shipRadius, yc);
|
||||||
|
// } else if (Object.is(baseSlope, 0)) {
|
||||||
|
// (↥) Horizontal, normal up
|
||||||
|
// const el = document.createElementNS(namespaceURIsvg, 'line');
|
||||||
|
// el.setAttribute('x1', xc);
|
||||||
|
// el.setAttribute('y1', ya);
|
||||||
|
// el.setAttribute('x2', xc);
|
||||||
|
// el.setAttribute('y2', yc);
|
||||||
|
// this point should be the position of the ship to make it
|
||||||
|
// adjacent to the collision edge without overlapping it
|
||||||
|
// console.log(el.getPointAtLength(5));
|
||||||
|
// const collPt = el.getPointAtLength(5);
|
||||||
|
// drawLine(xc, ya, collPt.x, collPt.y);
|
||||||
|
|
||||||
|
// console.log("foot", xc, ya - shipRadius);
|
||||||
|
// } else if (Object.is(baseSlope, -0)) {
|
||||||
|
// (↧) Horizontal, normal down
|
||||||
|
|
||||||
|
// console.log("foot", xc, ya + shipRadius);
|
||||||
|
// } else {
|
||||||
|
// const foot = perpIntxn(baseSlope, xa, ya, xc, yc);
|
||||||
|
// console.log("foot", foot);
|
||||||
|
// drawLine(foot.x, foot.y, xc, yc)
|
||||||
|
// const el = document.createElementNS(namespaceURIsvg, 'line');
|
||||||
|
// el.setAttribute('x1', foot.x);
|
||||||
|
// el.setAttribute('y1', foot.y);
|
||||||
|
// el.setAttribute('x2', xc);
|
||||||
|
// el.setAttribute('y2', yc);
|
||||||
|
// this point should be the position of the ship to make it
|
||||||
|
// adjacent to the collision edge without overlapping it
|
||||||
|
// console.log(el.getPointAtLength(5));
|
||||||
|
// const collPt = el.getPointAtLength(5);
|
||||||
|
// drawLine(foot.x, foot.y, collPt.x, collPt.y);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (s.collision && !isLandable(s.collision.edge)) {
|
||||||
|
// console.log("a", "position", position, s.position);
|
||||||
|
// s.velocity = { x: 0, y: 0 };
|
||||||
|
// } else if (s.collision) {
|
||||||
|
// console.log("b", s.position, s.collision);
|
||||||
|
//
|
||||||
|
// s.velocity = { x: 0, y: 0 };
|
||||||
|
// s.position.y = Math.trunc(s.collision.edge.ya - 5);
|
||||||
|
// s.isLanded = true;
|
||||||
|
// s.node.style.transform = `translate(${s.position.x}px, ${s.position.y}px)`;
|
||||||
// console.log("ship landed", s, "edge", s.collision.edge.ya);
|
// console.log("ship landed", s, "edge", s.collision.edge.ya);
|
||||||
|
if (s.collision) {
|
||||||
|
console.log("a");
|
||||||
|
s.velocity = { x: 0, y: 0 };
|
||||||
|
const baseSlope = slope(s.collision.edge);
|
||||||
|
const normalSlope = 1 / -baseSlope;
|
||||||
|
const radAngle = Math.atan(normalSlope);
|
||||||
|
const { xa, ya, xb, yb } = s.collision.edge;
|
||||||
|
const foot = perpIntxn(baseSlope, xa, ya, xc, yc);
|
||||||
|
const el = document.createElementNS(namespaceURIsvg, 'line');
|
||||||
|
el.setAttribute('x1', foot.x);
|
||||||
|
el.setAttribute('y1', foot.y);
|
||||||
|
el.setAttribute('x2', xc);
|
||||||
|
el.setAttribute('y2', yc);
|
||||||
|
// the problem is that by this point the ship is already closer than
|
||||||
|
// its radius so the line is less than 5 units long
|
||||||
|
console.log("foot", foot, "line", el);
|
||||||
|
const [posX, posY] = [5 * Math.sin(radAngle), 5 * Math.cos(radAngle)];
|
||||||
|
const collPt = el.getPointAtLength(5);
|
||||||
|
// let l = drawLine(foot.x, foot.y, foot.x - posX, foot.y - posY);
|
||||||
|
let l = drawLine(foot.x, foot.y, foot.x - posY, foot.y - posX);
|
||||||
|
console.log("line length", l.getTotalLength(), l);
|
||||||
|
s.position = { x: foot.x - posY, y: foot.y - posX };
|
||||||
|
// s.position = { x: collPt.x, y: collPt.y };
|
||||||
|
s.node.style.transform = `translate(${s.position.x}px, ${s.position.y}px)`;
|
||||||
} else {
|
} else {
|
||||||
console.log("c");
|
console.log("c");
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 29 KiB |
Reference in New Issue
Block a user