Browse Source

Continuously traveling trains

Tyler Hallada 6 years ago
parent
commit
35e3f8f3a3
2 changed files with 32 additions and 23 deletions
  1. 25 23
      src/transport.ts
  2. 7 0
      src/utils.ts

+ 25 - 23
src/transport.ts

@@ -2,12 +2,17 @@ import * as PIXI from 'pixi.js';
2 2
 import Line from './Line';
3 3
 import Station from './Station';
4 4
 import Train from './Train';
5
-import { distance, pointsEqual, randomInt, randomPoint, weightedRandom } from './utils';
5
+import { distance, pointsAlmostEqual, pointsEqual, randomInt, randomPoint,
6
+         weightedRandom } from './utils';
6 7
 
7 8
 import './style.css';
8 9
 
9
-const maxSpeed = 10.0;
10
-const acceleration = 0.25;
10
+const MAX_SPEED = 10.0;
11
+const ACCELERATION = 0.025;
12
+const APPROACH_DISTANCE = 3.0;
13
+const MAX_JOURNEY = Math.floor(Math.sqrt(
14
+  Math.pow(window.innerWidth, 2) + Math.pow(window.innerHeight, 2),
15
+) / 4);
11 16
 
12 17
 const trainTexts: PIXI.Text[] = [];
13 18
 
@@ -53,8 +58,10 @@ const initTrains = (numTrains: number, stations: Station[]): Train[] => {
53 58
   const trains = [];
54 59
   for (let i = 0; i < numTrains; i += 1) {
55 60
     const originStation = stations[Math.floor(Math.random() * stations.length)];
56
-    // const destStation = stations[Math.floor(Math.random() * stations.length)];
57
-    trains.push(new Train(originStation.location, 0, 0, originStation, undefined));
61
+    trains.push(new Train(
62
+      new PIXI.Point(originStation.location.x, originStation.location.y),
63
+      0, 0, originStation, undefined),
64
+    );
58 65
   }
59 66
   return trains;
60 67
 };
@@ -63,34 +70,34 @@ const moveTrains = (trains: Train[], stations: Station[]) => {
63 70
   for (const train of trains) {
64 71
     // choose a destination randomly with a bias towards larger stations
65 72
     if (train.destination === undefined) {
66
-      const closeStations = Station.stationsWithinRadius(stations, train.location, 500);
73
+      const closeStations = Station.stationsWithinRadius(stations, train.location, MAX_JOURNEY);
67 74
       const closeStationWeights = closeStations.map(station => station.population);
68 75
       train.destination = weightedRandom(closeStations, closeStationWeights);
69 76
     }
70 77
 
71 78
     // train reached destination, stop moving.
72
-    if (pointsEqual(train.location, train.destination.location)) {
79
+    if (pointsAlmostEqual(train.location, train.destination.location)) {
73 80
       train.speed = 0;
81
+      train.origin = train.destination;
82
+      train.destination = undefined;
74 83
       continue;
75 84
     }
76 85
 
77 86
     const journeyLeft = distance(train.location, train.destination.location);
78
-    // speeding up
79
-    if (train.speed < maxSpeed) {
80
-      train.speed += acceleration;
81
-    }
82 87
 
83
-    // slowing down
84
-    if ((train.speed / acceleration) >= (journeyLeft / train.speed)) {
85
-      train.speed -= acceleration;
88
+    if ((train.speed / ACCELERATION) >= ((journeyLeft / train.speed) - APPROACH_DISTANCE) &&
89
+        train.speed !== ACCELERATION) {
90
+      // slowing down
91
+      train.speed -= ACCELERATION;
92
+    } else if (train.speed < MAX_SPEED) {
93
+      // speeding up
94
+      train.speed += ACCELERATION;
86 95
     }
87 96
 
88 97
     // advance train
89 98
     const progress = train.speed / journeyLeft;
90
-    train.location = new PIXI.Point(
91
-      train.location.x + ((train.destination.location.x - train.location.x) * progress),
92
-      train.location.y + ((train.destination.location.y - train.location.y) * progress),
93
-    );
99
+    train.location.x += ((train.destination.location.x - train.location.x) * progress);
100
+    train.location.y += ((train.destination.location.y - train.location.y) * progress);
94 101
   }
95 102
 };
96 103
 
@@ -124,11 +131,6 @@ const run = () => {
124 131
   fpsText.x = window.innerWidth;
125 132
   fpsText.y = 0;
126 133
 
127
-  // make these const
128
-  // let stations = initStations(30);
129
-  // let trains = initTrains(15, stations);
130
-  // let line = new Line(stations, 10);
131
-
132 134
   const stations = initStations(30);
133 135
   const trains = initTrains(15, stations);
134 136
 

+ 7 - 0
src/utils.ts

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