- Timestamp:
- Apr 1, 2015, 1:21:27 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UEngine.pas
r18 r19 56 56 end; 57 57 58 { TTrackPoint } 59 58 60 TTrackPoint = class 59 61 Line: TMetroLine; … … 61 63 Point: TPoint; 62 64 Pending: Boolean; 65 function GetDown: TTrackPoint; 66 function GetUp: TTrackPoint; 63 67 end; 64 68 … … 75 79 76 80 TMetroLine = class 81 private 82 procedure UpdateEndingLines; 83 public 77 84 Engine: TEngine; 78 85 Color: TColor; … … 80 87 Trains: TMetroTrains; 81 88 TrackPoints: TTrackPoints; 82 procedure ConnectStation(Station: TMapStation );83 procedure DisconnectStation( Station: TMapStation);89 procedure ConnectStation(Station: TMapStation; LineStationDown, LineStationUp: TLineStation); 90 procedure DisconnectStation(LineStation: TLineStation); 84 91 procedure RouteTrack(TP1, TP2: TTrackPoint); 92 procedure RemoteTrackBetween(TP1, TP2: TTrackPoint); 85 93 function GetTrackLength: Integer; 86 94 function GetStationTrackPos(LineStation: TLineStation): Integer; … … 219 227 MetroLineThickness = 13; 220 228 TrackClickDistance = 20; 229 EndStationLength = 50; 221 230 222 231 implementation … … 224 233 uses 225 234 UGeometric; 235 236 { TTrackPoint } 237 238 function TTrackPoint.GetDown: TTrackPoint; 239 var 240 NewIndex: Integer; 241 begin 242 NewIndex := LineStation.Line.LineStations.IndexOf(LineStation) - 1; 243 if NewIndex >= 0 then Result := TLineStation(LineStation.Line.LineStations[NewIndex]).TrackPoint 244 else Result := nil; 245 end; 246 247 function TTrackPoint.GetUp: TTrackPoint; 248 var 249 NewIndex: Integer; 250 begin 251 NewIndex := LineStation.Line.LineStations.IndexOf(LineStation) + 1; 252 if NewIndex < LineStation.Line.LineStations.Count then 253 Result := TLineStation(LineStation.Line.LineStations[NewIndex]).TrackPoint 254 else Result := nil; 255 end; 226 256 227 257 { TLineStations } … … 332 362 { TMetroLine } 333 363 334 procedure TMetroLine.ConnectStation(Station: TMapStation); 364 procedure TMetroLine.UpdateEndingLines; 365 var 366 Index: Integer; 367 NewTrackPoint: TTrackPoint; 368 Angle: Double; 369 EndPoint: TPoint; 370 begin 371 if LineStations.Count >= 2 then begin 372 Index := TrackPoints.IndexOf(TLineStation(LineStations.First).TrackPoint); 373 if Index = 0 then begin 374 NewTrackPoint := TTrackPoint.Create; 375 NewTrackPoint.Line := Self; 376 TrackPoints.Insert(0, NewTrackPoint); 377 end; 378 Index := TrackPoints.IndexOf(TLineStation(LineStations.Last).TrackPoint); 379 if Index = TrackPoints.Count - 1 then begin 380 NewTrackPoint := TTrackPoint.Create; 381 NewTrackPoint.Line := Self; 382 TrackPoints.Insert(TrackPoints.Count, NewTrackPoint); 383 end; 384 385 Angle := arctan2((TTrackPoint(TrackPoints[2]).Point.Y - TTrackPoint(TrackPoints[1]).Point.Y), 386 (TTrackPoint(TrackPoints[2]).Point.X - TTrackPoint(TrackPoints[1]).Point.X)); 387 EndPoint := Point(Round(TTrackPoint(TrackPoints[1]).Point.X - EndStationLength * Cos(Angle)), 388 Round(TTrackPoint(TrackPoints[1]).Point.Y - EndStationLength * Sin(Angle))); 389 TTrackPoint(TrackPoints.First).Point := EndPoint; 390 391 Angle := arctan2((TTrackPoint(TrackPoints[TrackPoints.Count - 2]).Point.Y - TTrackPoint(TrackPoints[TrackPoints.Count - 3]).Point.Y), 392 (TTrackPoint(TrackPoints[TrackPoints.Count - 2]).Point.X - TTrackPoint(TrackPoints[TrackPoints.Count - 3]).Point.X)); 393 EndPoint := Point(Round(TTrackPoint(TrackPoints[TrackPoints.Count - 2]).Point.X + EndStationLength * Cos(Angle)), 394 Round(TTrackPoint(TrackPoints[TrackPoints.Count - 2]).Point.Y + EndStationLength * Sin(Angle))); 395 TTrackPoint(TrackPoints.Last).Point := EndPoint; 396 end; 397 end; 398 399 procedure TMetroLine.ConnectStation(Station: TMapStation; LineStationDown, LineStationUp: TLineStation); 335 400 var 336 401 Train: TMetroTrain; 337 402 NewTrackPoint: TTrackPoint; 338 403 NewLineStation: TLineStation; 339 begin 404 Index: Integer; 405 begin 406 if not Assigned(LineStationDown) and not Assigned(LineStationUp) and (LineStations.Count > 0) then 407 raise Exception.Create('No old line station to connect new station'); 340 408 NewLineStation := TLineStation.Create; 341 409 NewLineStation.Line := Self; 342 410 NewLineStation.MapStation := Station; 343 LineStations.Add(NewLineStation); 411 Index := 0; 412 if Assigned(LineStationDown) then Index := LineStations.IndexOf(LineStationDown) + 1 413 else if Assigned(LineStationDown) then Index := LineStations.IndexOf(LineStationUp); 414 LineStations.Insert(Index, NewLineStation); 344 415 Station.Lines.Add(Self); 345 416 … … 348 419 NewTrackPoint.Point := Station.Position; 349 420 NewTrackPoint.Line := TrackPoints.Line; 350 TrackPoints.Add(NewTrackPoint); 351 421 Index := 0; 422 if Assigned(LineStationDown) then Index := TrackPoints.IndexOf(LineStationDown.TrackPoint) + 1 423 else if Assigned(LineStationUp) then Index := TrackPoints.IndexOf(LineStationUp.TrackPoint); 424 TrackPoints.Insert(Index, NewTrackPoint); 352 425 NewLineStation.TrackPoint := NewTrackPoint; 353 426 354 if LineStations.Count >= 2 then 355 RouteTrack(TLineStation(LineStations[LineStations.Count - 2]).TrackPoint, NewLineStation.TrackPoint); 427 if Assigned(LineStationDown) then 428 RouteTrack(NewLineStation.TrackPoint.GetDown, NewLineStation.TrackPoint); 429 if Assigned(LineStationUp) then 430 RouteTrack(NewLineStation.TrackPoint, NewLineStation.TrackPoint.GetUp); 356 431 357 432 // Place one train if at least two stations present … … 364 439 end; 365 440 end; 441 UpdateEndingLines; 366 442 Engine.ComputeShapeDistance; 367 443 end; 368 444 369 procedure TMetroLine.DisconnectStation(Station: TMapStation); 370 var 371 I: Integer; 372 StationIndex: Integer; 373 begin 374 if (LineStations.Count > 0) and (TLineStation(LineStations.Last).MapStation = Station) then begin 375 StationIndex := LineStations.Count - 1; 376 LineStations.Delete(StationIndex); 377 Station.Lines.Remove(Self); 378 if LineStations.Count > 0 then begin 379 while (TrackPoints.Count > 0) and (not ComparePoint(TTrackPoint(TrackPoints.Last).Point, 380 TLineStation(LineStations.Last).MapStation.Position)) do 381 TrackPoints.Delete(TrackPoints.Count - 1); 382 end else TrackPoints.Clear; 383 384 // Remove trains if less then two stations 385 if LineStations.Count < 2 then 386 for I := Trains.Count - 1 downto 0 do begin 387 TMetroTrain(Trains[I]).Line := nil; 388 Trains.Delete(I); 389 end; 390 end; 445 procedure TMetroLine.DisconnectStation(LineStation: TLineStation); 446 var 447 I: Integer; 448 Index: Integer; 449 begin 450 // Delete old trackpoints 451 452 Index := TrackPoints.IndexOf(LineStation.TrackPoint) - 1; 453 while (Index >= 0) and (not Assigned(TTrackPoint(TrackPoints[Index]).LineStation)) do begin 454 TrackPoints.Delete(Index); 455 Dec(Index); 456 end; 457 Index := Index + 1; 458 TrackPoints.Delete(Index); 459 while (Index < TrackPoints.Count) and (not Assigned(TTrackPoint(TrackPoints[Index]).LineStation)) do 460 TrackPoints.Delete(Index); 461 462 LineStation.MapStation.Lines.Remove(Self); 463 Index := LineStations.IndexOf(LineStation); 464 LineStations.Delete(Index); 465 466 // Remove trains if less then two stations 467 if LineStations.Count < 2 then 468 for I := Trains.Count - 1 downto 0 do begin 469 TMetroTrain(Trains[I]).Line := nil; 470 Trains.Delete(I); 471 end; 472 UpdateEndingLines; 391 473 Engine.ComputeShapeDistance; 392 474 end; … … 399 481 Index1, Index2: Integer; 400 482 begin 483 RemoteTrackBetween(TP1, TP2); 401 484 Index1 := TrackPoints.IndexOf(TP1); 402 485 Index2 := TrackPoints.IndexOf(TP2); 403 if Index2 <> Index1 + 1 then404 raise Exception.Create('Supported only two neighbor track points for routing');405 486 P1 := TTrackPoint(TrackPoints[Index1]).Point; 406 487 P2 := TTrackPoint(TrackPoints[Index2]).Point; … … 414 495 end; 415 496 TrackPoints.Insert(Index1 + 1, NewTrackPoint); 497 end; 498 499 procedure TMetroLine.RemoteTrackBetween(TP1, TP2: TTrackPoint); 500 var 501 Index1, Index2: Integer; 502 Temp: Integer; 503 I: Integer; 504 begin 505 Index1 := TrackPoints.IndexOf(TP1); 506 Index2 := TrackPoints.IndexOf(TP2); 507 if (Index1 = -1) then 508 raise Exception.Create('TrackPoint1 not found'); 509 if (Index2 = -1) then 510 raise Exception.Create('TrackPoint2 not found'); 511 if Index1 > Index2 then begin 512 Temp := Index1; 513 Index1 := Index2; 514 Index2 := Temp; 515 end; 516 for I := 1 to Index2 - Index1 - 1 do 517 TrackPoints.Delete(Index1 + 1); 416 518 end; 417 519 … … 997 1099 procedure TEngine.Tick; 998 1100 const 999 NewStationPeriod = OneSecond * 20;1000 NewPassengerPeriod = OneSecond;1001 NewPassengerProbability = 0. 1;1101 NewStationPeriod = 20 * OneSecond; 1102 NewPassengerPeriod = 0.3 * OneSecond; 1103 NewPassengerProbability = 0.01; 1002 1104 var 1003 1105 Passenger: TMetroPassenger; … … 1058 1160 FocusedStation: TMapStation; 1059 1161 Line: TMetroLine; 1162 LineStationDown: TLineStation; 1163 LineStationUp: TLineStation; 1164 CurrentTrackPoint: TTrackPoint; 1060 1165 begin 1061 1166 LastMousePos := Position; 1062 1167 if MouseHold then begin 1063 if Assigned(TrackStationDown) then begin1064 1168 FocusedStation := GetStationOnPos(Position); 1169 if Assigned(TrackStationDown) then Line := TrackStationDown.Line; 1170 if Assigned(TrackStationUp) then Line := TrackStationUp.Line; 1065 1171 if not Assigned(LastFocusedStation) and Assigned(FocusedStation) then begin 1066 if (TrackStationDown.Line.LineStations.SearchMapStation(FocusedStation) = nil) then begin 1067 TrackStationDown.Line.ConnectStation(FocusedStation); 1068 TrackStationDown := TTrackPoint(TrackStationDown.Line.TrackPoints.Last); 1172 if Assigned(TrackStationDown) and (TrackStationDown.LineStation.MapStation = FocusedStation) then begin 1173 // Disconnect down 1174 CurrentTrackPoint := TrackStationDown; 1175 TrackStationDown := TrackStationDown.GetDown; 1176 Line.DisconnectStation(CurrentTrackPoint.LineStation); 1069 1177 end else 1070 if (SelectedLine.TrackPoints.Count > 0) and (TLineStation(TrackStationDown.Line.LineStations.Last).MapStation = FocusedStation) then begin 1071 Line := TrackStationDown.Line; 1072 TrackStationDown.Line.DisconnectStation(FocusedStation); 1073 TrackStationDown := TTrackPoint(Line.TrackPoints.Last); 1074 end else if (TrackStationDown.Line.LineStations.Count > 0) and (TLineStation(TrackStationDown.Line.LineStations.Last).MapStation = FocusedStation) then begin 1075 TrackStationDown.Line.ConnectStation(FocusedStation); 1178 if Assigned(TrackStationUp) and (TrackStationUp.LineStation.MapStation = FocusedStation) then begin 1179 // Disconnect up 1180 CurrentTrackPoint := TrackStationUp; 1181 if Assigned(TrackStationUp) then 1182 TrackStationUp := TrackStationUp.GetUp; 1183 Line.DisconnectStation(CurrentTrackPoint.LineStation); 1184 end else 1185 if Assigned(Line) and (Line.LineStations.SearchMapStation(FocusedStation) = nil) then begin 1186 if Assigned(TrackStationDown) then LineStationDown := TrackStationDown.LineStation 1187 else LineStationDown := nil; 1188 if Assigned(TrackStationUp) then LineStationUp := TrackStationUp.LineStation 1189 else LineStationUp := nil; 1190 Line.ConnectStation(FocusedStation, LineStationDown, LineStationUp); 1191 if Assigned(TrackStationDown) then TrackStationDown := TrackStationDown.GetUp 1192 else if Assigned(TrackStationUp) then TrackStationUp := TrackStationUp.GetDown; 1193 end; 1194 {else 1195 if (TrackStationDown.Line.LineStations.Count > 0) and (TLineStation(TrackStationDown.Line.LineStations.Last).MapStation = FocusedStation) then begin 1196 Line.ConnectStation(FocusedStation, TrackStationDown, TrackStationUp); 1076 1197 TrackStationDown := TTrackPoint(TrackStationDown.Line.TrackPoints.Last); 1077 1198 end; 1199 } 1078 1200 end; 1079 1201 LastFocusedStation := FocusedStation; 1080 end;1081 1202 end; 1082 1203 end; … … 1149 1270 NewLine := GetUnusedLine; 1150 1271 if Assigned(NewLine) then begin 1151 NewLine.ConnectStation(Station );1272 NewLine.ConnectStation(Station, nil, nil); 1152 1273 TrackStationDown := TTrackPoint(NewLine.TrackPoints.Last); 1153 1274 TrackStationUp := nil; … … 1173 1294 1174 1295 // Start with 3 stations with each different shape 1175 InitialStationCount := 3 0;1296 InitialStationCount := 3; 1176 1297 for I := 0 to InitialStationCount - 1 do begin 1177 1298 NewStation := Stations.AddNew; … … 1187 1308 end; 1188 1309 1189 SelectedLine := TMetroLine(Lines[0]);1310 SelectedLine := nil; 1190 1311 LastNewStationTime := Now; 1191 1312 LastNewPassengerTime := Now; … … 1243 1364 GameOverReason = 'Overcrowding at this station has forced you to resign as metro manager.'; 1244 1365 GameOverStatistic = '%d passengers travelled on your metro over %d days.'; 1245 EndStationLength = 50;1246 1366 begin 1247 1367 Canvas.Brush.Color := $eff0e0; … … 1258 1378 for S := 1 to TrackPoints.Count - 1 do begin 1259 1379 Canvas.LineTo(TTrackPoint(TrackPoints[S]).Point); 1260 if (S = TrackPoints.Count - 1) then begin1380 { if (S = TrackPoints.Count - 1) then begin 1261 1381 Canvas.Pen.EndCap := pecSquare; 1262 1382 Angle := arctan2((TTrackPoint(TrackPoints[S]).Point.Y - TTrackPoint(TrackPoints[S - 1]).Point.Y), … … 1270 1390 Round(EndPoint.Y + Sin(Angle - Pi / 2) * EndStationLength / 3))); 1271 1391 Canvas.Pen.EndCap := pecRound; 1272 end; 1273 end; 1392 end;} 1393 end; 1394 { 1274 1395 if (TrackPoints.Count > 1) then begin 1275 1396 Canvas.Pen.EndCap := pecSquare; … … 1285 1406 Round(EndPoint.Y - Sin(Angle - Pi / 2) * EndStationLength / 3))); 1286 1407 Canvas.Pen.EndCap := pecRound; 1287 end; 1408 end; } 1288 1409 end; 1289 1410
Note:
See TracChangeset
for help on using the changeset viewer.