begin work on proper framework
This commit is contained in:
145
train/train.ts
Normal file
145
train/train.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
import { drawLine } from "../drawing/line.ts";
|
||||
import { ComplexPath, PathSegment } from "../math/path.ts";
|
||||
import { Vector } from "doodler";
|
||||
import { Follower } from "../physics/follower.ts";
|
||||
import { Mover } from "../physics/mover.ts";
|
||||
import { Spline, Track } from "../track.ts";
|
||||
|
||||
export class Train {
|
||||
nodes: Vector[] = [];
|
||||
|
||||
cars: TrainCar[] = [];
|
||||
|
||||
path: Spline<Track>;
|
||||
t: number;
|
||||
|
||||
engineLength = 40;
|
||||
spacing = 30;
|
||||
|
||||
speed = 0;
|
||||
|
||||
constructor(track: Spline<Track>, cars: TrainCar[] = []) {
|
||||
this.path = track;
|
||||
this.t = 0;
|
||||
this.nodes.push(this.path.followEvenPoints(this.t));
|
||||
this.nodes.push(this.path.followEvenPoints(this.t - this.real2Track(40)));
|
||||
const engineSprites = document.getElementById(
|
||||
"engine-sprites",
|
||||
)! as HTMLImageElement;
|
||||
this.cars.push(
|
||||
new TrainCar(
|
||||
55,
|
||||
engineSprites,
|
||||
80,
|
||||
20,
|
||||
{ at: new Vector(0, 60), width: 80, height: 20 },
|
||||
),
|
||||
new TrainCar(
|
||||
25,
|
||||
engineSprites,
|
||||
40,
|
||||
20,
|
||||
{ at: new Vector(80, 0), width: 40, height: 20 },
|
||||
),
|
||||
);
|
||||
this.cars[0].points = this.nodes.map((n) => n) as [Vector, Vector];
|
||||
this.cars[1].points = this.nodes.map((n) => n) as [Vector, Vector];
|
||||
let currentOffset = 40;
|
||||
for (const car of cars) {
|
||||
currentOffset += this.spacing;
|
||||
const a = this.path.followEvenPoints(this.t - currentOffset);
|
||||
currentOffset += car.length;
|
||||
const b = this.path.followEvenPoints(this.t - currentOffset);
|
||||
car.points = [a, b];
|
||||
this.cars.push(car);
|
||||
}
|
||||
}
|
||||
|
||||
move(dTime: number) {
|
||||
this.t = (this.t + this.speed * dTime * 10) % this.path.evenPoints.length;
|
||||
// console.log(this.t);
|
||||
let currentOffset = 0;
|
||||
for (const car of this.cars) {
|
||||
if (!car.points) return;
|
||||
const [a, b] = car.points;
|
||||
a.set(this.path.followEvenPoints(this.t - currentOffset));
|
||||
currentOffset += car.length;
|
||||
b.set(this.path.followEvenPoints(this.t - currentOffset));
|
||||
currentOffset += this.spacing;
|
||||
car.draw();
|
||||
}
|
||||
// this.draw();
|
||||
}
|
||||
|
||||
// draw() {
|
||||
// for (const [i, node] of this.nodes.entries()) {
|
||||
// doodler.drawCircle(node.point, 10, { color: 'purple', weight: 3 })
|
||||
// // const next = this.nodes[i + 1];
|
||||
// // if (next) {
|
||||
// // const to = Vector.sub(node.point, next.point);
|
||||
// // to.setMag(40);
|
||||
// // doodler.line(next.point, Vector.add(to, next.point))
|
||||
// // }
|
||||
// }
|
||||
// }
|
||||
|
||||
real2Track(length: number) {
|
||||
return length / this.path.pointSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
export class TrainCar {
|
||||
img: HTMLImageElement;
|
||||
imgWidth: number;
|
||||
imgHeight: number;
|
||||
sprite?: ISprite;
|
||||
|
||||
points?: [Vector, Vector];
|
||||
length: number;
|
||||
|
||||
constructor(
|
||||
length: number,
|
||||
img: HTMLImageElement,
|
||||
w: number,
|
||||
h: number,
|
||||
sprite?: ISprite,
|
||||
) {
|
||||
this.img = img;
|
||||
this.sprite = sprite;
|
||||
this.imgWidth = w;
|
||||
this.imgHeight = h;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
draw() {
|
||||
if (!this.points) return;
|
||||
const [a, b] = this.points;
|
||||
const origin = Vector.add(Vector.sub(a, b).div(2), b);
|
||||
const angle = Vector.sub(b, a).heading();
|
||||
|
||||
doodler.drawCircle(origin, 4, { color: "blue" });
|
||||
|
||||
doodler.drawRotated(origin, angle, () => {
|
||||
this.sprite
|
||||
? doodler.drawSprite(
|
||||
this.img,
|
||||
this.sprite.at,
|
||||
this.sprite.width,
|
||||
this.sprite.height,
|
||||
origin.copy().sub(this.imgWidth / 2, this.imgHeight / 2),
|
||||
this.imgWidth,
|
||||
this.imgHeight,
|
||||
)
|
||||
: doodler.drawImage(
|
||||
this.img,
|
||||
origin.copy().sub(this.imgWidth / 2, this.imgHeight / 2),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
interface ISprite {
|
||||
at: Vector;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
Reference in New Issue
Block a user