transport/src/transport.ts

107 lines
3.0 KiB
TypeScript

import * as PIXI from 'pixi.js';
import Line from './Line';
import Station from './Station';
import Train from './Train';
import { distance, randomInt, randomPoint } from './utils';
import './style.css';
const isPointDistant = (point: PIXI.Point, stations: Station[], minDistance: number): boolean => {
for (const station of stations) {
if (distance(point, station.location) < minDistance) {
return false;
}
}
return true;
};
const randomDistantPoint = (stations: Station[], minDistance: number): PIXI.Point | null => {
let tries = 100;
while (tries > 0) {
const point = randomPoint();
if (isPointDistant(point, stations, minDistance)) {
return point;
}
tries -= 1;
}
return null;
};
const initStations = (numStations: number): Station[] => {
const stations: Station[] = [];
for (let i = 0; i < numStations; i += 1) {
stations.push(new Station(randomDistantPoint(stations, 30), randomInt(100, 1000)));
}
return stations;
};
const drawStations = (stations: Station[], graphics: PIXI.Graphics) => {
for (const station of stations) {
graphics.drawCircle(station.location.x, station.location.y, station.population / 60);
}
};
const initTrains = (numTrains: number, stations: Station[]): Train[] => {
const trains = [];
for (let i = 0; i < numTrains; i += 1) {
const originStation = stations[Math.floor(Math.random() * stations.length)];
const destStation = stations[Math.floor(Math.random() * stations.length)];
trains.push(new Train(originStation.location, 0, 0, originStation, destStation));
}
return trains;
};
const drawLine = (line: Line, graphics: PIXI.Graphics) => {
const start = line.stations[0].location;
graphics.moveTo(start.x, start.y);
for (const station of line.stations.slice(1)) {
graphics.lineTo(station.location.x, station.location.y);
}
};
const run = () => {
const app = new PIXI.Application({
antialias: true,
height: window.innerHeight,
width: window.innerWidth,
});
const ticker = new PIXI.ticker.Ticker();
const graphics = new PIXI.Graphics();
const fpsText = new PIXI.Text('', { fontSize: '25px', fontFamily: 'monospace', fill: 'yellow' });
fpsText.anchor = new PIXI.ObservablePoint(null, 0, 1);
fpsText.x = window.innerWidth;
fpsText.y = 0;
// make these const
let stations = initStations(30);
let trains = initTrains(15, stations);
let line = new Line(stations, 10);
stations = initStations(30);
trains = initTrains(15, stations);
line = new Line(stations, 10);
ticker.stop();
ticker.add((deltaTime) => {
graphics.clear();
fpsText.text = `${Math.round(ticker.FPS)}`;
graphics.lineStyle(1, 0xaeaeae, 1);
drawStations(stations, graphics);
drawLine(line, graphics);
});
ticker.start();
app.stage.addChild(graphics);
app.stage.addChild(fpsText);
document.body.appendChild(app.view);
window.addEventListener('resize', () => {
app.renderer.resize(window.innerWidth, window.innerHeight);
});
};
run();