trainsim/main.ts
2023-02-08 11:53:11 -07:00

161 lines
4.0 KiB
TypeScript

import { lerp } from "./math/lerp.ts";
import { ComplexPath, PathSegment } from "./math/path.ts";
import { Mover } from "./physics/mover.ts";
import { Train } from "./train.ts";
import { fillCircle, drawCircle } from 'drawing';
import { generateSquareTrack, loadFromJson } from "./track.ts";
import { drawLine } from "./drawing/line.ts";
import { initializeDoodler, Vector } from 'doodler';
// for (const mover of trains) {
// mover.setContext(ctx);
// mover.velocity.add(Vector.random2D())
// }
initializeDoodler({
width: 400,
height: 400,
bg: '#333'
});
const path = loadFromJson();
const controls = {
ArrowUp: false,
ArrowRight: false,
ArrowDown: false,
ArrowLeft: false,
}
let t = 0;
let currentSeg = 0;
let speed = 1;
const trainCount = 1;
const trains = Array(trainCount).fill(null).map((_, i) => new Train(path.segments[i % path.segments.length], 5));
doodler.createLayer(() => {
path.draw();
// for (const train of trains) {
// train.move();
// }
// ctx.strokeStyle = 'red';
// ctx.lineWidth = 4;
// const seg = path.segments[currentSeg];
// const start = seg.getPointAtT(t);
// const tan = seg.tangent(t).normalize().mult(25);
// const tan = seg.tangent(t);
// for (const p of path.evenPoints) {
// p.drawDot();
// }
// doodler.line(start, new Vector(start.x + tan.x, start.y + tan.y), {color: 'blue'});
// doodler.fillCircle(start, 5, {fillColor: 'blue'})
const points = Array(5).fill(null).map((_,i) => path.followEvenPoints(t - (i * 15)))
for (const point of points) {
point &&
doodler.drawCircle(point, 5, { strokeColor: 'green' })
}
// const point = path.followEvenPoints(t);
t = (t + (speed / 2)) % path.evenPoints.length;
// path.segments.forEach(s => s.calculateApproxLength(10000))
})
document.addEventListener('keyup', e => {
if (e.key === 'd') {
// console.log(trains)
// console.log(path.segments.reduce((a,b) => a + b.calculateApproxLength(1000), 0))
// console.log(path.evenPoints);
}
if (e.key === 'ArrowUp') {
// for (const train of trains) {
// train.speed += .1;
// }
speed += .1
}
if (e.key === 'ArrowDown') {
// for (const train of trains) {
// train.speed -= .1;
// }
speed -= .1
}
if (e.key === 'e') {
for (const t of path.segments) {
t.editable = !t.editable;
for (const p of t.points) {
if (t.editable) {
doodler.registerDraggable(p, 10)
doodler.addDragEvents({
point: p,
onDragEnd: () => {
console.log('dragend');
t.length = t.calculateApproxLength(100)
path.evenPoints = path.calculateEvenlySpacedPoints(1)
}
})
}
else
doodler.unregisterDraggable(p)
}
}
}
})
// document.addEventListener('keydown', e => {
// const valid = ["ArrowUp",
// "ArrowRight",
// "ArrowDown",
// "ArrowLeft",]
// if (valid.includes(e.key))
// controls[e.key as keyof typeof controls] = true;
// })
// document.addEventListener('keyup', e => {
// const valid = ["ArrowUp",
// "ArrowRight",
// "ArrowDown",
// "ArrowLeft",]
// if (valid.includes(e.key))
// controls[e.key as keyof typeof controls] = false;
// })
// function getSteeringForce(mover: Mover, dir: string) {
// const dirs = {
// ArrowUp: 0,
// ArrowRight: .1 * Math.PI,
// ArrowDown: Math.PI,
// ArrowLeft: -.1 * Math.PI,
// }
// const target = mover.velocity.copy();
// target.normalize();
// target.mult(10);
// target.rotate(dirs[dir as keyof typeof dirs]);
// const force = Vector.sub(target, mover.velocity);
// force.limit(.1)
// return force;
// }
document.addEventListener('keydown', e => {
if (e.ctrlKey && e.key === 's') {
e.preventDefault();
path.segments.forEach((s: any) => {
s.next = s.next.id
s.prev = s.prev.id
delete s.ctx
})
delete path.ctx;
const json = JSON.stringify(path);
localStorage.setItem('railPath', json);
}
})