From 35e3f8f3a38a844f5307490edf5490cafc78f7a6 Mon Sep 17 00:00:00 2001 From: Tyler Hallada Date: Mon, 9 Apr 2018 23:41:16 -0400 Subject: [PATCH] Continuously traveling trains --- src/transport.ts | 48 +++++++++++++++++++++++++----------------------- src/utils.ts | 7 +++++++ 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/transport.ts b/src/transport.ts index 89daca6..5930934 100644 --- a/src/transport.ts +++ b/src/transport.ts @@ -2,12 +2,17 @@ import * as PIXI from 'pixi.js'; import Line from './Line'; import Station from './Station'; import Train from './Train'; -import { distance, pointsEqual, randomInt, randomPoint, weightedRandom } from './utils'; +import { distance, pointsAlmostEqual, pointsEqual, randomInt, randomPoint, + weightedRandom } from './utils'; import './style.css'; -const maxSpeed = 10.0; -const acceleration = 0.25; +const MAX_SPEED = 10.0; +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[] = []; @@ -53,8 +58,10 @@ 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, undefined)); + trains.push(new Train( + new PIXI.Point(originStation.location.x, originStation.location.y), + 0, 0, originStation, undefined), + ); } return trains; }; @@ -63,34 +70,34 @@ const moveTrains = (trains: Train[], stations: Station[]) => { for (const train of trains) { // choose a destination randomly with a bias towards larger stations 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); train.destination = weightedRandom(closeStations, closeStationWeights); } // train reached destination, stop moving. - if (pointsEqual(train.location, train.destination.location)) { + if (pointsAlmostEqual(train.location, train.destination.location)) { train.speed = 0; + train.origin = train.destination; + train.destination = undefined; continue; } const journeyLeft = distance(train.location, train.destination.location); - // speeding up - if (train.speed < maxSpeed) { - train.speed += acceleration; - } - // slowing down - if ((train.speed / acceleration) >= (journeyLeft / train.speed)) { - train.speed -= acceleration; + if ((train.speed / ACCELERATION) >= ((journeyLeft / train.speed) - APPROACH_DISTANCE) && + train.speed !== ACCELERATION) { + // slowing down + train.speed -= ACCELERATION; + } else if (train.speed < MAX_SPEED) { + // speeding up + train.speed += ACCELERATION; } // advance train const progress = train.speed / journeyLeft; - train.location = new PIXI.Point( - train.location.x + ((train.destination.location.x - train.location.x) * progress), - train.location.y + ((train.destination.location.y - train.location.y) * progress), - ); + train.location.x += ((train.destination.location.x - train.location.x) * progress); + train.location.y += ((train.destination.location.y - train.location.y) * progress); } }; @@ -124,11 +131,6 @@ const run = () => { 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); - const stations = initStations(30); const trains = initTrains(15, stations); diff --git a/src/utils.ts b/src/utils.ts index ebbfbe6..c946193 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,7 @@ import * as PIXI from 'pixi.js'; +const EPSILON = 1.0; + export const randomInt = (min: number, max: number): number => ( // inclusive of min and max 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) ); +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 => { const distX = pointA.x - pointB.x; const distY = pointA.y - pointB.y;