import { ComplexPath, PathSegment } from "../math/path.ts"; import { Follower } from "../physics/follower.ts"; import { Mover } from "../physics/mover.ts"; import { getContextItem } from "../lib/context.ts"; import { Doodler, Vector } from "@bearmetal/doodler"; import { Spline, TrackSegment } from "../track/system.ts"; import { ResourceManager } from "../lib/resources.ts"; export class Train { nodes: Vector[] = []; cars: TrainCar[] = []; path: Spline; t: number; engineLength = 40; spacing = 30; speed = 10; constructor(track: Spline, cars: TrainCar[]) { this.path = track; this.t = 0; const resources = getContextItem("resources"); this.cars = cars; // 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 }, // ), // ); let currentOffset = 0; try { for (const car of this.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.nodes.push(a, b); } } catch { currentOffset = 0; for (const car of this.cars.toReversed()) { 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.nodes.push(a, b); } } } move(dTime: number) { this.t = this.t + this.speed * dTime * 10; // % this.path.evenPoints.length; // This should probably be on the track system // 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() { // const doodler = getContextItem("doodler"); // this.path.draw(); // for (const [i, node] of this.nodes.entries()) { // // doodler.drawCircle(node, 10, { color: "purple", weight: 3 }); // doodler.fillCircle(node, 2, { color: "purple" }); // // 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)) // // } // } // } draw() { for (const car of this.cars) { car.draw(); } } 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 doodler = getContextItem("doodler"); 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; }