207 lines
4.9 KiB
TypeScript
207 lines
4.9 KiB
TypeScript
import { lerp } from "./math/lerp.ts";
|
|
import { ComplexPath, PathSegment } from "./math/path.ts";
|
|
import { Vector } from "./math/vector.ts";
|
|
import { Mover } from "./physics/mover.ts";
|
|
import { Train } from "./train.ts";
|
|
import { fillCircle, drawCircle } from 'drawing';
|
|
import { generateSquareTrack } from "./track.ts";
|
|
import { drawLine } from "./drawing/line.ts";
|
|
import { hello } from 'doodler';
|
|
|
|
hello();
|
|
|
|
const canvas = document.createElement('canvas');
|
|
canvas.height = 400;
|
|
canvas.width = 400;
|
|
document.body.append(canvas);
|
|
const ctx = canvas.getContext('2d')!;
|
|
|
|
// for (const mover of trains) {
|
|
// mover.setContext(ctx);
|
|
// mover.velocity.add(Vector.random2D())
|
|
// }
|
|
|
|
const clear = () => {
|
|
ctx.fillStyle = 'black';
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height)
|
|
}
|
|
|
|
const fps = 60;
|
|
|
|
setInterval(() => {
|
|
// for (const train of trains) {
|
|
// train.move();
|
|
// }
|
|
draw();
|
|
}, 1000 / fps);
|
|
|
|
|
|
// const path = new PathSegment([new Vector(20, 20), new Vector(200, 100), new Vector(200, 300), new Vector(20, 380)]);
|
|
const path = generateSquareTrack();
|
|
path.setContext(ctx);
|
|
// const train = new Train(path.segments[0], 4);
|
|
// train.setContext(ctx);
|
|
// train.velocity.x = -1;
|
|
// train.velocity.y = 1;
|
|
|
|
const controls = {
|
|
ArrowUp: false,
|
|
ArrowRight: false,
|
|
ArrowDown: false,
|
|
ArrowLeft: false,
|
|
}
|
|
|
|
let t = 0;
|
|
let currentSeg = 0;
|
|
|
|
const trainCount = 1;
|
|
const trains = Array(trainCount).fill(null).map((_, i) => new Train(path.segments[i % path.segments.length], 5));
|
|
for (const train of trains) {
|
|
train.setContext(ctx);
|
|
// train.maxSpeed = Math.random() * 5 + 1
|
|
}
|
|
|
|
function draw() {
|
|
clear();
|
|
path.draw();
|
|
|
|
// for (const control in controls) {
|
|
// if (controls.hasOwnProperty(control)) {
|
|
// const isActive = controls[control as keyof typeof controls];
|
|
// if (isActive) {
|
|
// const force = getSteeringForce(train, control);
|
|
// train.applyForce(force);
|
|
// }
|
|
// }
|
|
|
|
// if (Object.values(controls).every(c => !c)) {
|
|
// train.acceleration.set(0, 0)
|
|
// }
|
|
// }
|
|
|
|
// train.follow(path)
|
|
for (const train of trains) {
|
|
train.move();
|
|
}
|
|
// ctx.strokeStyle = 'orange';
|
|
|
|
ctx.strokeStyle = 'red';
|
|
ctx.lineWidth = 4;
|
|
const seg = path.segments[currentSeg];
|
|
const start = seg.getPointAtT(t);
|
|
const tan = seg.tangent(t).normalize().mult(25);
|
|
drawLine(ctx, start.x, start.y, start.x + tan.x, start.y + tan.y);
|
|
|
|
t += .01;
|
|
if (t > 1) {
|
|
t -= 1;
|
|
currentSeg = (currentSeg + 1) % path.segments.length;
|
|
}
|
|
}
|
|
|
|
// let wKeydown =false
|
|
|
|
// document.addEventListener('keydown', e => {
|
|
// if (e.key === 'w' && !wKeydown) {
|
|
// wKeydown = true;
|
|
// for (const train of trains) {
|
|
// train.acceleration.add(.1, 0);
|
|
// }
|
|
// }
|
|
// });
|
|
// document.addEventListener('keyup', e => {
|
|
// if (e.key === 'w') {
|
|
// wKeydown = false;
|
|
// for (const train of trains) {
|
|
// train.acceleration.sub(.1, 0);
|
|
// }
|
|
// }
|
|
// });
|
|
// let sKeydown = false;
|
|
// document.addEventListener('keydown', e => {
|
|
// if (e.key === 's' && !sKeydown) {
|
|
// sKeydown = true;
|
|
// for (const train of trains) {
|
|
// train.acceleration.sub(.1, 0);
|
|
// }
|
|
// }
|
|
// });
|
|
// document.addEventListener('keyup', e => {
|
|
// if (e.key === 's') {
|
|
// sKeydown = false;
|
|
// for (const train of trains) {
|
|
// train.acceleration.add(.1, 0);
|
|
// }
|
|
// }
|
|
// });
|
|
|
|
document.addEventListener('keyup', e => {
|
|
if (e.key === 'd') {
|
|
console.log(trains)
|
|
}
|
|
|
|
if (e.key === 'ArrowUp') {
|
|
for (const train of trains) {
|
|
train.speed += .1;
|
|
}
|
|
}
|
|
if (e.key === 'ArrowDown') {
|
|
for (const train of trains) {
|
|
train.speed -= .1;
|
|
}
|
|
}
|
|
|
|
if (e.key === 'e') {
|
|
for (const t of path.segments) {
|
|
t.editable = !t.editable;
|
|
}
|
|
}
|
|
})
|
|
|
|
// 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);
|
|
}
|
|
}) |