WIP: gear down with G key
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<!-- <svg viewBox="-200 -150 400 300" version="1.1" xmlns="http://www.w3.org/2000/svg"> -->
|
<svg viewBox="-200 -150 400 300" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
<svg viewBox="-10 -10 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
<!-- <svg viewBox="-10 -10 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg"> -->
|
||||||
<style>
|
<style>
|
||||||
foreignObject {
|
foreignObject {
|
||||||
font-size: 4pt;
|
font-size: 4pt;
|
||||||
@@ -109,7 +109,7 @@
|
|||||||
</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 20,10 30,10 30,20 40,40 10,40" />
|
<polygon class="wall" points="20,20 50,20 70,40 70,70 50,90 20,90 0,70 0,40" />
|
||||||
<!-- <polygon class="wall" points="-10,20 10,10 10,20" /> -->
|
<!-- <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" /> -->
|
||||||
@@ -193,7 +193,8 @@
|
|||||||
rotate: 0,
|
rotate: 0,
|
||||||
collision: null,
|
collision: null,
|
||||||
isLanded: false,
|
isLanded: false,
|
||||||
node: null
|
node: null,
|
||||||
|
gearDown: false
|
||||||
};
|
};
|
||||||
|
|
||||||
let friction = 0;
|
let friction = 0;
|
||||||
@@ -211,6 +212,7 @@
|
|||||||
s.node = ship;
|
s.node = ship;
|
||||||
const gun = ship.querySelector('#cannon');
|
const gun = ship.querySelector('#cannon');
|
||||||
const shipBody = ship.querySelector("#body");
|
const shipBody = ship.querySelector("#body");
|
||||||
|
const legs = ship.querySelector("#legs");
|
||||||
// const walls = document.querySelectorAll('.wall:not(.inverse)');
|
// const walls = document.querySelectorAll('.wall:not(.inverse)');
|
||||||
const walls = document.querySelectorAll('.wall');
|
const walls = document.querySelectorAll('.wall');
|
||||||
const bulletsContainer = document.querySelector("#bullets");
|
const bulletsContainer = document.querySelector("#bullets");
|
||||||
@@ -529,6 +531,44 @@
|
|||||||
return edge || actualCorner;
|
return edge || actualCorner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function collisionPosition(edge, position, velocity) {
|
||||||
|
const baseSlope = slope(edge);
|
||||||
|
// if (Object.is(baseSlope, 0)) s.isLanded = true;
|
||||||
|
|
||||||
|
const { xa, ya, xb, yb } = edge;
|
||||||
|
const baseLine = { x1: xa, y1: ya, x2: xb, y2: yb };
|
||||||
|
|
||||||
|
const velocityLine = {
|
||||||
|
x1: position.x,
|
||||||
|
y1: position.y,
|
||||||
|
x2: position.x + velocity.x,
|
||||||
|
y2: position.y + velocity.y
|
||||||
|
};
|
||||||
|
|
||||||
|
// console.log("COLLISION DETECTED", s.collision);
|
||||||
|
|
||||||
|
// console.log("baseSlope", baseSlope);
|
||||||
|
const baseNrmlIntxn = perpIntxn(baseSlope, xa, ya, position.x, position.y);
|
||||||
|
const baseVelIntxn = lineIntxnPt(baseLine, velocityLine);
|
||||||
|
// console.log("baseNrmlIntxn", baseNrmlIntxn, "baseVelIntxn", baseVelIntxn);
|
||||||
|
const baseSegLength = distance(baseNrmlIntxn.x, baseNrmlIntxn.y , baseVelIntxn.x, baseVelIntxn.y);
|
||||||
|
const normalSegLength = distance(baseNrmlIntxn.x, baseNrmlIntxn.y, position.x, position.y);
|
||||||
|
// console.log("baseSegLength", baseSegLength, "normalSegLength", normalSegLength);
|
||||||
|
const theta = Math.atan(normalSegLength / baseSegLength);
|
||||||
|
const shipRadius = 5;
|
||||||
|
const h = shipRadius / Math.sin(theta);
|
||||||
|
|
||||||
|
const cl = document.createElementNS(namespaceURIsvg, 'line');
|
||||||
|
cl.setAttribute('x1', baseVelIntxn.x);
|
||||||
|
cl.setAttribute('y1', baseVelIntxn.y);
|
||||||
|
cl.setAttribute('x2', position.x);
|
||||||
|
cl.setAttribute('y2', position.y);
|
||||||
|
|
||||||
|
// console.log("h", h, "theta", theta);
|
||||||
|
const clPos = cl.getPointAtLength(h);
|
||||||
|
return clPos;
|
||||||
|
}
|
||||||
|
|
||||||
function lineIntxnPt({ x1, y1, x2, y2 }, { x1: x3, y1: y3, x2: x4, y2: y4 }) {
|
function lineIntxnPt({ x1, y1, x2, y2 }, { x1: x3, y1: y3, x2: x4, y2: y4 }) {
|
||||||
// https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection#Given_two_points_on_each_line
|
// https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection#Given_two_points_on_each_line
|
||||||
const denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
|
const denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
|
||||||
@@ -561,61 +601,29 @@
|
|||||||
const changeY = 0.001 * elapsed * velocityY;
|
const changeY = 0.001 * elapsed * velocityY;
|
||||||
|
|
||||||
let { x, y } = s.position;
|
let { x, y } = s.position;
|
||||||
console.log("current position", x, y);
|
// console.log("current position", x, y);
|
||||||
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;
|
let [xc, yc] = position;
|
||||||
|
|
||||||
const collE = getCollisionEdges(edgeszz, position);
|
const collE = getCollisionEdges(edgeszz, position);
|
||||||
console.log("collision edges", collE);
|
// console.log("collision edges", collE);
|
||||||
current = s.collision;
|
current = s.collision;
|
||||||
s.collision = detectCollisions(position, allWallCorners, findAllEdges(allEdgePts, position), collE);
|
s.collision = detectCollisions(position, allWallCorners, findAllEdges(allEdgePts, position), collE);
|
||||||
|
|
||||||
console.log("future position", xc, yc);
|
// console.log("future position", xc, yc);
|
||||||
|
|
||||||
if (!current && s.collision) {
|
if (!current && s.collision) {
|
||||||
const baseSlope = slope(s.collision.edge);
|
const baseSlope = slope(s.collision.edge);
|
||||||
if (Object.is(baseSlope, 0)) s.isLanded = true;
|
if (Object.is(baseSlope, 0) && s.gearDown) s.isLanded = true;
|
||||||
const { xa, ya, xb, yb } = s.collision.edge;
|
const clPos = collisionPosition(s.collision.edge, s.position, s.velocity);
|
||||||
const baseLine = { x1: xa, y1: ya, x2: xb, y2: yb };
|
|
||||||
|
|
||||||
const velocityLine = {
|
|
||||||
x1: s.position.x,
|
|
||||||
y1: s.position.y,
|
|
||||||
x2: s.position.x + s.velocity.x,
|
|
||||||
y2: s.position.y + s.velocity.y
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log("COLLISION DETECTED", s.collision);
|
|
||||||
|
|
||||||
console.log("baseSlope", baseSlope);
|
|
||||||
const baseNrmlIntxn = perpIntxn(baseSlope, xa, ya, s.position.x, s.position.y);
|
|
||||||
const baseVelIntxn = lineIntxnPt(baseLine, velocityLine);
|
|
||||||
console.log("baseNrmlIntxn", baseNrmlIntxn, "baseVelIntxn", baseVelIntxn);
|
|
||||||
const baseSegLength = distance(baseNrmlIntxn.x, baseNrmlIntxn.y , baseVelIntxn.x, baseVelIntxn.y);
|
|
||||||
const normalSegLength = distance(baseNrmlIntxn.x, baseNrmlIntxn.y, s.position.x, s.position.y);
|
|
||||||
console.log("baseSegLength", baseSegLength, "normalSegLength", normalSegLength);
|
|
||||||
const theta = Math.atan(normalSegLength / baseSegLength);
|
|
||||||
const shipRadius = 5;
|
|
||||||
const h = shipRadius / Math.sin(theta);
|
|
||||||
|
|
||||||
const cl = document.createElementNS(namespaceURIsvg, 'line');
|
|
||||||
cl.setAttribute('x1', baseVelIntxn.x);
|
|
||||||
cl.setAttribute('y1', baseVelIntxn.y);
|
|
||||||
cl.setAttribute('x2', s.position.x);
|
|
||||||
cl.setAttribute('y2', s.position.y);
|
|
||||||
|
|
||||||
console.log("h", h, "theta", theta, );
|
|
||||||
const clPos = cl.getPointAtLength(h);
|
|
||||||
|
|
||||||
s.velocity = { x: 0, y: 0 };
|
s.velocity = { x: 0, y: 0 };
|
||||||
s.position = { x: clPos.x, y: clPos.y }
|
s.position = { x: clPos.x, y: clPos.y }
|
||||||
s.node.style.transform = `translate(${s.position.x}px, ${s.position.y}px)`;
|
s.node.style.transform = `translate(${s.position.x}px, ${s.position.y}px)`;
|
||||||
} else if (current && s.collision) {
|
} else if (current && s.collision) {
|
||||||
// nothing
|
|
||||||
s.velocity = { x: 0, y: 0 };
|
s.velocity = { x: 0, y: 0 };
|
||||||
} else {
|
} else {
|
||||||
// console.log("c");
|
s.isLanded = false;
|
||||||
|
|
||||||
s.position = { x: positionX, y: positionY }
|
s.position = { x: positionX, y: positionY }
|
||||||
s.node.style.transform = `translate(${positionX}px, ${positionY}px)`;
|
s.node.style.transform = `translate(${positionX}px, ${positionY}px)`;
|
||||||
}
|
}
|
||||||
@@ -640,77 +648,48 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateLines(elapsed, edges, currentPos, futurePos) {
|
function updateLines(elapsed, walls, position, velocity) {
|
||||||
const edgeIds = edges.map(({edge: { xa, ya, xb, yb }}) => `normal${xa}-${ya}-${xb}-${yb}`);
|
const edges = walls.reduce((acc, wall) => {
|
||||||
|
return [...acc, ...wall.edges];
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const edgeIds = edges.map(e => `normal${e.xa}-${e.ya}-${e.xb}-${e.yb}`);
|
||||||
const nodes = [...linesContainer.children];
|
const nodes = [...linesContainer.children];
|
||||||
|
|
||||||
nodes.forEach(n => {
|
nodes.forEach(n => {
|
||||||
if (!edgeIds.includes(n.id)) n.remove();
|
if (!edgeIds.includes(n.id)) n.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
edges.forEach(({ edge: { xa, ya, xb, yb }}) => {
|
// console.log("EDGES", edges);
|
||||||
|
|
||||||
|
edges.forEach(({ xa, ya, xb, yb }) => {
|
||||||
const id = `normal${xa}-${ya}-${xb}-${yb}`;
|
const id = `normal${xa}-${ya}-${xb}-${yb}`;
|
||||||
const g = linesContainer.querySelector(`#${id}`) || document.createElementNS(namespaceURIsvg, 'g');
|
const g = linesContainer.querySelector(`#${id}`) || document.createElementNS(namespaceURIsvg, 'g');
|
||||||
const el = g.querySelector('line') || document.createElementNS(namespaceURIsvg, 'line');
|
const el = g.querySelector('line') || document.createElementNS(namespaceURIsvg, 'line');
|
||||||
const star = g.querySelector('circle') || document.createElementNS(namespaceURIsvg, 'circle');
|
const star = g.querySelector('circle') || document.createElementNS(namespaceURIsvg, 'circle');
|
||||||
star.setAttribute('r', 1);
|
star.setAttribute('r', 1);
|
||||||
|
// console.log(position, velocity, xa, ya, xb, yb);
|
||||||
|
|
||||||
const baseSlope = slope({ xa, ya, xb, yb });
|
const baseSlope = slope({ xa, ya, xb, yb });
|
||||||
const intx = perpIntxn(baseSlope, xa, ya, s.position.x, s.position.y);
|
|
||||||
const baseNrmlIntxn = perpIntxn(baseSlope, xa, ya, s.position.x, s.position.y);
|
|
||||||
|
|
||||||
// make sure this is using the calculated future velocity, not the current
|
let isx, isy;
|
||||||
const baseLine = { x1: xa, y1: ya, x2: xb, y2: yb };
|
|
||||||
|
|
||||||
const velocityLine = {
|
// console.log("BASESLOPE", baseSlope);
|
||||||
x1: s.position.x,
|
|
||||||
y1: s.position.y,
|
|
||||||
x2: s.position.x + s.velocity.x,
|
|
||||||
y2: s.position.y + s.velocity.y
|
|
||||||
};
|
|
||||||
|
|
||||||
const baseVelIntxn = lineIntxnPt(baseLine, velocityLine);
|
|
||||||
const baseSegLength = distance(baseNrmlIntxn.x, baseNrmlIntxn.y , baseVelIntxn.x, baseVelIntxn.y);
|
|
||||||
const normalSegLength = distance(baseNrmlIntxn.x, baseNrmlIntxn.y, s.position.x, s.position.y);
|
|
||||||
console.log("distance", baseSegLength);
|
|
||||||
const theta = Math.atan(normalSegLength / baseSegLength);
|
|
||||||
console.log("theta", theta);
|
|
||||||
// const contactPos = { x: Math.acos() }
|
|
||||||
const h = 5 / Math.sin(theta);
|
|
||||||
console.log("h", 5 / Math.sin(theta));
|
|
||||||
console.log("cos(theta)", Math.cos(theta));
|
|
||||||
el.setAttribute('x2', intx.x);
|
|
||||||
el.setAttribute('y2', intx.y);
|
|
||||||
el.setAttribute('x1', currentPos.x);
|
|
||||||
el.setAttribute('y1', currentPos.y);
|
|
||||||
|
|
||||||
console.log("normal line length at current position", el.getTotalLength());
|
|
||||||
el.setAttribute('x1', futurePos.x);
|
|
||||||
el.setAttribute('y1', futurePos.y);
|
|
||||||
|
|
||||||
console.log("normal line length at future position", el.getTotalLength());
|
|
||||||
|
|
||||||
el.setAttribute('x1', s.position.x);
|
|
||||||
el.setAttribute('y1', s.position.y);
|
|
||||||
|
|
||||||
star.setAttribute('cx', s.position.x);
|
|
||||||
star.setAttribute('cy', baseVelIntxn.y - h);
|
|
||||||
|
|
||||||
el.setAttribute('id', `normal${xa}-${ya}-${xb}-${yb}`);
|
|
||||||
g.appendChild(el);
|
|
||||||
g.appendChild(star);
|
|
||||||
linesContainer.appendChild(g);
|
|
||||||
|
|
||||||
const cl = document.createElementNS(namespaceURIsvg, 'line');
|
|
||||||
cl.setAttribute('x1', baseVelIntxn.x);
|
|
||||||
cl.setAttribute('y1', baseVelIntxn.y);
|
|
||||||
cl.setAttribute('x2', s.position.x);
|
|
||||||
cl.setAttribute('y2', s.position.y);
|
|
||||||
const clPt = cl.getPointAtLength(h);
|
|
||||||
console.log(clPt);
|
|
||||||
|
|
||||||
star.setAttribute('cx', clPt.x);
|
|
||||||
star.setAttribute('cy', clPt.y);
|
|
||||||
|
|
||||||
|
if (baseSlope === -Infinity || baseSlope === Infinity) {
|
||||||
|
isx = xa;
|
||||||
|
isy = position.y;
|
||||||
|
} else if (baseSlope === 0) { // base is horizontal
|
||||||
|
isx = position.x;
|
||||||
|
isy = ya;
|
||||||
|
} else {
|
||||||
|
// const clPt = collisionPosition({ xa, ya, xb, yb }, position, velocity);
|
||||||
|
// console.log(clPt);
|
||||||
|
// isx = clPt.x;
|
||||||
|
// isy = clPt.y;
|
||||||
|
star.setAttribute('cx', 0);
|
||||||
|
star.setAttribute('cy', 0);
|
||||||
|
}
|
||||||
|
|
||||||
return g;
|
return g;
|
||||||
});
|
});
|
||||||
@@ -740,7 +719,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function animate(timestamp) {
|
function animate(timestamp) {
|
||||||
console.log("current timestamp", timestamp, "previous", previous);
|
// console.log("current timestamp", timestamp, "previous", previous);
|
||||||
|
|
||||||
const elapsed = timestamp - previous;
|
const elapsed = timestamp - previous;
|
||||||
const delta = timestamp - zero;
|
const delta = timestamp - zero;
|
||||||
@@ -762,10 +741,12 @@
|
|||||||
frameCount++;
|
frameCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// console.log("COLLISION EDGES", edgeszz);
|
||||||
updateShip(s, elapsed, edgeszz);
|
updateShip(s, elapsed, edgeszz);
|
||||||
updateBullets(elapsed);
|
updateBullets(elapsed);
|
||||||
// updateEdges(position);
|
// updateEdges(position);
|
||||||
// if (!s.collision) updateLines(elapsed, collE, {x, y}, s.position);
|
// if (!s.collision) updateLines(elapsed, edgeszz, s.position, s.velocity);
|
||||||
if (drawCollisionLines) updateTriangles(position);
|
if (drawCollisionLines) updateTriangles(position);
|
||||||
|
|
||||||
if (s.collision && !s.isLanded) {
|
if (s.collision && !s.isLanded) {
|
||||||
@@ -864,6 +845,10 @@
|
|||||||
case "KeyP": // Pause
|
case "KeyP": // Pause
|
||||||
started = !started;
|
started = !started;
|
||||||
break;
|
break;
|
||||||
|
case "KeyG": // Landing gear
|
||||||
|
legs.style.display = !legs.style.display || legs.style.display === "none" ? "initial" : "none";
|
||||||
|
s.gearDown = !s.gearDown;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 29 KiB |
Reference in New Issue
Block a user