- Timestamp:
- Mar 26, 2015, 9:06:17 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UEngine.pas
r8 r9 40 40 end; 41 41 42 TTrackPoint = record 43 StationIndex: Integer; 44 Point: TPoint; 45 end; 46 42 47 { TMetroLine } 43 48 … … 47 52 Stations: TMetroStations; 48 53 Trains: TMetroTrains; 49 TrackPoints: array of T Point;54 TrackPoints: array of TTrackPoint; 50 55 procedure ConnectStation(Station: TMetroStation); 51 56 procedure DisconnectStation(Station: TMetroStation); 52 procedure AddTrack(P1, P2: TPoint );57 procedure AddTrack(P1, P2: TPoint; StationIndex: Integer); 53 58 function GetTrackLength: Integer; 54 function GetStationTrackPos(Station : TMetroStation): Integer;59 function GetStationTrackPos(StationIndex: Integer): Integer; 55 60 constructor Create; 56 61 destructor Destroy; override; … … 70 75 private 71 76 LastPosDelta: Integer; 77 function GetTargetStation: TMetroStation; 72 78 public 73 79 Passengers: TMetroPassengers; … … 77 83 InStation: Boolean; 78 84 StationStopTime: TDateTime; 79 TargetStation : TMetroStation;80 function GetPos : TPoint;85 TargetStationIndex: Integer; 86 function GetPosition: TPoint; 81 87 constructor Create; 82 88 destructor Destroy; override; 89 property TargetStation: TMetroStation read GetTargetStation; 83 90 end; 84 91 … … 88 95 function GetUnusedTrain: TMetroTrain; 89 96 function GetUnusedCount: Integer; 97 function AddNew: TMetroTrain; 90 98 end; 91 99 … … 123 131 LastNewStationTime: TDateTime; 124 132 LastNewPassengerTime: TDateTime; 133 LastNewWeekTime: TDateTime; 125 134 ImagePassenger: TImage; 126 135 ImageLocomotive: TImage; … … 211 220 end; 212 221 222 function TMetroTrains.AddNew: TMetroTrain; 223 begin 224 Result := TMetroTrain.Create; 225 Add(Result); 226 end; 227 213 228 { TMetroStations } 214 229 … … 264 279 var 265 280 Train: TMetroTrain; 281 StationIndex: Integer; 266 282 begin 267 283 Stations.Add(Station); 268 284 Station.Lines.Add(Self); 285 StationIndex := Stations.Count - 1; 269 286 if Stations.Count = 1 then begin 270 287 SetLength(TrackPoints, Length(TrackPoints) + 1); 271 TrackPoints[High(TrackPoints)] := Station.Position; 288 TrackPoints[High(TrackPoints)].StationIndex := StationIndex; 289 TrackPoints[High(TrackPoints)].Point := Station.Position; 272 290 end else begin 273 291 if Stations.Count > 1 then 274 AddTrack(TMetroStation(Stations[Stations.Count - 2]).Position, Station.Position );292 AddTrack(TMetroStation(Stations[Stations.Count - 2]).Position, Station.Position, StationIndex); 275 293 // Place one train if at least two stations present 276 294 if (Stations.Count = 2) then begin … … 278 296 if Assigned(Train) then begin 279 297 Train.Line := Self; 280 Train.TargetStation := TMetroStation(Stations.First);298 Train.TargetStationIndex := 0; 281 299 Trains.Add(Train); 282 300 end; … … 289 307 var 290 308 I: Integer; 309 StationIndex: Integer; 291 310 begin 292 311 if (Stations.Count > 0) and (Stations.Last = Station) then begin 293 Stations.Delete(Stations.Count - 1); 312 StationIndex := Stations.Count - 1; 313 Stations.Delete(StationIndex); 294 314 Station.Lines.Remove(Self); 295 315 if Stations.Count > 0 then begin 296 while (Length(TrackPoints) > 0) and (not ComparePoint(TrackPoints[High(TrackPoints)], TMetroStation(Stations.Last).Position)) do 316 while (Length(TrackPoints) > 0) and (not ComparePoint(TrackPoints[High(TrackPoints)].Point, 317 TMetroStation(Stations.Last).Position)) do 297 318 SetLength(TrackPoints, Length(TrackPoints) - 1); 298 319 end else SetLength(TrackPoints, 0); … … 307 328 end; 308 329 309 procedure TMetroLine.AddTrack(P1, P2: TPoint );330 procedure TMetroLine.AddTrack(P1, P2: TPoint; StationIndex: Integer); 310 331 var 311 332 Delta: TPoint; … … 314 335 if Abs(Delta.X) > Abs(Delta.Y) then begin 315 336 SetLength(TrackPoints, Length(TrackPoints) + 1); 316 TrackPoints[High(TrackPoints)] := Point(P2.X - Sign(Delta.X) * Abs(Delta.Y), P1.Y); 337 TrackPoints[High(TrackPoints)].Point := Point(P2.X - Sign(Delta.X) * Abs(Delta.Y), P1.Y); 338 TrackPoints[High(TrackPoints)].StationIndex := StationIndex - 1; 317 339 end else begin 318 340 SetLength(TrackPoints, Length(TrackPoints) + 1); 319 TrackPoints[High(TrackPoints)] := Point(P1.X, P2.Y - Sign(Delta.Y) * Abs(Delta.X)); 341 TrackPoints[High(TrackPoints)].Point := Point(P1.X, P2.Y - Sign(Delta.Y) * Abs(Delta.X)); 342 TrackPoints[High(TrackPoints)].StationIndex := StationIndex - 1; 320 343 end; 321 344 SetLength(TrackPoints, Length(TrackPoints) + 1); 322 TrackPoints[High(TrackPoints)] := P2; 345 TrackPoints[High(TrackPoints)].Point := P2; 346 TrackPoints[High(TrackPoints)].StationIndex := StationIndex; 323 347 end; 324 348 … … 330 354 for I := 0 to High(TrackPoints) do 331 355 if I > 0 then 332 Result := Result + Distance(TrackPoints[I] , TrackPoints[I - 1]);333 end; 334 335 function TMetroLine.GetStationTrackPos(Station : TMetroStation): Integer;356 Result := Result + Distance(TrackPoints[I].Point, TrackPoints[I - 1].Point); 357 end; 358 359 function TMetroLine.GetStationTrackPos(StationIndex: Integer): Integer; 336 360 var 337 361 I: Integer; … … 340 364 for I := 0 to High(TrackPoints) do begin 341 365 if I > 0 then 342 Result := Result + Distance(TrackPoints[I] , TrackPoints[I - 1]);343 if (TrackPoints[I].X = Station.Position.X) and (TrackPoints[I].Y = Station.Position.Y)then Break;366 Result := Result + Distance(TrackPoints[I].Point, TrackPoints[I - 1].Point); 367 if TrackPoints[I].StationIndex = StationIndex then Break; 344 368 end; 345 369 end; … … 362 386 { TMetroTrain } 363 387 364 function TMetroTrain.GetPos: TPoint; 388 function TMetroTrain.GetTargetStation: TMetroStation; 389 begin 390 Result := nil; 391 if Assigned(Line) then 392 if (TargetStationIndex >= 0) and (TargetStationIndex < Line.Stations.Count) then 393 Result := TMetroStation(Line.Stations[TargetStationIndex]); 394 end; 395 396 function TMetroTrain.GetPosition: TPoint; 365 397 var 366 398 I: Integer; … … 374 406 if Length(TrackPoints) > 1 then 375 407 for I := 1 to High(TrackPoints) do begin 376 D := Distance(TrackPoints[I] , TrackPoints[I - 1]);408 D := Distance(TrackPoints[I].Point, TrackPoints[I - 1].Point); 377 409 if (Sum + D) > Self.TrackPos then begin 378 R := Point(TrackPoints[I].X - TrackPoints[I - 1].X, TrackPoints[I].Y - TrackPoints[I - 1].Y); 379 Result := Point(Trunc(TrackPoints[I - 1].X + R.X * (TrackPos - Sum) / D), 380 Trunc(TrackPoints[I - 1].Y + R.Y * (TrackPos - Sum) / D)); 410 R := Point(TrackPoints[I].Point.X - TrackPoints[I - 1].Point.X, 411 TrackPoints[I].Point.Y - TrackPoints[I - 1].Point.Y); 412 Result := Point(Trunc(TrackPoints[I - 1].Point.X + R.X * (TrackPos - Sum) / D), 413 Trunc(TrackPoints[I - 1].Point.Y + R.Y * (TrackPos - Sum) / D)); 381 414 Exit; 382 415 end else Sum := Sum + D; 383 416 end; 384 Result := TrackPoints[High(TrackPoints)] ;417 Result := TrackPoints[High(TrackPoints)].Point; 385 418 end else Result := Point(0, 0); 386 419 end; … … 482 515 with TMetroLine(Lines[I]) do begin 483 516 for T := 1 to High(TrackPoints) do begin 484 D := PointToLineDistance(Pos, TrackPoints[T - 1] , TrackPoints[T]);517 D := PointToLineDistance(Pos, TrackPoints[T - 1].Point, TrackPoints[T].Point); 485 518 if D < Distance then begin 486 519 Result := TMetroLine(Lines[I]); … … 616 649 P: Integer; 617 650 PosDelta: Integer; 618 TargetStationIndex: Integer;619 651 CurrentStation: TMetroStation; 620 BestStation: TMetroStation;621 652 begin 622 653 if State = gsRunning then begin 654 655 // Add new stations 656 if (Now - LastNewWeekTime) > 7 then begin 657 LastNewWeekTime := Now; 658 Trains.AddNew; 659 // TODO: Show notification screen with confirmation 660 end; 623 661 624 662 // Add new stations … … 653 691 654 692 // Choose next target station 655 TargetStationIndex := Line.Stations.IndexOf(TargetStation)+ Direction;693 TargetStationIndex := TargetStationIndex + Direction; 656 694 if TargetStationIndex < 0 then begin 657 TargetStationIndex := 1; 658 Direction := -Direction; 695 if Line.Stations.Last = Line.Stations.First then begin 696 TargetStationIndex := Line.Stations.Count - 2; 697 TrackPos := Line.GetStationTrackPos(Line.Stations.Count - 1); 698 end else begin 699 TargetStationIndex := 1; 700 Direction := -Direction; 701 end; 659 702 end else if TargetStationIndex >= Line.Stations.Count then begin 660 TargetStationIndex := Line.Stations.Count - 2; 661 Direction := -Direction; 703 if Line.Stations.Last = Line.Stations.First then begin 704 TargetStationIndex := 1; 705 TrackPos := 0; 706 end else begin 707 TargetStationIndex := Line.Stations.Count - 2; 708 Direction := -Direction; 709 end; 662 710 end; 663 TargetStation := TMetroStation(Line.Stations[TargetStationIndex]);664 711 665 712 // Unload passengers in target station … … 695 742 end; 696 743 697 LastPosDelta := Abs(TrackPos - Line.GetStationTrackPos(TargetStation ));744 LastPosDelta := Abs(TrackPos - Line.GetStationTrackPos(TargetStationIndex)); 698 745 InStation := False; 699 746 end; … … 701 748 TrackPos := TrackPos + Direction * TrainSpeed; 702 749 if TrackPos < 0 then begin 703 TrackPos := 0; 750 if Line.Stations.First = Line.Stations.Last then TrackPos := Line.GetTrackLength 751 else TrackPos := 0; 704 752 end else 705 753 if TrackPos > Line.GetTrackLength then begin 706 TrackPos := Line.GetTrackLength; 707 end; 708 PosDelta := Abs(TrackPos - Line.GetStationTrackPos(TargetStation)); 754 if Line.Stations.First = Line.Stations.Last then TrackPos := 0 755 else TrackPos := Line.GetTrackLength; 756 end; 757 PosDelta := Abs(TrackPos - Line.GetStationTrackPos(TargetStationIndex)); 709 758 if PosDelta >= LastPosDelta then begin 710 759 // We are getting far from station, stop at station 711 TrackPos := Line.GetStationTrackPos(TargetStation );760 TrackPos := Line.GetStationTrackPos(TargetStationIndex); 712 761 InStation := True; 713 762 StationStopTime := Now; … … 721 770 for I := 0 to Stations.Count - 1 do 722 771 with TMetroStation(Stations[I]) do begin 723 //if Passengers.Count > MaxWaitingPassengers then State := gsGameOver;772 if Passengers.Count > MaxWaitingPassengers then State := gsGameOver; 724 773 end; 725 774 … … 837 886 LastNewStationTime := Now; 838 887 LastNewPassengerTime := Now; 888 LastNewWeekTime := Now; 839 889 State := gsRunning; 840 890 StartTime := Now; … … 899 949 Canvas.Pen.Style := psSolid; 900 950 Canvas.Pen.Width := 15; 901 if Length(TrackPoints) > 0 then Canvas.MoveTo(TrackPoints[0] );951 if Length(TrackPoints) > 0 then Canvas.MoveTo(TrackPoints[0].Point); 902 952 for S := 1 to High(TrackPoints) do begin 903 Canvas.LineTo(TrackPoints[S] );953 Canvas.LineTo(TrackPoints[S].Point); 904 954 if (S = High(TrackPoints)) then begin 905 Angle := arctan2((TrackPoints[S]. Y - TrackPoints[S - 1].Y), (TrackPoints[S].X - TrackPoints[S - 1].X));906 EndPoint := Point(Round(TrackPoints[S]. X + EndStationLength * Cos(Angle)),907 Round(TrackPoints[S]. Y + EndStationLength * Sin(Angle)));955 Angle := arctan2((TrackPoints[S].Point.Y - TrackPoints[S - 1].Point.Y), (TrackPoints[S].Point.X - TrackPoints[S - 1].Point.X)); 956 EndPoint := Point(Round(TrackPoints[S].Point.X + EndStationLength * Cos(Angle)), 957 Round(TrackPoints[S].Point.Y + EndStationLength * Sin(Angle))); 908 958 Canvas.LineTo(EndPoint); 909 959 Canvas.MoveTo(Point(Round(EndPoint.X + Cos(Angle + Pi / 2) * EndStationLength / 3), … … 914 964 end; 915 965 if (Length(TrackPoints) > 1) then begin 916 Angle := arctan2((TrackPoints[1]. Y - TrackPoints[0].Y), (TrackPoints[1].X - TrackPoints[0].X));917 Canvas.MoveTo(TrackPoints[0] );918 EndPoint := Point(Round(TrackPoints[0]. X - EndStationLength * Cos(Angle)),919 Round(TrackPoints[0]. Y - EndStationLength * Sin(Angle)));966 Angle := arctan2((TrackPoints[1].Point.Y - TrackPoints[0].Point.Y), (TrackPoints[1].Point.X - TrackPoints[0].Point.X)); 967 Canvas.MoveTo(TrackPoints[0].Point); 968 EndPoint := Point(Round(TrackPoints[0].Point.X - EndStationLength * Cos(Angle)), 969 Round(TrackPoints[0].Point.Y - EndStationLength * Sin(Angle))); 920 970 Canvas.LineTo(EndPoint); 921 971 Canvas.MoveTo(Point(Round(EndPoint.X - Cos(Angle + Pi / 2) * EndStationLength / 3), … … 939 989 Canvas.Brush.Style := bsSolid; 940 990 Canvas.Pen.Style := psClear; 941 Pos := GetPos ;991 Pos := GetPosition; 942 992 Canvas.Rectangle(Pos.X - TrainSize div 2, Pos.Y - TrainSize div 2, 943 993 Pos.X + TrainSize div 2, Pos.Y + TrainSize div 2);
Note:
See TracChangeset
for help on using the changeset viewer.