Move collision detection code into its own function
This commit is contained in:
@@ -314,6 +314,44 @@
|
||||
});
|
||||
}
|
||||
|
||||
function detectCollision(points, visibleTriangles) {
|
||||
const cornerCollision = points.some(([x, y]) => {
|
||||
cornerPt.x = x - positionX;
|
||||
cornerPt.y = y - positionY;
|
||||
|
||||
return shipBody.isPointInFill(cornerPt);
|
||||
});
|
||||
|
||||
const shipRadius = 5;
|
||||
const sideCollision = [...visibleTriangles].reduce((acc, t) => {
|
||||
const [[ax, ay], [bx, by], [shipx, shipy]] =
|
||||
t.getAttribute('points').split(' ').map(n => n.split(',').map(n => +n));
|
||||
|
||||
const da = distance(ax, ay, shipx, shipy);
|
||||
const db = distance(bx, by, shipx, shipy);
|
||||
// TODO: calculate this one ahead of time
|
||||
const dc = distance(ax, ay, bx, by);
|
||||
|
||||
// https://en.wikipedia.org/wiki/Altitude_(triangle)#Altitude_in_terms_of_the_sides
|
||||
// Find altitude of side c (the base)
|
||||
const s = (1 / 2) * (da + db + dc);
|
||||
const hc = (2 / dc) * Math.sqrt(s * (s - da) * (s - db) * (s - dc));
|
||||
|
||||
// https://en.wikipedia.org/wiki/Law_of_cosines
|
||||
// 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);
|
||||
|
||||
return cornerCollision || sideCollision;
|
||||
}
|
||||
|
||||
requestAnimationFrame(firstFrame);
|
||||
|
||||
let start;
|
||||
@@ -408,65 +446,12 @@
|
||||
drawEdges(trianglePts);
|
||||
}
|
||||
|
||||
// info.innerText = [...visibleTriangles].map(t => {
|
||||
// const [[ax, ay], [bx, by], [shipx, shipy]] =
|
||||
// t.getAttribute('points').split(' ').map(n => n.split(',').map(n => +n));
|
||||
//
|
||||
// const da = distance(ax, ay, shipx, shipy);
|
||||
// const db = distance(bx, by, shipx, shipy);
|
||||
// const dc = distance(ax, ay, bx, by);
|
||||
// const s = (1 / 2) * (da + db + dc);
|
||||
// const hc = (2 / dc) * Math.sqrt(s * (s - da) * (s - db) * (s - dc));
|
||||
//
|
||||
// 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));
|
||||
//
|
||||
// const PI = Math.PI / 2;
|
||||
// const acute = alpha < PI && beta < PI;
|
||||
//
|
||||
// return `${da.toFixed(2)} ${db.toFixed(2)} ${dc.toFixed(2)} ${hc.toFixed(2)} ${alpha.toFixed(2)} ${beta.toFixed(2)}`;
|
||||
// }).join('\n');
|
||||
const collision = detectCollision(points, visibleTriangles);
|
||||
|
||||
// can do this after side collision detection
|
||||
// const ts = updateTriangles(position);
|
||||
// const corners = ts.reduce((acc, t) => {
|
||||
// const [a, b,] = t.getAttribute('points').split(' ');
|
||||
// // return p.map(t => t.split(','));
|
||||
// // acc.push(a);
|
||||
// // acc.push(b);
|
||||
// return [a, b, ...acc];
|
||||
// }, []);
|
||||
//
|
||||
// const uniqueCorners = [...new Set(corners)].map(n => n.split(',').map(n => +n));
|
||||
|
||||
const cornerCollision = points.some(([x, y]) => {
|
||||
cornerPt.x = x - positionX;
|
||||
cornerPt.y = y - positionY;
|
||||
|
||||
return shipBody.isPointInFill(cornerPt);
|
||||
});
|
||||
|
||||
const shipRadius = 5;
|
||||
const sideCollision = [...visibleTriangles].reduce((acc, t) => {
|
||||
const [[ax, ay], [bx, by], [shipx, shipy]] =
|
||||
t.getAttribute('points').split(' ').map(n => n.split(',').map(n => +n));
|
||||
|
||||
const da = distance(ax, ay, shipx, shipy);
|
||||
const db = distance(bx, by, shipx, shipy);
|
||||
const dc = distance(ax, ay, bx, by);
|
||||
const s = (1 / 2) * (da + db + dc);
|
||||
const hc = (2 / dc) * Math.sqrt(s * (s - da) * (s - db) * (s - dc));
|
||||
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));
|
||||
const acute = alpha < halfPi && beta < halfPi;
|
||||
|
||||
return acute ? [...acc, hc] : acc;
|
||||
}, []).some(h => h <= shipRadius);
|
||||
|
||||
wall.setAttribute('fill', cornerCollision || sideCollision ? 'red' : 'black');
|
||||
wall.setAttribute('fill', collision ? 'red' : 'black');
|
||||
hitbox.style.transform = `translate(${positionX}px, ${positionY}px)`;
|
||||
|
||||
if (cornerCollision || sideCollision) {
|
||||
if (collision) {
|
||||
// restart game
|
||||
zeroForTimer = timestamp;
|
||||
restart = true;
|
||||
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 17 KiB |
Reference in New Issue
Block a user