Changeset 91
- Timestamp:
- Sep 22, 2022, 10:57:26 PM (2 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/BigMetro.lpi
r90 r91 89 89 </Item2> 90 90 </RequiredPackages> 91 <Units Count=" 9">91 <Units Count="11"> 92 92 <Unit0> 93 93 <Filename Value="BigMetro.lpr"/> … … 132 132 <IsPartOfProject Value="True"/> 133 133 </Unit8> 134 <Unit9> 135 <Filename Value="UView.pas"/> 136 <IsPartOfProject Value="True"/> 137 </Unit9> 138 <Unit10> 139 <Filename Value="URiver.pas"/> 140 <IsPartOfProject Value="True"/> 141 </Unit10> 134 142 </Units> 135 143 </ProjectOptions> -
trunk/BigMetro.lpr
r90 r91 9 9 Interfaces, // this includes the LCL widgetset 10 10 Forms, SysUtils, UFormMain, UFormImages, Common, UMenu, UControls, 11 UMetroPassenger, UColors ;11 UMetroPassenger, UColors, UView, URiver; 12 12 13 13 {$R *.res} -
trunk/Languages/BigMetro.cs.po
r86 r91 24 24 msgid "Big Metro" 25 25 msgstr "Big Metro" 26 27 #: uengine.salreadyconnectedtrackpoint28 msgid "Trying to connect already connected track point"29 msgstr "Pokus o připojení již připojeného bodu trasy"30 31 #: uengine.salreadydisconnectedtrackpoint32 msgid "Trying to disconnect not connected track point"33 msgstr "Pokus o rozpojení již připojeného bodu trasy"34 26 35 27 #: uengine.sday … … 70 62 msgid "Station have to have MapStation" 71 63 msgstr "" 72 73 #: uengine.strackpointnotfound74 #, object-pascal-format75 msgid "Track point %d not found"76 msgstr ""77 78 #: uengine.szerozoomnotalowed79 msgid "Zero zoom not allowed"80 msgstr "Nulové přiblížení není povoleno"81 64 82 65 #: umenu.sautomatic … … 136 119 msgstr "Zkusit znovu" 137 120 121 #: utrack.salreadyconnectedtrackpoint 122 #, fuzzy 123 msgctxt "utrack.salreadyconnectedtrackpoint" 124 msgid "Trying to connect already connected track point" 125 msgstr "Pokus o připojení již připojeného bodu trasy" 126 127 #: utrack.salreadydisconnectedtrackpoint 128 #, fuzzy 129 msgctxt "utrack.salreadydisconnectedtrackpoint" 130 msgid "Trying to disconnect not connected track point" 131 msgstr "Pokus o rozpojení již připojeného bodu trasy" 132 133 #: utrack.strackpointnotfound 134 #, object-pascal-format 135 msgctxt "utrack.strackpointnotfound" 136 msgid "Track point %d not found" 137 msgstr "" 138 139 #: uview.szerozoomnotalowed 140 #, fuzzy 141 msgctxt "uview.szerozoomnotalowed" 142 msgid "Zero zoom not allowed" 143 msgstr "Nulové přiblížení není povoleno" 144 -
trunk/Languages/BigMetro.de.po
r88 r91 16 16 msgstr "" 17 17 18 #: tformmain.applicationinfo1.description 19 msgid "Enjoyable real-time metro building game." 20 msgstr "" 21 18 22 #: tformmain.caption 19 23 msgctxt "tformmain.caption" 20 24 msgid "Big Metro" 21 25 msgstr "Big Metro" 22 23 #: uengine.salreadyconnectedtrackpoint24 msgid "Trying to connect already connected track point"25 msgstr "Versuch ein bereits verbundene Line zu verbinden"26 27 #: uengine.salreadydisconnectedtrackpoint28 msgid "Trying to disconnect not connected track point"29 msgstr "Versuch einen nicht verbundene Line zu unterbrechen"30 26 31 27 #: uengine.sday … … 42 38 43 39 #: uengine.sgameoverstatistic 40 #, object-pascal-format 44 41 msgid "%d passengers travelled on your metro over %d days." 45 42 msgstr "%d Passagiere fuhren mit deiner Metro über %d Tage." … … 49 46 msgstr "Neuer Highscore!" 50 47 48 #: uengine.snooldstationtoconnectnew 49 msgid "No old line station to connect new station" 50 msgstr "" 51 51 52 #: uengine.soldhighscore 53 #, object-pascal-format 52 54 msgid "Old high score was %d passengers in %d days." 53 55 msgstr "Der alte Highscore war %d passager in %d Tagen." 54 56 55 #: uengine.szerozoomnotalowed 56 msgid "Zero zoom not allowed" 57 msgstr "Diese Zoomstufe ist nicht erlaubt" 57 #: uengine.sstationnotdefined 58 msgid "Station have to be defined" 59 msgstr "" 60 61 #: uengine.sstationwithoutmapstation 62 msgid "Station have to have MapStation" 63 msgstr "" 58 64 59 65 #: umenu.sautomatic … … 113 119 msgstr "Neustart" 114 120 121 #: utrack.salreadyconnectedtrackpoint 122 #, fuzzy 123 msgctxt "utrack.salreadyconnectedtrackpoint" 124 msgid "Trying to connect already connected track point" 125 msgstr "Versuch ein bereits verbundene Line zu verbinden" 126 127 #: utrack.salreadydisconnectedtrackpoint 128 #, fuzzy 129 msgctxt "utrack.salreadydisconnectedtrackpoint" 130 msgid "Trying to disconnect not connected track point" 131 msgstr "Versuch einen nicht verbundene Line zu unterbrechen" 132 133 #: utrack.strackpointnotfound 134 #, object-pascal-format 135 msgctxt "utrack.strackpointnotfound" 136 msgid "Track point %d not found" 137 msgstr "" 138 139 #: uview.szerozoomnotalowed 140 #, fuzzy 141 msgctxt "uview.szerozoomnotalowed" 142 msgid "Zero zoom not allowed" 143 msgstr "Diese Zoomstufe ist nicht erlaubt" 144 -
trunk/Languages/BigMetro.pot
r86 r91 13 13 msgctxt "tformmain.caption" 14 14 msgid "Big Metro" 15 msgstr ""16 17 #: uengine.salreadyconnectedtrackpoint18 msgid "Trying to connect already connected track point"19 msgstr ""20 21 #: uengine.salreadydisconnectedtrackpoint22 msgid "Trying to disconnect not connected track point"23 15 msgstr "" 24 16 … … 59 51 #: uengine.sstationwithoutmapstation 60 52 msgid "Station have to have MapStation" 61 msgstr ""62 63 #: uengine.strackpointnotfound64 #, object-pascal-format65 msgid "Track point %d not found"66 msgstr ""67 68 #: uengine.szerozoomnotalowed69 msgid "Zero zoom not allowed"70 53 msgstr "" 71 54 … … 123 106 msgstr "" 124 107 108 #: utrack.salreadyconnectedtrackpoint 109 msgctxt "utrack.salreadyconnectedtrackpoint" 110 msgid "Trying to connect already connected track point" 111 msgstr "" 112 113 #: utrack.salreadydisconnectedtrackpoint 114 msgctxt "utrack.salreadydisconnectedtrackpoint" 115 msgid "Trying to disconnect not connected track point" 116 msgstr "" 117 118 #: utrack.strackpointnotfound 119 #, object-pascal-format 120 msgctxt "utrack.strackpointnotfound" 121 msgid "Track point %d not found" 122 msgstr "" 123 124 #: uview.szerozoomnotalowed 125 msgctxt "uview.szerozoomnotalowed" 126 msgid "Zero zoom not allowed" 127 msgstr "" 128 -
trunk/UEngine.pas
r90 r91 9 9 Classes, SysUtils, Graphics, Controls, ExtCtrls, Math, DateUtils, 10 10 UMetaCanvas, Generics.Collections, Generics.Defaults, UMenu, UControls, 11 UMetroPassenger, UColors ;11 UMetroPassenger, UColors, UView, URiver, UTrack; 12 12 13 13 type … … 17 17 TMetroLine = class; 18 18 TMetroTrains = class; 19 TTrackPoint = class;20 19 TLineStation = class; 21 TTrackPoints = class;22 TTrack = class;23 TTrackLink = class;24 TTrackLinks = class;25 20 26 21 { TMapStation } … … 51 46 end; 52 47 48 { TLineStation } 49 53 50 TLineStation = class 54 51 Line: TMetroLine; … … 62 59 Line: TMetroLine; 63 60 function SearchMapStation(Station: TMapStation): TLineStation; 64 end;65 66 { TTrackPoint }67 68 TTrackPoint = class69 LineStation: TLineStation;70 Position: TPoint;71 //PositionShift: TPoint;72 PositionDesigned: TPoint;73 Pending: Boolean;74 Track: TTrack;75 NeighPoints: TTrackPoints;76 NeighLinks: TTrackLinks;77 LinkUp: TTrackLink;78 LinkDown: TTrackLink;79 procedure Connect(TrackPoint: TTrackPoint);80 procedure Disconnect(TrackPoint: TTrackPoint);81 function GetDown: TTrackPoint;82 function GetUp: TTrackPoint;83 function GetNeighDown: TTrackPoint;84 function GetNeighUp: TTrackPoint;85 function GetLinkDown: TTrackLink;86 function GetLinkUp: TTrackLink;87 // Move to TTrackLink later88 function GetDistance: Integer;89 constructor Create;90 destructor Destroy; override;91 end;92 93 { TTrackPoints }94 95 TTrackPoints = class(TObjectList<TTrackPoint>)96 Track: TTrack;97 function AddNew: TTrackPoint;98 end;99 100 { TTrackLink }101 102 TTrackLink = class103 Points: TTrackPoints;104 Shift: TPoint;105 Track: TTrack;106 constructor Create;107 destructor Destroy; override;108 end;109 110 { TTrackLinks }111 112 TTrackLinks = class(TObjectList<TTrackLink>)113 Track: TTrack;114 function SearchPoints(Point1, Point2: TTrackPoint): TTrackLink;115 function AddNew: TTrackLink;116 end;117 118 TTrack = class119 Points: TTrackPoints;120 Links: TTrackLinks;121 Line: TMetroLine;122 procedure RouteTrack(TP1, TP2: TTrackPoint);123 procedure RemoveTrackBetween(TP1, TP2: TTrackPoint);124 constructor Create;125 destructor Destroy; override;126 end;127 128 { TTracks }129 130 TTracks = class(TObjectList<TTrackLink>)131 function SearchPointUp(TrackPoint: TTrackPoint; Skip: TTrackLink): TTrackLink;132 function SearchPointDown(TrackPoint: TTrackPoint; Skip: TTrackLink): TTrackLink;133 end;134 135 { TTrackPointsAngle }136 137 TTrackPointsAngle = class138 Angle: Double;139 TrackLinks: TTrackLinks;140 constructor Create;141 destructor Destroy; override;142 end;143 144 { TTrackPointsAngleGroup }145 146 TTrackPointsAngleGroup = class(TObjectList<TTrackPointsAngle>)147 function SearchAngle(Angle: Double): TTrackPointsAngle;148 61 end; 149 62 … … 163 76 procedure ConnectStation(Station: TMapStation; LineStationDown, LineStationUp: TLineStation); 164 77 procedure DisconnectStation(ALineStation: TLineStation); 165 function GetTrackLength: Integer;166 78 constructor Create; 167 79 destructor Destroy; override; … … 179 91 TMetroTrain = class; 180 92 93 { TMetroCarriage } 94 181 95 TMetroCarriage = class 182 96 Train: TMetroTrain; 183 97 end; 98 99 { TMetroCarriages } 184 100 185 101 TMetroCarriages = class(TObjectList<TMetroCarriage>) … … 219 135 end; 220 136 221 { TRiver }222 223 TRiver = class224 Points: array of TPoint;225 procedure Paint(Canvas: TCanvas);226 end;227 228 TRivers = class(TObjectList<TRiver>)229 end;230 231 137 TMap = class 232 138 Size: TPoint; … … 234 140 constructor Create; 235 141 destructor Destroy; override; 236 end;237 238 { TView }239 240 TView = class241 private242 FDestRect: TRect;243 FSourceRect: TRect;244 FZoom: Double;245 procedure SetDestRect(AValue: TRect);246 procedure SetSourceRect(AValue: TRect);247 procedure SetZoom(AValue: Double);248 public249 function PointDestToSrc(Pos: TPoint): TPoint;250 function PointSrcToDest(Pos: TPoint): TPoint;251 constructor Create;252 property SourceRect: TRect read FSourceRect write SetSourceRect;253 property DestRect: TRect read FDestRect write SetDestRect;254 property Zoom: Double read FZoom write SetZoom;255 142 end; 256 143 … … 408 295 409 296 resourcestring 410 SZeroZoomNotAlowed = 'Zero zoom not allowed';411 SAlreadyConnectedTrackPoint = 'Trying to connect already connected track point';412 SAlreadyDisconnectedTrackPoint = 'Trying to disconnect not connected track point';413 297 SGameOver = 'Game Over'; 414 298 SGameOverReason = 'Overcrowding at this station has forced you to resign as metro manager.'; … … 417 301 SNewHighScore = 'New high score!'; 418 302 SOldHighScore = 'Old high score was %d passengers in %d days.'; 419 STrackPointNotFound = 'Track point %d not found';420 303 SStationNotDefined = 'Station have to be defined'; 421 304 SNoOldStationToConnectNew = 'No old line station to connect new station'; 422 305 SStationWithoutMapStation = 'Station have to have MapStation'; 423 306 424 { TTrackLinks }425 426 function TTrackLinks.SearchPoints(Point1, Point2: TTrackPoint): TTrackLink;427 var428 I: Integer;429 begin430 I := 0;431 while (I < 0) and432 ((Items[I].Points.First <> Point1) or (Items[I].Points.Last <> Point2)) and433 ((Items[I].Points.First <> Point2) or (Items[I].Points.Last <> Point1)) do434 Inc(I);435 if I < 0 then Result := Items[I]436 else Result := nil;437 end;438 439 function TTrackLinks.AddNew: TTrackLink;440 begin441 Result := TTrackLink.Create;442 Result.Track := Track;443 end;444 445 { TTrackPoints }446 447 function TTrackPoints.AddNew: TTrackPoint;448 begin449 Result := TTrackPoint.Create;450 Result.Track := Track;451 end;452 453 { TTrack }454 455 constructor TTrack.Create;456 begin457 Points := TTrackPoints.Create;458 Points.Track := Self;459 Links := TTrackLinks.Create;460 Links.Track := Self;461 end;462 463 destructor TTrack.Destroy;464 begin465 FreeAndNil(Points);466 FreeAndNil(Links);467 inherited;468 end;469 470 { TTrackLink }471 472 constructor TTrackLink.Create;473 begin474 Points := TTrackPoints.Create;475 Points.OwnsObjects := False;476 end;477 478 destructor TTrackLink.Destroy;479 begin480 FreeAndNil(Points);481 inherited;482 end;483 484 { TRiver }485 486 procedure TRiver.Paint(Canvas: TCanvas);487 begin488 Canvas.Brush.Color := $ffffe0;489 Canvas.Brush.Style := bsSolid;490 Canvas.Polygon(Points);491 end;492 493 307 { TMap } 494 308 … … 501 315 begin 502 316 FreeAndNil(Rivers); 503 inherited;504 end;505 506 { TView }507 508 procedure TView.SetDestRect(AValue: TRect);509 var510 Diff: TPoint;511 begin512 if RectEquals(FDestRect, AValue) then Exit;513 Diff := Point(Trunc((DestRect.Right - DestRect.Left) / Zoom - (AValue.Right - AValue.Left) / Zoom) div 2,514 Trunc((DestRect.Bottom - DestRect.Top) / Zoom - (AValue.Bottom - AValue.Top) / Zoom) div 2);515 FDestRect := AValue;516 FSourceRect := Bounds(FSourceRect.Left + Diff.X, FSourceRect.Top + Diff.Y,517 Trunc((DestRect.Right - DestRect.Left) / Zoom),518 Trunc((DestRect.Bottom - DestRect.Top) / Zoom));519 end;520 521 procedure TView.SetSourceRect(AValue: TRect);522 var523 ZX: Double;524 ZY: Double;525 begin526 if RectEquals(FSourceRect, AValue) then Exit;527 FSourceRect := AValue;528 ZX := (FDestRect.Right - FDestRect.Left) / (FSourceRect.Right - FSourceRect.Left);529 ZY := (FDestRect.Bottom - FDestRect.Top) / (FSourceRect.Bottom - FSourceRect.Top);530 if ZX > ZY then531 Zoom := ZY532 else Zoom := ZX;533 end;534 535 procedure TView.SetZoom(AValue: Double);536 begin537 if FZoom = AValue then Exit;538 if AValue = 0 then539 raise Exception.Create(SZeroZoomNotAlowed);540 FZoom := AValue;541 FSourceRect := Bounds(Trunc(FSourceRect.Left + (FSourceRect.Right - FSourceRect.Left) div 2 - (DestRect.Right - DestRect.Left) / Zoom / 2),542 Trunc(FSourceRect.Top + (FSourceRect.Bottom - FSourceRect.Top) div 2 - (FDestRect.Bottom - DestRect.Top) / Zoom / 2),543 Trunc((DestRect.Right - DestRect.Left) / Zoom),544 Trunc((DestRect.Bottom - DestRect.Top) / Zoom));545 end;546 547 function TView.PointDestToSrc(Pos: TPoint): TPoint;548 begin549 Result := Point(Trunc(Pos.X / FZoom + FSourceRect.Left),550 Trunc(Pos.Y / FZoom + FSourceRect.Top));551 end;552 553 function TView.PointSrcToDest(Pos: TPoint): TPoint;554 begin555 Result := Point(Trunc((Pos.X - FSourceRect.Left) * FZoom),556 Trunc((Pos.Y - FSourceRect.Top) * FZoom));557 end;558 559 constructor TView.Create;560 begin561 Zoom := 1;562 end;563 564 { TTracks }565 566 function TTracks.SearchPointUp(TrackPoint: TTrackPoint; Skip: TTrackLink): TTrackLink;567 var568 I: Integer;569 begin570 I := 0;571 while (I < Count) and (Items[I].Points[1] <> TrackPoint) and (Items[I] <> Skip) do Inc(I);572 if I < Count then Result := Items[I]573 else Result := nil;574 end;575 576 function TTracks.SearchPointDown(TrackPoint: TTrackPoint; Skip: TTrackLink): TTrackLink;577 var578 I: Integer;579 begin580 I := 0;581 while (I < Count) and (Items[I].Points[0] <> TrackPoint) and (Items[I] <> Skip) do Inc(I);582 if I < Count then Result := Items[I]583 else Result := nil;584 end;585 586 { TTrackPointsAngleGroup }587 588 function TTrackPointsAngleGroup.SearchAngle(Angle: Double): TTrackPointsAngle;589 var590 I: Integer;591 begin592 I := 0;593 while (I < Count) and (Items[I].Angle <> Angle) do Inc(I);594 if I < Count then Result := Items[I]595 else Result := nil;596 end;597 598 { TTrackPointsAngle }599 600 constructor TTrackPointsAngle.Create;601 begin602 TrackLinks := TTrackLinks.Create;603 TrackLinks.OwnsObjects := False;604 end;605 606 destructor TTrackPointsAngle.Destroy;607 begin608 FreeAndNil(TrackLinks);609 inherited;610 end;611 612 { TTrackPoint }613 614 procedure TTrackPoint.Connect(TrackPoint: TTrackPoint);615 var616 NewLink: TTrackLink;617 begin618 if NeighPoints.IndexOf(TrackPoint) = -1 then begin619 NeighPoints.Add(TrackPoint);620 TrackPoint.NeighPoints.Add(Self);621 622 // Add new link to both self and connected track point623 NewLink := Track.Links.AddNew;624 NewLink.Points.Add(TrackPoint);625 NewLink.Points.Add(Self);626 NeighLinks.Add(NewLink);627 TrackPoint.NeighLinks.Add(NewLink);628 Track.Links.Add(NewLink);629 end else raise Exception.Create(SAlreadyConnectedTrackPoint);630 end;631 632 procedure TTrackPoint.Disconnect(TrackPoint: TTrackPoint);633 var634 Index: Integer;635 Link: TTrackLink;636 begin637 Index := NeighPoints.IndexOf(TrackPoint);638 if NeighPoints.IndexOf(TrackPoint) <> -1 then begin639 NeighPoints.Delete(Index);640 TrackPoint.NeighPoints.Remove(Self);641 642 // Remove link from both track points643 Link := NeighLinks.SearchPoints(Self, TrackPoint);644 NeighLinks.Remove(Link);645 TrackPoint.NeighLinks.Remove(Link);646 Track.Links.Remove(Link);647 end else raise Exception.Create(SAlreadyDisconnectedTrackPoint);648 end;649 650 function TTrackPoint.GetDown: TTrackPoint;651 var652 I: Integer;653 begin654 I := Track.Points.IndexOf(Self) - 1;655 while (I >= 0) and not Assigned(Track.Points[I].LineStation) do656 Dec(I);657 if I >= 0 then Result := Track.Points[I]658 else Result := nil;659 end;660 661 function TTrackPoint.GetUp: TTrackPoint;662 var663 I: Integer;664 begin665 I := Track.Points.IndexOf(Self) + 1;666 while (I < Track.Points.Count) and not Assigned(Track.Points[I].LineStation) do667 Inc(I);668 if I < Track.Points.Count then Result := Track.Points[I]669 else Result := nil;670 end;671 672 function TTrackPoint.GetNeighDown: TTrackPoint;673 var674 NewIndex: Integer;675 begin676 Result := nil;677 NewIndex := Track.Points.IndexOf(Self) - 1;678 if NewIndex >= 0 then Result := Track.Points[NewIndex];679 end;680 681 function TTrackPoint.GetNeighUp: TTrackPoint;682 var683 NewIndex: Integer;684 begin685 Result := nil;686 if Assigned(Track) then begin687 NewIndex := Track.Points.IndexOf(Self) + 1;688 if NewIndex < Track.Points.Count then Result := Track.Points[NewIndex];689 end;690 end;691 692 function TTrackPoint.GetLinkDown: TTrackLink;693 begin694 if Assigned(LinkDown) then Result := LinkDown695 else begin696 LinkDown := TTrackLink.Create;697 LinkDown.Points.Add(GetNeighDown);698 LinkDown.Points.Add(Self);699 Result := LinkDown;700 GetNeighDown.LinkUp := LinkDown;701 end;702 end;703 704 function TTrackPoint.GetLinkUp: TTrackLink;705 begin706 if Assigned(LinkUp) then Result := LinkUp707 else begin708 LinkUp := TTrackLink.Create;709 LinkUp.Points.Add(Self);710 LinkUp.Points.Add(GetNeighUp);711 Result := LinkUp;712 GetNeighUp.LinkDown := LinkUp;713 end;714 end;715 716 function TTrackPoint.GetDistance: Integer;717 var718 Index: Integer;719 begin720 Index := Track.Points.IndexOf(Self);721 Result := Distance(Track.Points[Index + 1].Position, Track.Points[Index].Position);722 end;723 724 constructor TTrackPoint.Create;725 begin726 NeighPoints := TTrackPoints.Create;727 NeighPoints.OwnsObjects := False;728 NeighLinks := TTrackLinks.Create;729 NeighLinks.OwnsObjects := False;730 end;731 732 destructor TTrackPoint.Destroy;733 begin734 FreeAndNil(NeighLinks);735 FreeAndNil(NeighPoints);736 317 inherited; 737 318 end; … … 854 435 procedure TMetroLine.UpdateEndingLine(EndIndex, Direction: Integer); 855 436 var 856 Index: Integer;857 NewTrackPoint: TTrackPoint;437 //Index: Integer; 438 //NewTrackPoint: TTrackPoint; 858 439 Angle: Double; 859 440 EndPoint: TPoint; … … 922 503 923 504 NewTrackPoint := Track.Points.AddNew; 924 NewTrackPoint. LineStation:= NewLineStation;505 NewTrackPoint.OwnerPoint := NewLineStation; 925 506 NewTrackPoint.Position := Station.Position; 926 507 NewTrackPoint.PositionDesigned := NewTrackPoint.Position; … … 986 567 // Delete old trackpoints 987 568 Index := Track.Points.IndexOf(ALineStation.TrackPoint) - 1; 988 while (Index >= 0) and (not Assigned(Track.Points[Index]. LineStation)) do begin569 while (Index >= 0) and (not Assigned(Track.Points[Index].OwnerPoint)) do begin 989 570 Track.Points.Delete(Index); 990 571 Dec(Index); … … 992 573 Index := Index + 1; 993 574 Track.Points.Delete(Index); 994 while (Index < Track.Points.Count) and (not Assigned(Track.Points[Index]. LineStation)) do575 while (Index < Track.Points.Count) and (not Assigned(Track.Points[Index].OwnerPoint)) do 995 576 Track.Points.Delete(Index); 996 577 … … 1020 601 end; 1021 602 1022 procedure TTrack.RouteTrack(TP1, TP2: TTrackPoint);1023 var1024 NewTrackPoint: TTrackPoint;1025 Delta: TPoint;1026 P1, P2: TPoint;1027 Index1, Index2: Integer;1028 begin1029 RemoveTrackBetween(TP1, TP2);1030 Index1 := Points.IndexOf(TP1);1031 Index2 := Points.IndexOf(TP2);1032 P1 := Points[Index1].PositionDesigned;1033 P2 := Points[Index2].PositionDesigned;1034 NewTrackPoint := Points.AddNew;1035 Delta := Point(P2.X - P1.X, P2.Y - P1.Y);1036 if Abs(Delta.X) > Abs(Delta.Y) then begin1037 NewTrackPoint.PositionDesigned := Point(P2.X - Sign(Delta.X) * Abs(Delta.Y), P1.Y);1038 NewTrackPoint.Position := NewTrackPoint.PositionDesigned;1039 end else begin1040 NewTrackPoint.PositionDesigned := Point(P1.X, P2.Y - Sign(Delta.Y) * Abs(Delta.X));1041 NewTrackPoint.Position := NewTrackPoint.PositionDesigned;1042 end;1043 Points.Insert(Index1 + 1, NewTrackPoint);1044 end;1045 1046 procedure TTrack.RemoveTrackBetween(TP1, TP2: TTrackPoint);1047 var1048 Index1, Index2: Integer;1049 Temp: Integer;1050 I: Integer;1051 begin1052 Index1 := Points.IndexOf(TP1);1053 Index2 := Points.IndexOf(TP2);1054 if (Index1 = -1) then1055 raise Exception.Create(Format(STrackPointNotFound, [1]));1056 if (Index2 = -1) then1057 raise Exception.Create(Format(STrackPointNotFound, [2]));1058 if Index1 > Index2 then begin1059 Temp := Index1;1060 Index1 := Index2;1061 Index2 := Temp;1062 end;1063 for I := 1 to Index2 - Index1 - 1 do1064 Points.Delete(Index1 + 1);1065 end;1066 1067 function TMetroLine.GetTrackLength: Integer;1068 var1069 I: Integer;1070 begin1071 Result := 0;1072 for I := 0 to Track.Points.Count - 1 do1073 if I > 0 then1074 Result := Result + Distance(Track.Points[I].Position, Track.Points[I - 1].Position);1075 end;1076 1077 603 constructor TMetroLine.Create; 1078 604 begin … … 1082 608 Trains.OwnsObjects := False; 1083 609 Track := TTrack.Create; 1084 Track. Line:= Self;610 Track.Owner := Self; 1085 611 end; 1086 612 … … 1705 1231 else Direction := -Direction; 1706 1232 TP := BaseTrackPoint.GetUp; 1707 if Assigned(TP) then TargetStation := T P.LineStation1233 if Assigned(TP) then TargetStation := TLineStation(TP.OwnerPoint) 1708 1234 else begin 1709 1235 TP := BaseTrackPoint.GetDown; 1710 if Assigned(TP) then TargetStation := T P.LineStation;1236 if Assigned(TP) then TargetStation := TLineStation(TP.OwnerPoint); 1711 1237 end; 1712 1238 end; … … 2344 1870 2345 1871 // Draw design time lines 2346 if Assigned(TrackStationDown) and Assigned(TrackStationDown. LineStation) then begin2347 Canvas.Pen.Color := T rackStationDown.Track.Line.Color;2348 Canvas.MoveTo(T rackStationDown.LineStation.TrackPoint.Position);1872 if Assigned(TrackStationDown) and Assigned(TrackStationDown.OwnerPoint) then begin 1873 Canvas.Pen.Color := TMetroLine(TrackStationDown.Track.Owner).Color; 1874 Canvas.MoveTo(TLineStation(TrackStationDown.OwnerPoint).TrackPoint.Position); 2349 1875 DrawLine(Canvas, View.PointDestToSrc(LastMousePos)); 2350 1876 end; 2351 if Assigned(TrackStationUp) and Assigned(TrackStationUp. LineStation) then begin2352 Canvas.Pen.Color := T rackStationUp.Track.Line.Color;2353 Canvas.MoveTo(T rackStationUp.LineStation.TrackPoint.Position);1877 if Assigned(TrackStationUp) and Assigned(TrackStationUp.OwnerPoint) then begin 1878 Canvas.Pen.Color := TMetroLine(TrackStationUp.Track.Owner).Color; 1879 Canvas.MoveTo(TLineStation(TrackStationUp.OwnerPoint).TrackPoint.Position); 2354 1880 DrawLine(Canvas, View.PointDestToSrc(LastMousePos)); 2355 1881 end; … … 2589 2115 Line := nil; 2590 2116 if Assigned(TrackStationDown) then begin 2591 Line := T rackStationDown.Track.Line;2117 Line := TMetroLine(TrackStationDown.Track.Owner); 2592 2118 Redraw; 2593 2119 end; 2594 2120 if Assigned(TrackStationUp) then begin 2595 Line := T rackStationUp.Track.Line;2121 Line := TMetroLine(TrackStationUp.Track.Owner); 2596 2122 Redraw; 2597 2123 end; 2598 2124 if Assigned(Line) and not Assigned(LastFocusedStation) and Assigned(FocusedStation) then begin 2599 if Assigned(TrackStationDown) and (T rackStationDown.LineStation.MapStation = FocusedStation) then begin2125 if Assigned(TrackStationDown) and (TLineStation(TrackStationDown.OwnerPoint).MapStation = FocusedStation) then begin 2600 2126 // Disconnect down 2601 2127 CurrentTrackPoint := TrackStationDown; 2602 2128 TrackStationDown := TrackStationDown.GetDown; 2603 Line.DisconnectStation( CurrentTrackPoint.LineStation);2129 Line.DisconnectStation(TLineStation(CurrentTrackPoint.OwnerPoint)); 2604 2130 end else 2605 if Assigned(TrackStationUp) and (T rackStationUp.LineStation.MapStation = FocusedStation) then begin2131 if Assigned(TrackStationUp) and (TLineStation(TrackStationUp.OwnerPoint).MapStation = FocusedStation) then begin 2606 2132 // Disconnect up 2607 2133 CurrentTrackPoint := TrackStationUp; 2608 2134 if Assigned(TrackStationUp) then 2609 2135 TrackStationUp := TrackStationUp.GetUp; 2610 Line.DisconnectStation( CurrentTrackPoint.LineStation);2136 Line.DisconnectStation(TLineStation(CurrentTrackPoint.OwnerPoint)); 2611 2137 end else 2612 2138 if Assigned(Line) and ((not Line.IsCircular) or ((TrackStationDown <> nil) and (TrackStationUp <> nil))) and … … 2617 2143 ((TrackStationDown = nil) or (TrackStationUp = nil)) and 2618 2144 (not Line.IsCircular))) then begin 2619 if Assigned(TrackStationDown) then LineStationDown := T rackStationDown.LineStation2145 if Assigned(TrackStationDown) then LineStationDown := TLineStation(TrackStationDown.OwnerPoint) 2620 2146 else LineStationDown := nil; 2621 if Assigned(TrackStationUp) then LineStationUp := T rackStationUp.LineStation2147 if Assigned(TrackStationUp) then LineStationUp := TLineStation(TrackStationUp.OwnerPoint) 2622 2148 else LineStationUp := nil; 2623 2149 Line.ConnectStation(FocusedStation, LineStationDown, LineStationUp); … … 2674 2200 FocusedTrack := GetTrackOnPos(View.PointDestToSrc(Position)); 2675 2201 if Assigned(FocusedTrack.Points[0]) then begin 2676 SelectedTrain.Line := FocusedTrack.Points[0].Track.Line;2202 SelectedTrain.Line := TMetroLine(FocusedTrack.Points[0].Track.Owner); 2677 2203 SelectedTrain.Line.Trains.Add(SelectedTrain); 2678 2204 SelectedTrain.BaseTrackPoint := FocusedTrack.Points[0]; 2679 2205 end else 2680 2206 if Assigned(FocusedTrack.Points[1]) then begin 2681 SelectedTrain.Line := FocusedTrack.Points[1].Track.Line;2207 SelectedTrain.Line := TMetroLine(FocusedTrack.Points[1].Track.Owner); 2682 2208 SelectedTrain.Line.Trains.Add(SelectedTrain); 2683 2209 SelectedTrain.BaseTrackPoint := FocusedTrack.Points[1]; … … 2695 2221 2696 2222 // Remove single line station on line 2697 if Assigned(TrackStationDown) and (TrackStationDown.Track.Line.LineStations.Count = 1) then begin 2698 TrackStationDown.Track.Line.DisconnectStation(TrackStationDown.Track.Line.LineStations.First); 2699 end; 2700 if Assigned(TrackStationUp) and (TrackStationUp.Track.Line.LineStations.Count = 1) then begin 2701 TrackStationUp.Track.Line.DisconnectStation(TrackStationUp.Track.Line.LineStations.First); 2223 if Assigned(TrackStationDown) and (TMetroLine(TrackStationDown.Track.Owner).LineStations.Count = 1) then begin 2224 TMetroLine(TrackStationDown.Track.Owner).DisconnectStation( 2225 TMetroLine(TrackStationDown.Track.Owner).LineStations.First); 2226 end; 2227 if Assigned(TrackStationUp) and (TMetroLine(TrackStationUp.Track.Owner).LineStations.Count = 1) then begin 2228 TMetroLine(TrackStationUp.Track.Owner).DisconnectStation( 2229 TMetroLine(TrackStationUp.Track.Owner).LineStations.First); 2702 2230 end; 2703 2231 end; … … 2756 2284 Track := GetTrackOnPos(View.PointDestToSrc(Position)); 2757 2285 if Assigned(Track) and Assigned(Track.Points[0]) and Assigned(Track.Points[1]) then begin 2758 SelectedLine := T rack.Points[0].Track.Line;2286 SelectedLine := TMetroLine(Track.Points[0].Track.Owner); 2759 2287 2760 2288 TrackStationDown := Track.Points[0]; 2761 2289 NewIndex := TrackStationDown.Track.Points.IndexOf(TrackStationDown); 2762 while Assigned(TrackStationDown) and (not Assigned(TrackStationDown. LineStation)) do begin2290 while Assigned(TrackStationDown) and (not Assigned(TrackStationDown.OwnerPoint)) do begin 2763 2291 NewIndex := NewIndex - 1; 2764 2292 if NewIndex >= 0 then TrackStationDown := TrackStationDown.Track.Points[NewIndex] … … 2767 2295 TrackStationUp := Track.Points[1]; 2768 2296 NewIndex := TrackStationUp.Track.Points.IndexOf(TrackStationDown); 2769 while Assigned(TrackStationUp) and (not Assigned(TrackStationUp. LineStation)) do begin2297 while Assigned(TrackStationUp) and (not Assigned(TrackStationUp.OwnerPoint)) do begin 2770 2298 NewIndex := NewIndex + 1; 2771 2299 if NewIndex < TrackStationUp.Track.Points.Count then -
trunk/UTrack.pas
r86 r91 4 4 5 5 uses 6 Classes, SysUtils, Generics.Collections;6 Classes, SysUtils, Math, Generics.Collections; 7 7 8 8 type 9 9 TTrack = class; 10 10 TTrackPoints = class; 11 TTrackLink = class; 11 12 TTrackLinks = class; 12 13 … … 14 15 15 16 TTrackPoint = class 17 OwnerPoint: TObject; 18 Position: TPoint; 19 //PositionShift: TPoint; 20 PositionDesigned: TPoint; 21 Pending: Boolean; 16 22 Track: TTrack; 17 Position: TPoint;18 23 NeighPoints: TTrackPoints; 19 24 NeighLinks: TTrackLinks; 25 LinkUp: TTrackLink; 26 LinkDown: TTrackLink; 20 27 procedure Connect(TrackPoint: TTrackPoint); 21 28 procedure Disconnect(TrackPoint: TTrackPoint); 29 function GetDown: TTrackPoint; 30 function GetUp: TTrackPoint; 31 function GetNeighDown: TTrackPoint; 32 function GetNeighUp: TTrackPoint; 33 function GetLinkDown: TTrackLink; 34 function GetLinkUp: TTrackLink; 35 // Move to TTrackLink later 36 function GetDistance: Integer; 22 37 constructor Create; 23 38 destructor Destroy; override; … … 27 42 28 43 TTrackPoints = class(TObjectList<TTrackPoint>) 44 Track: TTrack; 45 function AddNew: TTrackPoint; 29 46 end; 30 47 … … 32 49 33 50 TTrackLink = class 34 Track: TTrack;35 51 Points: TTrackPoints; 52 Shift: TPoint; 36 53 constructor Create; 37 54 destructor Destroy; override; … … 42 59 TTrackLinks = class(TObjectList<TTrackLink>) 43 60 function SearchPoints(Point1, Point2: TTrackPoint): TTrackLink; 61 function AddNew: TTrackLink; 44 62 end; 45 63 … … 47 65 48 66 TTrack = class 49 public50 67 Points: TTrackPoints; 51 68 Links: TTrackLinks; 52 function AddNew: TTrackPoint; 69 Owner: TObject; 70 function GetLength: Integer; 71 procedure RouteTrack(TP1, TP2: TTrackPoint); 72 procedure RemoveTrackBetween(TP1, TP2: TTrackPoint); 53 73 constructor Create; 54 74 destructor Destroy; override; 55 procedure RemoveTrackBetween(TP1, TP2: TTrackPoint); 75 end; 76 77 { TTrackPointsAngle } 78 79 TTrackPointsAngle = class 80 Angle: Double; 81 TrackLinks: TTrackLinks; 82 constructor Create; 83 destructor Destroy; override; 84 end; 85 86 { TTrackPointsAngleGroup } 87 88 TTrackPointsAngleGroup = class(TObjectList<TTrackPointsAngle>) 89 function SearchAngle(Angle: Double): TTrackPointsAngle; 56 90 end; 57 91 58 92 59 93 implementation 94 95 uses 96 UGeometric; 97 98 resourcestring 99 SAlreadyConnectedTrackPoint = 'Trying to connect already connected track point'; 100 SAlreadyDisconnectedTrackPoint = 'Trying to disconnect not connected track point'; 101 STrackPointNotFound = 'Track point %d not found'; 60 102 61 103 { TTrackLinks } … … 67 109 I := 0; 68 110 while (I < 0) and 69 ((Items[I].Points.First <> Point1) or (Items[I].Points.Last <> Point2))70 and((Items[I].Points.First <> Point2) or (Items[I].Points.Last <> Point1)) do111 ((Items[I].Points.First <> Point1) or (Items[I].Points.Last <> Point2)) and 112 ((Items[I].Points.First <> Point2) or (Items[I].Points.Last <> Point1)) do 71 113 Inc(I); 72 114 if I < 0 then Result := Items[I] … … 74 116 end; 75 117 118 function TTrackLinks.AddNew: TTrackLink; 119 begin 120 Result := TTrackLink.Create; 121 end; 122 123 { TTrackPoints } 124 125 function TTrackPoints.AddNew: TTrackPoint; 126 begin 127 Result := TTrackPoint.Create; 128 Result.Track := Track; 129 end; 130 131 { TTrack } 132 133 constructor TTrack.Create; 134 begin 135 Points := TTrackPoints.Create; 136 Points.Track := Self; 137 Links := TTrackLinks.Create; 138 end; 139 140 destructor TTrack.Destroy; 141 begin 142 FreeAndNil(Points); 143 FreeAndNil(Links); 144 inherited; 145 end; 146 147 function TTrack.GetLength: Integer; 148 var 149 I: Integer; 150 begin 151 Result := 0; 152 for I := 0 to Points.Count - 1 do 153 if I > 0 then 154 Result := Result + Distance(Points[I].Position, Points[I - 1].Position); 155 end; 156 157 procedure TTrack.RouteTrack(TP1, TP2: TTrackPoint); 158 var 159 NewTrackPoint: TTrackPoint; 160 Delta: TPoint; 161 P1, P2: TPoint; 162 Index1, Index2: Integer; 163 begin 164 RemoveTrackBetween(TP1, TP2); 165 Index1 := Points.IndexOf(TP1); 166 Index2 := Points.IndexOf(TP2); 167 P1 := Points[Index1].PositionDesigned; 168 P2 := Points[Index2].PositionDesigned; 169 NewTrackPoint := Points.AddNew; 170 Delta := Point(P2.X - P1.X, P2.Y - P1.Y); 171 if Abs(Delta.X) > Abs(Delta.Y) then begin 172 NewTrackPoint.PositionDesigned := Point(P2.X - Sign(Delta.X) * Abs(Delta.Y), P1.Y); 173 NewTrackPoint.Position := NewTrackPoint.PositionDesigned; 174 end else begin 175 NewTrackPoint.PositionDesigned := Point(P1.X, P2.Y - Sign(Delta.Y) * Abs(Delta.X)); 176 NewTrackPoint.Position := NewTrackPoint.PositionDesigned; 177 end; 178 Points.Insert(Index1 + 1, NewTrackPoint); 179 end; 180 181 procedure TTrack.RemoveTrackBetween(TP1, TP2: TTrackPoint); 182 var 183 Index1, Index2: Integer; 184 Temp: Integer; 185 I: Integer; 186 begin 187 Index1 := Points.IndexOf(TP1); 188 Index2 := Points.IndexOf(TP2); 189 if (Index1 = -1) then 190 raise Exception.Create(Format(STrackPointNotFound, [1])); 191 if (Index2 = -1) then 192 raise Exception.Create(Format(STrackPointNotFound, [2])); 193 if Index1 > Index2 then begin 194 Temp := Index1; 195 Index1 := Index2; 196 Index2 := Temp; 197 end; 198 for I := 1 to Index2 - Index1 - 1 do 199 Points.Delete(Index1 + 1); 200 end; 201 76 202 { TTrackLink } 77 203 … … 84 210 destructor TTrackLink.Destroy; 85 211 begin 86 Points.Free;212 FreeAndNil(Points); 87 213 inherited; 88 214 end; 89 215 90 { TTrackPoints } 91 92 function TTrack.AddNew: TTrackPoint; 93 begin 94 Result := TTrackPoint.Create; 95 Result.Track := Self; 96 Points.Add(Result); 216 { TTrackPointsAngleGroup } 217 218 function TTrackPointsAngleGroup.SearchAngle(Angle: Double): TTrackPointsAngle; 219 var 220 I: Integer; 221 begin 222 I := 0; 223 while (I < Count) and (Items[I].Angle <> Angle) do Inc(I); 224 if I < Count then Result := Items[I] 225 else Result := nil; 226 end; 227 228 { TTrackPointsAngle } 229 230 constructor TTrackPointsAngle.Create; 231 begin 232 TrackLinks := TTrackLinks.Create; 233 TrackLinks.OwnsObjects := False; 234 end; 235 236 destructor TTrackPointsAngle.Destroy; 237 begin 238 FreeAndNil(TrackLinks); 239 inherited; 97 240 end; 98 241 … … 106 249 NeighPoints.Add(TrackPoint); 107 250 TrackPoint.NeighPoints.Add(Self); 108 // Add new link 109 NewLink := TTrackLink.Create; 251 252 // Add new link to both self and connected track point 253 NewLink := Track.Links.AddNew; 110 254 NewLink.Points.Add(TrackPoint); 111 255 NewLink.Points.Add(Self); … … 113 257 TrackPoint.NeighLinks.Add(NewLink); 114 258 Track.Links.Add(NewLink); 115 end ;259 end else raise Exception.Create(SAlreadyConnectedTrackPoint); 116 260 end; 117 261 … … 125 269 NeighPoints.Delete(Index); 126 270 TrackPoint.NeighPoints.Remove(Self); 127 // Remove link 271 272 // Remove link from both track points 128 273 Link := NeighLinks.SearchPoints(Self, TrackPoint); 129 274 NeighLinks.Remove(Link); 130 275 TrackPoint.NeighLinks.Remove(Link); 131 276 Track.Links.Remove(Link); 132 end; 277 end else raise Exception.Create(SAlreadyDisconnectedTrackPoint); 278 end; 279 280 function TTrackPoint.GetDown: TTrackPoint; 281 var 282 I: Integer; 283 begin 284 I := Track.Points.IndexOf(Self) - 1; 285 while (I >= 0) and not Assigned(Track.Points[I].OwnerPoint) do 286 Dec(I); 287 if I >= 0 then Result := Track.Points[I] 288 else Result := nil; 289 end; 290 291 function TTrackPoint.GetUp: TTrackPoint; 292 var 293 I: Integer; 294 begin 295 I := Track.Points.IndexOf(Self) + 1; 296 while (I < Track.Points.Count) and not Assigned(Track.Points[I].OwnerPoint) do 297 Inc(I); 298 if I < Track.Points.Count then Result := Track.Points[I] 299 else Result := nil; 300 end; 301 302 function TTrackPoint.GetNeighDown: TTrackPoint; 303 var 304 NewIndex: Integer; 305 begin 306 Result := nil; 307 NewIndex := Track.Points.IndexOf(Self) - 1; 308 if NewIndex >= 0 then Result := Track.Points[NewIndex]; 309 end; 310 311 function TTrackPoint.GetNeighUp: TTrackPoint; 312 var 313 NewIndex: Integer; 314 begin 315 Result := nil; 316 if Assigned(Track) then begin 317 NewIndex := Track.Points.IndexOf(Self) + 1; 318 if NewIndex < Track.Points.Count then Result := Track.Points[NewIndex]; 319 end; 320 end; 321 322 function TTrackPoint.GetLinkDown: TTrackLink; 323 begin 324 if Assigned(LinkDown) then Result := LinkDown 325 else begin 326 LinkDown := TTrackLink.Create; 327 LinkDown.Points.Add(GetNeighDown); 328 LinkDown.Points.Add(Self); 329 Result := LinkDown; 330 GetNeighDown.LinkUp := LinkDown; 331 end; 332 end; 333 334 function TTrackPoint.GetLinkUp: TTrackLink; 335 begin 336 if Assigned(LinkUp) then Result := LinkUp 337 else begin 338 LinkUp := TTrackLink.Create; 339 LinkUp.Points.Add(Self); 340 LinkUp.Points.Add(GetNeighUp); 341 Result := LinkUp; 342 GetNeighUp.LinkDown := LinkUp; 343 end; 344 end; 345 346 function TTrackPoint.GetDistance: Integer; 347 var 348 Index: Integer; 349 begin 350 Index := Track.Points.IndexOf(Self); 351 Result := Distance(Track.Points[Index + 1].Position, Track.Points[Index].Position); 133 352 end; 134 353 … … 137 356 NeighPoints := TTrackPoints.Create; 138 357 NeighPoints.OwnsObjects := False; 358 NeighLinks := TTrackLinks.Create; 359 NeighLinks.OwnsObjects := False; 139 360 end; 140 361 141 362 destructor TTrackPoint.Destroy; 142 var 143 I: Integer; 144 begin 145 // Disconnect from all before destruction 146 for I := NeighPoints.Count - 1 downto 0 do 147 NeighPoints[I].Disconnect(Self); 148 if Assigned(Track) then Track.Points.Remove(Self); 149 NeighPoints.Free; 363 begin 364 FreeAndNil(NeighLinks); 365 FreeAndNil(NeighPoints); 150 366 inherited; 151 367 end; 152 368 153 { TTrack }154 155 constructor TTrack.Create;156 begin157 Points := TTrackPoints.Create;158 end;159 160 destructor TTrack.Destroy;161 begin162 Points.Free;163 inherited;164 end;165 166 procedure TTrack.RemoveTrackBetween(TP1, TP2: TTrackPoint);167 var168 Index1, Index2: Integer;169 Temp: Integer;170 I: Integer;171 begin172 Index1 := Points.IndexOf(TP1);173 Index2 := Points.IndexOf(TP2);174 if (Index1 = -1) then175 raise Exception.Create('TrackPoint1 not found');176 if (Index2 = -1) then177 raise Exception.Create('TrackPoint2 not found');178 if Index1 > Index2 then begin179 Temp := Index1;180 Index1 := Index2;181 Index2 := Temp;182 end;183 for I := 1 to Index2 - Index1 - 1 do184 Points.Delete(Index1 + 1);185 end;186 187 188 369 end. 189 370
Note:
See TracChangeset
for help on using the changeset viewer.