Continuously traveling trains

This commit is contained in:
Tyler Hallada 2018-04-09 23:41:16 -04:00
parent 502f15f1ef
commit 35e3f8f3a3
2 changed files with 32 additions and 23 deletions

View File

@ -2,12 +2,17 @@ import * as PIXI from 'pixi.js';
import Line from './Line'; import Line from './Line';
import Station from './Station'; import Station from './Station';
import Train from './Train'; import Train from './Train';
import { distance, pointsEqual, randomInt, randomPoint, weightedRandom } from './utils'; import { distance, pointsAlmostEqual, pointsEqual, randomInt, randomPoint,
weightedRandom } from './utils';
import './style.css'; import './style.css';
const maxSpeed = 10.0; const MAX_SPEED = 10.0;
const acceleration = 0.25; const ACCELERATION = 0.025;
const APPROACH_DISTANCE = 3.0;
const MAX_JOURNEY = Math.floor(Math.sqrt(
Math.pow(window.innerWidth, 2) + Math.pow(window.innerHeight, 2),
) / 4);
const trainTexts: PIXI.Text[] = []; const trainTexts: PIXI.Text[] = [];
@ -53,8 +58,10 @@ const initTrains = (numTrains: number, stations: Station[]): Train[] => {
const trains = []; const trains = [];
for (let i = 0; i < numTrains; i += 1) { for (let i = 0; i < numTrains; i += 1) {
const originStation = stations[Math.floor(Math.random() * stations.length)]; const originStation = stations[Math.floor(Math.random() * stations.length)];
// const destStation = stations[Math.floor(Math.random() * stations.length)]; trains.push(new Train(
trains.push(new Train(originStation.location, 0, 0, originStation, undefined)); new PIXI.Point(originStation.location.x, originStation.location.y),
0, 0, originStation, undefined),
);
} }
return trains; return trains;
}; };
@ -63,34 +70,34 @@ const moveTrains = (trains: Train[], stations: Station[]) => {
for (const train of trains) { for (const train of trains) {
// choose a destination randomly with a bias towards larger stations // choose a destination randomly with a bias towards larger stations
if (train.destination === undefined) { if (train.destination === undefined) {
const closeStations = Station.stationsWithinRadius(stations, train.location, 500); const closeStations = Station.stationsWithinRadius(stations, train.location, MAX_JOURNEY);
const closeStationWeights = closeStations.map(station => station.population); const closeStationWeights = closeStations.map(station => station.population);
train.destination = weightedRandom(closeStations, closeStationWeights); train.destination = weightedRandom(closeStations, closeStationWeights);
} }
// train reached destination, stop moving. // train reached destination, stop moving.
if (pointsEqual(train.location, train.destination.location)) { if (pointsAlmostEqual(train.location, train.destination.location)) {
train.speed = 0; train.speed = 0;
train.origin = train.destination;
train.destination = undefined;
continue; continue;
} }
const journeyLeft = distance(train.location, train.destination.location); const journeyLeft = distance(train.location, train.destination.location);
// speeding up
if (train.speed < maxSpeed) {
train.speed += acceleration;
}
if ((train.speed / ACCELERATION) >= ((journeyLeft / train.speed) - APPROACH_DISTANCE) &&
train.speed !== ACCELERATION) {
// slowing down // slowing down
if ((train.speed / acceleration) >= (journeyLeft / train.speed)) { train.speed -= ACCELERATION;
train.speed -= acceleration; } else if (train.speed < MAX_SPEED) {
// speeding up
train.speed += ACCELERATION;
} }
// advance train // advance train
const progress = train.speed / journeyLeft; const progress = train.speed / journeyLeft;
train.location = new PIXI.Point( train.location.x += ((train.destination.location.x - train.location.x) * progress);
train.location.x + ((train.destination.location.x - train.location.x) * progress), train.location.y += ((train.destination.location.y - train.location.y) * progress);
train.location.y + ((train.destination.location.y - train.location.y) * progress),
);
} }
}; };
@ -124,11 +131,6 @@ const run = () => {
fpsText.x = window.innerWidth; fpsText.x = window.innerWidth;
fpsText.y = 0; fpsText.y = 0;
// make these const
// let stations = initStations(30);
// let trains = initTrains(15, stations);
// let line = new Line(stations, 10);
const stations = initStations(30); const stations = initStations(30);
const trains = initTrains(15, stations); const trains = initTrains(15, stations);

View File

@ -1,5 +1,7 @@
import * as PIXI from 'pixi.js'; import * as PIXI from 'pixi.js';
const EPSILON = 1.0;
export const randomInt = (min: number, max: number): number => ( export const randomInt = (min: number, max: number): number => (
// inclusive of min and max // inclusive of min and max
Math.floor(Math.random() * (max - (min + 1))) + min Math.floor(Math.random() * (max - (min + 1))) + min
@ -25,6 +27,11 @@ export const pointsEqual = (pointA: PIXI.Point, pointB: PIXI.Point): boolean =>
(pointA.x === pointB.x && pointA.y === pointB.y) (pointA.x === pointB.x && pointA.y === pointB.y)
); );
export const pointsAlmostEqual = (pointA: PIXI.Point, pointB: PIXI.Point): boolean => (
Math.abs(pointA.x - pointB.x) < EPSILON &&
Math.abs(pointA.y - pointB.y) < EPSILON
);
export const distance = (pointA: PIXI.Point, pointB: PIXI.Point): number => { export const distance = (pointA: PIXI.Point, pointB: PIXI.Point): number => {
const distX = pointA.x - pointB.x; const distX = pointA.x - pointB.x;
const distY = pointA.y - pointB.y; const distY = pointA.y - pointB.y;