|
@@ -2,10 +2,13 @@ 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, randomInt, randomPoint } from './utils';
|
|
5
|
+import { distance, pointsEqual, randomInt, randomPoint, weightedRandom } from './utils';
|
6
|
6
|
|
7
|
7
|
import './style.css';
|
8
|
8
|
|
|
9
|
+const maxSpeed = 10.0;
|
|
10
|
+const acceleration = 0.25;
|
|
11
|
+
|
9
|
12
|
const isPointDistant = (point: PIXI.Point, stations: Station[], minDistance: number): boolean => {
|
10
|
13
|
for (const station of stations) {
|
11
|
14
|
if (distance(point, station.location) < minDistance) {
|
|
@@ -45,12 +48,53 @@ const initTrains = (numTrains: number, stations: Station[]): Train[] => {
|
45
|
48
|
const trains = [];
|
46
|
49
|
for (let i = 0; i < numTrains; i += 1) {
|
47
|
50
|
const originStation = stations[Math.floor(Math.random() * stations.length)];
|
48
|
|
- const destStation = stations[Math.floor(Math.random() * stations.length)];
|
49
|
|
- trains.push(new Train(originStation.location, 0, 0, originStation, destStation));
|
|
51
|
+ // const destStation = stations[Math.floor(Math.random() * stations.length)];
|
|
52
|
+ trains.push(new Train(originStation.location, 0, 0, originStation, undefined));
|
50
|
53
|
}
|
51
|
54
|
return trains;
|
52
|
55
|
};
|
53
|
56
|
|
|
57
|
+const moveTrains = (trains: Train[], stations: Station[]) => {
|
|
58
|
+ for (const train of trains) {
|
|
59
|
+ // choose a destination randomly with a bias towards larger stations
|
|
60
|
+ if (train.destination === undefined) {
|
|
61
|
+ const closeStations = Station.stationsWithinRadius(stations, train.location, 500);
|
|
62
|
+ const closeStationWeights = closeStations.map(station => station.population);
|
|
63
|
+ train.destination = weightedRandom(closeStations, closeStationWeights);
|
|
64
|
+ }
|
|
65
|
+
|
|
66
|
+ // train reached destination, stop moving.
|
|
67
|
+ if (pointsEqual(train.location, train.destination.location)) {
|
|
68
|
+ train.speed = 0;
|
|
69
|
+ continue;
|
|
70
|
+ }
|
|
71
|
+
|
|
72
|
+ const journeyLeft = distance(train.location, train.destination.location);
|
|
73
|
+ // speeding up
|
|
74
|
+ if (train.speed < maxSpeed) {
|
|
75
|
+ train.speed += acceleration;
|
|
76
|
+ }
|
|
77
|
+
|
|
78
|
+ // slowing down
|
|
79
|
+ if ((train.speed / acceleration) >= (journeyLeft / train.speed)) {
|
|
80
|
+ train.speed -= acceleration;
|
|
81
|
+ }
|
|
82
|
+
|
|
83
|
+ // advance train
|
|
84
|
+ const progress = train.speed / journeyLeft;
|
|
85
|
+ train.location = new PIXI.Point(
|
|
86
|
+ train.location.x + (Math.abs(train.location.x - train.destination.location.x) * progress),
|
|
87
|
+ train.location.y + (Math.abs(train.location.y - train.destination.location.y) * progress),
|
|
88
|
+ );
|
|
89
|
+ }
|
|
90
|
+};
|
|
91
|
+
|
|
92
|
+const drawTrains = (trains: Train[], graphics: PIXI.Graphics) => {
|
|
93
|
+ for (const train of trains) {
|
|
94
|
+ graphics.drawCircle(train.location.x, train.location.y, 2);
|
|
95
|
+ }
|
|
96
|
+};
|
|
97
|
+
|
54
|
98
|
const drawLine = (line: Line, graphics: PIXI.Graphics) => {
|
55
|
99
|
const start = line.stations[0].location;
|
56
|
100
|
graphics.moveTo(start.x, start.y);
|
|
@@ -76,21 +120,22 @@ const run = () => {
|
76
|
120
|
// make these const
|
77
|
121
|
let stations = initStations(30);
|
78
|
122
|
let trains = initTrains(15, stations);
|
79
|
|
- let line = new Line(stations, 10);
|
|
123
|
+ // let line = new Line(stations, 10);
|
80
|
124
|
|
81
|
125
|
stations = initStations(30);
|
82
|
126
|
trains = initTrains(15, stations);
|
83
|
|
- line = new Line(stations, 10);
|
84
|
127
|
|
85
|
128
|
ticker.stop();
|
86
|
129
|
ticker.add((deltaTime) => {
|
|
130
|
+ moveTrains(trains, stations);
|
87
|
131
|
|
88
|
132
|
graphics.clear();
|
89
|
133
|
fpsText.text = `${Math.round(ticker.FPS)}`;
|
90
|
134
|
graphics.lineStyle(1, 0xaeaeae, 1);
|
91
|
135
|
|
92
|
136
|
drawStations(stations, graphics);
|
93
|
|
- drawLine(line, graphics);
|
|
137
|
+ drawTrains(trains, graphics);
|
|
138
|
+ // drawLine(line, graphics);
|
94
|
139
|
});
|
95
|
140
|
ticker.start();
|
96
|
141
|
|