First iteration of the Large Lady

This commit is contained in:
Emmaline Autumn 2025-02-16 14:22:17 -07:00
parent 9587ce5ae6
commit eb680c470f
5 changed files with 129 additions and 4 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -36,6 +36,7 @@ export class LoadState extends State<States> {
// This should be driven by a manifest
resources.set("snr:sprite/engine", new Image());
resources.set("snr:sprite/LargeLady", new Image());
// resources.get<HTMLImageElement>("snr:sprite/engine")!.src =
// "/sprites/EngineSprites.png";
resources.ready().then(() => {

View File

@ -8,6 +8,7 @@ import { DotFollower } from "../../train/newTrain.ts";
import { Train } from "../../train/train.ts";
import { State } from "../machine.ts";
import { States } from "./index.ts";
import { LargeLady } from "../../train/LargeLady.ts";
export class RunningState extends State<States> {
override name: States = States.RUNNING;
@ -58,9 +59,11 @@ export class RunningState extends State<States> {
// const path = track.path;
// const follower = new DotFollower(path, path.points[0].copy());
// ctx.trains.push(follower);
const train = new Train(track.path, [new RedEngine(), new Tender()]);
ctx.trains.push(train);
// const train = new Train(track.path, [new LargeLady(), new Tender()]);
// ctx.trains.push(train);
});
const train = new Train(track.path, [new LargeLady()], 1080);
ctx.trains.push(train);
// const trainCount = 1000;
// for (let i = 0; i < trainCount; i++) {
// const train = new Train(track.path, [new RedEngine(), new Tender()]);

118
src/train/LargeLady.ts Normal file
View File

@ -0,0 +1,118 @@
import { Doodler, Vector } from "@bearmetal/doodler";
import { TrainCar } from "./train.ts";
import { getContextItem } from "../lib/context.ts";
import { ResourceManager } from "../lib/resources.ts";
export class LargeLady extends TrainCar {
scale = 1;
constructor() {
const resources = getContextItem<ResourceManager>("resources");
const img = resources.get<HTMLImageElement>("snr:sprite/LargeLady")!;
super(50, 10, img, 160, 23, {
at: new Vector(0, 0),
width: 160,
height: 23,
});
this.bogies = [
{
pos: new Vector(0, 0),
angle: 0,
length: 35 * this.scale,
sprite: {
at: new Vector(0, 23),
width: 33,
height: 19,
offset: new Vector(-19, -9),
},
},
{
pos: new Vector(0, 0),
angle: 0,
length: 64 * this.scale,
// sprite: {
// at: new Vector(0, 23),
// width: 33,
// height: 19,
// offset: new Vector(-19, -9.5),
// },
sprite: {
at: new Vector(34, 23),
width: 51,
height: 19,
offset: new Vector(-25.5, -9.5),
},
},
{
pos: new Vector(0, 0),
angle: 0,
length: 35 * this.scale,
sprite: {
at: new Vector(34, 23),
width: 60,
height: 19,
offset: new Vector(-25.5, -9.5),
},
rotate: true,
},
{
pos: new Vector(0, 0),
angle: 0,
length: 0,
sprite: {
at: new Vector(95, 23),
width: 16,
height: 19,
offset: new Vector(-8, -9.5),
},
},
];
}
override draw(): void {
const doodler = getContextItem<Doodler>("doodler");
for (const b of this.bogies) {
if (!b.sprite) continue;
doodler.drawRotated(b.pos, b.angle + (b.rotate ? 0 : Math.PI), () => {
doodler.drawSprite(
this.img,
b.sprite!.at,
b.sprite!.width,
b.sprite!.height,
b.pos.copy().add(b.sprite!.offset ?? new Vector(0, 0)),
b.sprite!.width,
b.sprite!.height,
);
});
}
const c = this.bogies[2];
const b = this.bogies[1];
const origin = c.pos.copy().add(new Vector(18, 0).rotate(c.angle));
const difAngle = Vector.sub(b.pos, c.pos).heading();
const angle = c.angle;
const avgAngle = (difAngle + angle) / 2;
doodler.drawCircle(origin, 4, { color: "blue" });
doodler.drawRotated(origin, avgAngle + Math.PI, () => {
this.sprite
? doodler.drawSprite(
this.img,
this.sprite.at,
this.sprite.width,
this.sprite.height,
origin.copy().sub(
this.imgWidth * this.scale / 2,
this.imgHeight * this.scale / 2,
),
this.imgWidth * this.scale,
this.imgHeight * this.scale,
)
: doodler.drawImage(
this.img,
origin.copy().sub(this.imgWidth / 2, this.imgHeight / 2),
);
});
}
}

View File

@ -23,10 +23,10 @@ export class Train extends Debuggable {
);
}
constructor(track: Spline<TrackSegment>, cars: TrainCar[]) {
constructor(track: Spline<TrackSegment>, cars: TrainCar[], t = 0) {
super("train", "path");
this.path = track;
this.t = 0;
this.t = t;
this.cars = cars;
let currentOffset = 0;
@ -141,6 +141,8 @@ interface Bogie {
pos: Vector;
angle: number;
length: number;
sprite?: ISprite & { offset?: Vector };
rotate?: boolean;
}
export class TrainCar extends Debuggable {
@ -207,6 +209,7 @@ export class TrainCar extends Debuggable {
const a = this.train.path.followEvenPoints(t - offset);
offset += bogie.length;
this.setBogiePosition(a.p, i);
bogie.angle = a.tangent.heading();
this.segments.add(a.segmentId);
}
return offset;