Add side collision detection
This commit is contained in:
@@ -59,7 +59,7 @@
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<polygon id="wall" points="-20,-20 -20,-30 30,-30 30,30 -20,30 -20,20 20,20 20,-20" />
|
||||
<polygon id="wall" points="-20,-20 -20,-30 30,-30 30,30 -10,40 -20,30 20,20 20,-20" />
|
||||
<!-- <rect id="rect1" x="30" y="30" width="20" height="20"/> -->
|
||||
<g id="lines">
|
||||
</g>
|
||||
@@ -156,6 +156,7 @@
|
||||
function updateTriangles([positionX, positionY]) {
|
||||
const delim = ' ';
|
||||
const className = 'clockwise-orientation';
|
||||
const visible = [];
|
||||
|
||||
triangles.forEach(t => {
|
||||
const attr = t.getAttribute('points').split(delim);
|
||||
@@ -174,11 +175,14 @@
|
||||
}
|
||||
|
||||
t.classList[cwOrientation ? "add" : "remove"](className);
|
||||
if (cwOrientation) visible.push(t);
|
||||
// i think i can also discard obtuse triangles?
|
||||
|
||||
// if all the triangles are obtuse, i only need to check the nearest corner for a collision
|
||||
// otherwise, i need to check only the acute triangles
|
||||
});
|
||||
|
||||
return visible;
|
||||
}
|
||||
|
||||
const lines = lineContainer.querySelectorAll('line');
|
||||
@@ -286,6 +290,10 @@
|
||||
animate(timestamp);
|
||||
}
|
||||
|
||||
function distance(x1, y1, x2, y2) {
|
||||
return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
|
||||
}
|
||||
|
||||
function animate(timestamp) {
|
||||
const delta = timestamp - zero;
|
||||
const elapsed = timestamp - previous;
|
||||
@@ -294,11 +302,11 @@
|
||||
if (delta >= 1000) {
|
||||
fps.innerText = frameCount;
|
||||
|
||||
info.innerText = `velocity ${velocity}\n`
|
||||
+ 'bullets\nx\ty\tvx\tvy\n'
|
||||
+ bullets.map(b => {
|
||||
return `${b.x.toFixed(2)}\t${b.y.toFixed(2)}\t${b.vx.toFixed(2)}\t${b.vy.toFixed(2)}`;
|
||||
}).join("\n");
|
||||
// info.innerText = `velocity ${velocity}\n`
|
||||
// + 'bullets\nx\ty\tvx\tvy\n'
|
||||
// + bullets.map(b => {
|
||||
// return `${b.x.toFixed(2)}\t${b.y.toFixed(2)}\t${b.vx.toFixed(2)}\t${b.vy.toFixed(2)}`;
|
||||
// }).join("\n");
|
||||
|
||||
zero = timestamp;
|
||||
frameCount = 0;
|
||||
@@ -306,6 +314,7 @@
|
||||
frameCount++;
|
||||
}
|
||||
|
||||
|
||||
let degrees = getRotate(gun);
|
||||
|
||||
if (rotate > 0) gun.style.transform = `rotate(${(+degrees + rotationSpeed * elapsed) % 360}deg)`;
|
||||
@@ -338,7 +347,26 @@
|
||||
|
||||
updateBullets(elapsed);
|
||||
// updateLines(position);
|
||||
updateTriangles(position);
|
||||
const visibleTriangles = updateTriangles(position);
|
||||
|
||||
// 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');
|
||||
|
||||
// can do this after side collision detection
|
||||
// const ts = updateTriangles(position);
|
||||
@@ -359,7 +387,25 @@
|
||||
return shipBody.isPointInFill(cornerPt);
|
||||
});
|
||||
|
||||
wall.setAttribute('fill', cornerCollision ? 'red' : 'black');
|
||||
const PI = Math.PI / 2;
|
||||
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 < PI && beta < PI;
|
||||
|
||||
return acute ? [...acc, hc] : acc;
|
||||
}, []).some(h => h <= shipRadius);
|
||||
|
||||
wall.setAttribute('fill', cornerCollision || sideCollision ? 'red' : 'black');
|
||||
hitbox.style.transform = `translate(${positionX}px, ${positionY}px)`;
|
||||
|
||||
// if (+y < 200)
|
||||
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 17 KiB |
Reference in New Issue
Block a user