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);
|
requestAnimationFrame(firstFrame);
|
||||||
|
|
||||||
let start;
|
let start;
|
||||||
@@ -408,65 +446,12 @@
|
|||||||
drawEdges(trianglePts);
|
drawEdges(trianglePts);
|
||||||
}
|
}
|
||||||
|
|
||||||
// info.innerText = [...visibleTriangles].map(t => {
|
const collision = detectCollision(points, visibleTriangles);
|
||||||
// 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');
|
|
||||||
|
|
||||||
// can do this after side collision detection
|
wall.setAttribute('fill', collision ? 'red' : 'black');
|
||||||
// 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');
|
|
||||||
hitbox.style.transform = `translate(${positionX}px, ${positionY}px)`;
|
hitbox.style.transform = `translate(${positionX}px, ${positionY}px)`;
|
||||||
|
|
||||||
if (cornerCollision || sideCollision) {
|
if (collision) {
|
||||||
// restart game
|
// restart game
|
||||||
zeroForTimer = timestamp;
|
zeroForTimer = timestamp;
|
||||||
restart = true;
|
restart = true;
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 17 KiB |
Reference in New Issue
Block a user