Continuously traveling trains
This commit is contained in:
parent
502f15f1ef
commit
35e3f8f3a3
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// slowing down
|
if ((train.speed / ACCELERATION) >= ((journeyLeft / train.speed) - APPROACH_DISTANCE) &&
|
||||||
if ((train.speed / acceleration) >= (journeyLeft / train.speed)) {
|
train.speed !== ACCELERATION) {
|
||||||
train.speed -= acceleration;
|
// slowing down
|
||||||
|
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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user