Add TypeScript, generate stations and a line
This commit is contained in:
42
src/Line.ts
Normal file
42
src/Line.ts
Normal 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
11
src/Station.ts
Normal 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
23
src/Train.ts
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
106
src/transport.ts
Normal 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();
|
||||
@@ -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
16
src/utils.ts
Normal 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));
|
||||
};
|
||||
Reference in New Issue
Block a user