Add TypeScript, generate stations and a line

This commit is contained in:
2018-04-05 22:41:19 -04:00
parent 434578cebc
commit edae3f76f4
12 changed files with 430 additions and 37 deletions

42
src/Line.ts Normal file
View File

@@ -0,0 +1,42 @@
import Station from './Station';
import { distance, randomInt, randomPoint } from './utils';
const largestStation = (stations: Station[]): Station => {
let largest: Station = null;
for (const station of stations) {
if (largest === null || station.population > largest.population) {
largest = station;
}
}
return largest;
};
const stationsWithinRadius = (stations: Station[], point: PIXI.Point,
radius: number): Station[] => (
stations.filter(station => distance(point, station.location) <= radius)
);
const closestStations = (stations: Station[], point: PIXI.Point, num: number): Station[] => {
// bleh, i'm done
return stations;
};
export default class Line {
public stations: Station[];
constructor(stations: Station[], numStations: number) {
this.stations = [];
let stationsLeft = stations;
let largest = largestStation(stationsLeft);
stationsLeft = stationsLeft.filter(s => s !== largest);
this.stations.push(largest);
while (this.stations.length < numStations) {
largest = largestStation(stationsWithinRadius(stationsLeft, largest.location, 500));
if (largest === null) {
break;
}
stationsLeft = stationsLeft.filter(s => s !== largest);
this.stations.push(largest);
}
}
}

11
src/Station.ts Normal file
View File

@@ -0,0 +1,11 @@
export default class Station {
public location: PIXI.Point;
public population: number;
public connections: Station[];
constructor(location: PIXI.Point, population: number, connections?: Station[]) {
this.location = location;
this.population = population;
this.connections = connections;
}
}

23
src/Train.ts Normal file
View File

@@ -0,0 +1,23 @@
import Station from './Station';
export default class Train {
public location: PIXI.Point;
public speed: number;
public origin: Station;
public destination: Station;
public passengers: number;
constructor(location: PIXI.Point, speed: number, passengers: number, origin: Station,
destination: Station) {
this.location = location;
this.speed = speed;
this.origin = origin;
this.destination = destination;
this.passengers = passengers;
}
public boardPassengers() {
if (this.location === this.origin.location) { // about to leave a station
}
}
}

View File

@@ -1,30 +0,0 @@
import * as PIXI from 'pixi.js';
import { randomInt } from './utils';
import './style.css';
const app = new PIXI.Application(window.innerWidth, window.innerHeight);
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.Point(1, 0);
fpsText.x = window.innerWidth - 1;
fpsText.y = 0;
ticker.stop();
ticker.add((deltaTime) => {
fpsText.setText(Math.round(ticker.FPS));
graphics.lineStyle(1, 0xaeaeae, 1);
graphics.moveTo(randomInt(9, window.innerWidth), randomInt(0, window.innerHeight));
graphics.lineTo(randomInt(9, window.innerWidth), randomInt(0, window.innerHeight));
});
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);
});

106
src/transport.ts Normal file
View File

@@ -0,0 +1,106 @@
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();

View File

@@ -1,4 +0,0 @@
export const randomInt = (min, max) => (
// inclusive of min and max
Math.floor(Math.random() * (max - (min + 1))) + min
);

16
src/utils.ts Normal file
View File

@@ -0,0 +1,16 @@
import * as PIXI from 'pixi.js';
export const randomInt = (min: number, max: number): number => (
// inclusive of min and max
Math.floor(Math.random() * (max - (min + 1))) + min
);
export const randomPoint = () => (
new PIXI.Point(randomInt(0, window.innerWidth), randomInt(0, window.innerHeight))
);
export const distance = (pointA: PIXI.Point, pointB: PIXI.Point): number => {
const distX = pointA.x - pointB.x;
const distY = pointA.y - pointB.y;
return Math.sqrt((distX * distX) + (distY * distY));
};