Browse Source

Station and train colors

Tyler Hallada 6 years ago
parent
commit
902645d46a
3 changed files with 57 additions and 19 deletions
  1. 3 1
      src/Station.ts
  2. 39 18
      src/transport.ts
  3. 15 0
      src/utils.ts

+ 3 - 1
src/Station.ts

@@ -30,10 +30,12 @@ export default class Station {
30 30
   public connections: Station[];
31 31
   public id: number;
32 32
   public label: PIXI.Text;
33
+  public color: number;
33 34
 
34
-  constructor(location: PIXI.Point, population: number, connections?: Station[]) {
35
+  constructor(location: PIXI.Point, population: number, color: number, connections?: Station[]) {
35 36
     this.location = location;
36 37
     this.population = population;
38
+    this.color = color;
37 39
     this.connections = connections;
38 40
 
39 41
     // for debugging

+ 39 - 18
src/transport.ts

@@ -2,8 +2,8 @@ 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, pointsAlmostEqual, pointsEqual, randomInt, randomPoint,
6
-         weightedRandom } from './utils';
5
+import { avgHexColor, distance, pointsAlmostEqual, pointsEqual, randomInt, randomPoint,
6
+         rangeMap, weightedRandom } from './utils';
7 7
 
8 8
 import './style.css';
9 9
 
@@ -13,6 +13,7 @@ const APPROACH_DISTANCE = 3.0;
13 13
 const MAX_JOURNEY = Math.floor(Math.sqrt(
14 14
   Math.pow(window.innerWidth, 2) + Math.pow(window.innerHeight, 2),
15 15
 ) / 4);
16
+const TRAIN_CAPACITY = 50;
16 17
 
17 18
 const trainTexts: PIXI.Text[] = [];
18 19
 
@@ -40,20 +41,14 @@ const randomDistantPoint = (stations: Station[], minDistance: number): PIXI.Poin
40 41
 const initStations = (numStations: number): Station[] => {
41 42
   const stations: Station[] = [];
42 43
   for (let i = 0; i < numStations; i += 1) {
43
-    stations.push(new Station(randomDistantPoint(stations, 30), randomInt(100, 1000)));
44
+    stations.push(new Station(
45
+      randomDistantPoint(stations, 30),
46
+      randomInt(300, 2000),
47
+      randomInt(0x000000, 0xFFFFFF)));
44 48
   }
45 49
   return stations;
46 50
 };
47 51
 
48
-const drawStations = (stations: Station[], graphics: PIXI.Graphics) => {
49
-  for (const station of stations) {
50
-    const radius = station.population / 60;
51
-    graphics.drawCircle(station.location.x, station.location.y, radius);
52
-    station.label.x = station.location.x + radius + 1;
53
-    station.label.y = station.location.y + radius + 1;
54
-  }
55
-};
56
-
57 52
 const initTrains = (numTrains: number, stations: Station[]): Train[] => {
58 53
   const trains = [];
59 54
   for (let i = 0; i < numTrains; i += 1) {
@@ -75,11 +70,22 @@ const moveTrains = (trains: Train[], stations: Station[]) => {
75 70
                                                          MAX_JOURNEY);
76 71
       const closeStationWeights = closeStations.map(station => station.population);
77 72
       train.destination = weightedRandom(closeStations, closeStationWeights);
73
+
74
+      // board passengers
75
+      train.passengers += randomInt(0, TRAIN_CAPACITY);
76
+      train.origin.population -= randomInt(0, TRAIN_CAPACITY);
78 77
     }
79 78
 
80
-    // train reached destination, stop moving.
79
+    // train reached destination, stop moving and let passengers off
81 80
     if (pointsAlmostEqual(train.location, train.destination.location)) {
82 81
       train.speed = 0;
82
+      train.destination.population += train.passengers;
83
+      train.passengers = 0;
84
+
85
+      // TODO: average colors
86
+      // train.destination.color = avgHexColor(train.origin.color, train.destination.color);
87
+
88
+      // prepare for next journey
83 89
       train.origin = train.destination;
84 90
       train.destination = undefined;
85 91
       continue;
@@ -103,9 +109,23 @@ const moveTrains = (trains: Train[], stations: Station[]) => {
103 109
   }
104 110
 };
105 111
 
112
+const drawStations = (stations: Station[], graphics: PIXI.Graphics) => {
113
+  for (const station of stations) {
114
+    const radius = station.population / 60;
115
+    graphics.beginFill(station.color, 0.5);
116
+    graphics.drawCircle(station.location.x, station.location.y, radius);
117
+    graphics.endFill();
118
+    station.label.x = station.location.x + radius + 1;
119
+    station.label.y = station.location.y + radius + 1;
120
+  }
121
+};
122
+
106 123
 const drawTrains = (trains: Train[], graphics: PIXI.Graphics) => {
107 124
   for (const train of trains) {
108
-    graphics.drawCircle(train.location.x, train.location.y, 2);
125
+    graphics.beginFill(train.origin.color, 0.8);
126
+    graphics.drawCircle(train.location.x, train.location.y,
127
+                        rangeMap(train.passengers, 0, TRAIN_CAPACITY, 1, 5));
128
+    graphics.endFill();
109 129
     train.label.x = train.location.x + 1;
110 130
     train.label.y = train.location.y + 1;
111 131
   }
@@ -134,7 +154,8 @@ const run = () => {
134 154
   fpsText.y = 0;
135 155
 
136 156
   const stations = initStations(30);
137
-  const trains = initTrains(15, stations);
157
+  const trains = initTrains(100, stations);
158
+  // const line = new Line(stations, 10);
138 159
 
139 160
   ticker.stop();
140 161
   ticker.add((deltaTime) => {
@@ -157,9 +178,9 @@ const run = () => {
157 178
   app.stage.addChild(graphics);
158 179
   app.stage.addChild(fpsText);
159 180
   // Add debug labels
160
-  for (const train of trains) {
161
-    app.stage.addChild(train.label);
162
-  }
181
+  // for (const train of trains) {
182
+    // app.stage.addChild(train.label);
183
+  // }
163 184
   for (const station of stations) {
164 185
     app.stage.addChild(station.label);
165 186
   }

+ 15 - 0
src/utils.ts

@@ -37,3 +37,18 @@ export const distance = (pointA: PIXI.Point, pointB: PIXI.Point): number => {
37 37
   const distY = pointA.y - pointB.y;
38 38
   return Math.sqrt((distX * distX) + (distY * distY));
39 39
 };
40
+
41
+export const rangeMap = (num: number, inMin: number, inMax: number,
42
+                         outMin: number, outMax: number): number => (
43
+  (num - inMin) * (outMax - outMin) / (inMax - inMin) + outMin
44
+);
45
+
46
+// tslint:disable no-bitwise
47
+export const nthByte = (num: number, n: number): number => ((num >> (8 * n)) & 0xff);
48
+
49
+// FIXME: pretty sure this is wrong, just use a color library instead and then convert to hex
50
+export const avgHexColor = (colorA: number, colorB: number): number => (
51
+  (Math.round((nthByte(colorA, 2) + nthByte(colorB, 2)) / 2) & 0xFF) |
52
+  ((Math.round((nthByte(colorA, 1) + nthByte(colorB, 1)) / 2) & 0xFF) << 8) |
53
+  ((Math.round((nthByte(colorA, 0) + nthByte(colorB, 0)) / 2) & 0x0F) << 16)
54
+);