Refactor
This commit is contained in:
@@ -91,8 +91,8 @@
|
|||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<polygon id="wall" points="20,20 40,20 40,40 20,40" />
|
<!-- <polygon id="wall" points="20,20 40,20 40,40 20,40" /> -->
|
||||||
<!-- <polygon id="wall" points="-10,-30 -10,-40 30,-50 60,-30 80,0 150,0 150,10 60,50 -10,40 -20,20 20,20 20,-20" /> -->
|
<polygon id="wall" points="-10,-30 -10,-40 30,-50 60,-30 80,0 150,0 150,10 60,50 -10,40 -20,20 20,20 20,-20" />
|
||||||
|
|
||||||
<g id="triangles"></g>
|
<g id="triangles"></g>
|
||||||
<g id="lines"></g>
|
<g id="lines"></g>
|
||||||
@@ -147,7 +147,7 @@
|
|||||||
|
|
||||||
const triangleContainer = document.querySelector('#triangles');
|
const triangleContainer = document.querySelector('#triangles');
|
||||||
const lineContainer = document.querySelector('#lines');
|
const lineContainer = document.querySelector('#lines');
|
||||||
const trianglePts = points.map((pt, i) => [pt, points[(i + 1) % points.length]]);
|
const edgePts = points.map((pt, i) => [pt, points[(i + 1) % points.length]]);
|
||||||
const drawCollisionLines = false;
|
const drawCollisionLines = false;
|
||||||
|
|
||||||
function drawEdges(lpts) {
|
function drawEdges(lpts) {
|
||||||
@@ -167,7 +167,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
drawEdges(trianglePts);
|
drawEdges(edgePts);
|
||||||
|
|
||||||
function drawTriangles(container, pts, [positionX, positionY]) {
|
function drawTriangles(container, pts, [positionX, positionY]) {
|
||||||
pts.forEach(([[x1, y1], [x2, y2]]) => {
|
pts.forEach(([[x1, y1], [x2, y2]]) => {
|
||||||
@@ -178,7 +178,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
drawTriangles(triangleContainer, trianglePts, position);
|
drawTriangles(triangleContainer, edgePts, position);
|
||||||
const triangles = triangleContainer.querySelectorAll('polygon');
|
const triangles = triangleContainer.querySelectorAll('polygon');
|
||||||
|
|
||||||
// Triangle has a clockwise orientation
|
// Triangle has a clockwise orientation
|
||||||
@@ -209,7 +209,7 @@
|
|||||||
}, []);
|
}, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
const collisionEdges = findEdges(trianglePts, position);
|
const collisionEdges = findEdges(edgePts, position);
|
||||||
|
|
||||||
function updateTriangles([positionX, positionY]) {
|
function updateTriangles([positionX, positionY]) {
|
||||||
const delim = ' ';
|
const delim = ' ';
|
||||||
@@ -339,39 +339,29 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function detectCollision(points, visibleTriangles) {
|
function detectCollision(points, [xc, yc], edges) {
|
||||||
const cornerCollision = points.some(([x, y]) => {
|
const cornerCollision = points.some(([x, y]) => {
|
||||||
cornerPt.x = x - positionX;
|
cornerPt.x = x - xc;
|
||||||
cornerPt.y = y - positionY;
|
cornerPt.y = y - yc;
|
||||||
|
|
||||||
return shipBody.isPointInFill(cornerPt);
|
return shipBody.isPointInFill(cornerPt);
|
||||||
});
|
});
|
||||||
|
|
||||||
const shipRadius = 5;
|
const shipRadius = 5;
|
||||||
const sideCollision = [...visibleTriangles].reduce((acc, t) => {
|
const sideCollision = edges.reduce((acc, e) => {
|
||||||
const [[ax, ay], [bx, by], [shipx, shipy]] =
|
const [[xa, ya], [xb, yb]] = e.split(' ').map(n => n.split(',').map(n => +n));
|
||||||
t.getAttribute('points').split(' ').map(n => n.split(',').map(n => +n));
|
|
||||||
|
|
||||||
const da = distance(ax, ay, shipx, shipy);
|
const da = distance(xa, ya, xc, yc);
|
||||||
const db = distance(bx, by, shipx, shipy);
|
const db = distance(xb, yb, xc, yc);
|
||||||
// TODO: calculate this one ahead of time
|
// TODO: calculate this one ahead of time
|
||||||
const dc = distance(ax, ay, bx, by);
|
const dc = distance(xa, ya, xb, yb);
|
||||||
|
|
||||||
// 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));
|
||||||
|
|
||||||
// https://en.wikipedia.org/wiki/Law_of_cosines
|
return [...acc, hc];
|
||||||
// Solve for angles alpha and beta with inverse cosine (arccosine) function
|
|
||||||
const alpha = Math.acos((db**2 + dc**2 - da**2) / (2 * db * dc));
|
|
||||||
const beta = Math.acos((da**2 + dc**2 - db**2) / (2 * da * dc));
|
|
||||||
|
|
||||||
// Is acute if both angles are < 90 degrees
|
|
||||||
// TODO: what about right triangles?
|
|
||||||
const isAcute = alpha < halfPi && beta < halfPi;
|
|
||||||
|
|
||||||
return isAcute ? [...acc, hc] : acc;
|
|
||||||
}, []).some(h => h <= shipRadius);
|
}, []).some(h => h <= shipRadius);
|
||||||
|
|
||||||
return cornerCollision || sideCollision;
|
return cornerCollision || sideCollision;
|
||||||
@@ -409,6 +399,25 @@
|
|||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateEdges(position) {
|
||||||
|
const mappedEdges = findEdges(edgePts, position);
|
||||||
|
|
||||||
|
[...lineContainer.children].forEach(l => {
|
||||||
|
const x1 = l.getAttribute('x1');
|
||||||
|
const y1 = l.getAttribute('y1');
|
||||||
|
const x2 = l.getAttribute('x2');
|
||||||
|
const y2 = l.getAttribute('y2');
|
||||||
|
const edge = `${x1},${y1} ${x2},${y2}`;
|
||||||
|
|
||||||
|
if (mappedEdges.includes(edge))
|
||||||
|
if ([
|
||||||
|
lineContainer.childElementCount <= collisionEdges.length,
|
||||||
|
!collisionEdges.includes(edge)
|
||||||
|
].some(c => c))
|
||||||
|
l.remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let start;
|
let start;
|
||||||
let restart = false;
|
let restart = false;
|
||||||
function firstFrame(timestamp) {
|
function firstFrame(timestamp) {
|
||||||
@@ -449,38 +458,15 @@
|
|||||||
|
|
||||||
position = updateShip(elapsed);
|
position = updateShip(elapsed);
|
||||||
updateBullets(elapsed);
|
updateBullets(elapsed);
|
||||||
|
updateEdges(position);
|
||||||
const visibleTriangles = updateTriangles(position);
|
|
||||||
const visibleTrianglePoints = [...visibleTriangles].map(p => p.getAttribute("points"));
|
|
||||||
|
|
||||||
const mappedEdges = visibleTrianglePoints.map(vt => {
|
|
||||||
vt = vt.split(' ');
|
|
||||||
vt.pop();
|
|
||||||
return vt.join(' ');
|
|
||||||
});
|
|
||||||
|
|
||||||
[...lineContainer.children].forEach(l => {
|
|
||||||
const x1 = l.getAttribute('x1');
|
|
||||||
const y1 = l.getAttribute('y1');
|
|
||||||
const x2 = l.getAttribute('x2');
|
|
||||||
const y2 = l.getAttribute('y2');
|
|
||||||
const str = `${x1},${y1} ${x2},${y2}`;
|
|
||||||
|
|
||||||
if (mappedEdges.includes(str))
|
|
||||||
if ([
|
|
||||||
lineContainer.childElementCount <= collisionEdges.length,
|
|
||||||
!collisionEdges.includes(str)
|
|
||||||
].some(c => c))
|
|
||||||
l.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (restart) {
|
if (restart) {
|
||||||
restart = false;
|
restart = false;
|
||||||
[...lineContainer.children].forEach(c => c.remove());;
|
[...lineContainer.children].forEach(c => c.remove());;
|
||||||
drawEdges(trianglePts);
|
drawEdges(edgePts);
|
||||||
}
|
}
|
||||||
|
|
||||||
const collision = detectCollision(points, visibleTriangles);
|
const collision = detectCollision(points, position, findEdges(edgePts, position));
|
||||||
wall.setAttribute('fill', collision ? 'red' : 'black');
|
wall.setAttribute('fill', collision ? 'red' : 'black');
|
||||||
|
|
||||||
if (collision) {
|
if (collision) {
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Reference in New Issue
Block a user