Changeset 28 for trunk


Ignore:
Timestamp:
Apr 12, 2015, 2:32:33 PM (10 years ago)
Author:
chronos
Message:
  • Added: Now user can place additional trains on line and move trains between lines and different places on line.
Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/UEngine.pas

    r27 r28  
    143143  TMetroTrain = class
    144144  private
     145    FLine: TMetroLine;
    145146    LastPosDelta: Integer;
    146147    LastTrainMoveTime: TDateTime;
    147148    StationStopTime: TDateTime;
     149    procedure SetLine(AValue: TMetroLine);
    148150  public
    149151    Passengers: TMetroPassengers;
    150     Line: TMetroLine;
     152
    151153    BaseTrackPoint: TTrackPoint;
    152154    RelPos: Double;
     
    159161    constructor Create;
    160162    destructor Destroy; override;
     163    property Line: TMetroLine read FLine write SetLine;
    161164  end;
    162165
     
    187190  end;
    188191
     192  { TView }
     193
    189194  TView = class
    190     Size: TPoint;
    191     Zoom: Double;
     195  private
     196    FDestRect: TRect;
     197    FZoom: Double;
     198    procedure SetDestRect(AValue: TRect);
     199    procedure SetZoom(AValue: Double);
     200  public
     201    SourceRect: TRect;
     202    constructor Create;
     203    property DestRect: TRect read FDestRect write SetDestRect;
     204    property Zoom: Double read FZoom write SetZoom;
    192205  end;
    193206
     
    213226    function GetStationOnPos(Pos: TPoint): TMapStation;
    214227    function GetTrackOnPos(Pos: TPoint): TTrack;
     228    function GetTrainOnPos(Pos: TPoint): TMetroTrain;
    215229    procedure DrawLine(Canvas: TCanvas; Pos: TPoint);
    216230    procedure DrawShape(Canvas: TCanvas; Position: TPoint; Shape: TStationShape;
     
    233247    View: TView;
    234248    SelectedLine: TMetroLine;
     249    SelectedTrain: TMetroTrain;
    235250    TrackStationDown: TTrackPoint;
    236251    TrackStationUp: TTrackPoint;
     
    285300  UGeometric;
    286301
     302resourcestring
     303  SZeroZoomNotAlowed = 'Zero zoom not allowed';
     304
     305{ TView }
     306
     307procedure TView.SetDestRect(AValue: TRect);
     308var
     309  Diff: TPoint;
     310begin
     311  if RectEquals(FDestRect, AValue) then Exit;
     312  Diff := Point(Trunc((DestRect.Right - DestRect.Left) / Zoom - (AValue.Right - AValue.Left) / Zoom) div 2,
     313    Trunc((DestRect.Bottom - DestRect.Top) / Zoom - (AValue.Bottom - AValue.Top) / Zoom) div 2);
     314  FDestRect := AValue;
     315  SourceRect := Bounds(SourceRect.Left + Diff.X, SourceRect.Top + Diff.Y,
     316    Trunc((DestRect.Right - DestRect.Left) / Zoom),
     317    Trunc((DestRect.Bottom - DestRect.Top) / Zoom));
     318end;
     319
     320procedure TView.SetZoom(AValue: Double);
     321begin
     322  if FZoom = AValue then Exit;
     323  if AValue = 0 then
     324    raise Exception.Create(SZeroZoomNotAlowed);
     325  FZoom := AValue;
     326  SourceRect := Bounds(Trunc(SourceRect.Left + (SourceRect.Right - SourceRect.Left) div 2 - (DestRect.Right - DestRect.Left) / Zoom / 2),
     327    Trunc(SourceRect.Top +  (SourceRect.Bottom - SourceRect.Top) div 2 - (DestRect.Bottom - DestRect.Top) / Zoom / 2),
     328    Trunc((DestRect.Right - DestRect.Left) / Zoom),
     329    Trunc((DestRect.Bottom - DestRect.Top) / Zoom));
     330end;
     331
     332constructor TView.Create;
     333begin
     334  Zoom := 1.5;
     335end;
     336
    287337{ TTracks }
    288338
     
    361411  NewIndex: Integer;
    362412begin
     413  Result := nil;
    363414  NewIndex := Line.TrackPoints.IndexOf(Self) - 1;
    364   if NewIndex >= 0 then Result := TTrackPoint(Line.TrackPoints[NewIndex])
    365     else Result := nil;
     415  if NewIndex >= 0 then Result := TTrackPoint(Line.TrackPoints[NewIndex]);
    366416end;
    367417
     
    370420  NewIndex: Integer;
    371421begin
    372   NewIndex := Line.TrackPoints.IndexOf(Self) + 1;
    373   if NewIndex < Line.TrackPoints.Count then Result := TTrackPoint(Line.TrackPoints[NewIndex])
    374     else Result := nil;
     422  Result := nil;
     423  if Assigned(Line) then begin
     424    NewIndex := Line.TrackPoints.IndexOf(Self) + 1;
     425    if NewIndex < Line.TrackPoints.Count then Result := TTrackPoint(Line.TrackPoints[NewIndex]);
     426  end;
    375427end;
    376428
     
    731783
    732784{ TMetroTrain }
     785
     786procedure TMetroTrain.SetLine(AValue: TMetroLine);
     787begin
     788  if FLine = AValue then Exit;
     789  FLine := AValue;
     790  if AValue = nil then begin
     791    RelPos := 0;
     792    BaseTrackPoint := nil;
     793    TargetStation := nil;
     794  end;
     795end;
    733796
    734797function TMetroTrain.GetTargetStationDistance: Integer;
     
    10131076    end;
    10141077    Inc(I);
     1078  end;
     1079end;
     1080
     1081function TEngine.GetTrainOnPos(Pos: TPoint): TMetroTrain;
     1082var
     1083  I: Integer;
     1084  MinDistance: Integer;
     1085  D: Integer;
     1086begin
     1087  Result := nil;
     1088  MinDistance := High(Integer);
     1089  for I := 0 to Trains.Count - 1 do
     1090  with TMetroTrain(Trains[I]) do begin
     1091    D := Distance(GetPosition, Pos);
     1092    if (D < (TrainSize div 2)) and (D < MinDistance) then begin
     1093      Result := TMetroTrain(Trains[I]);
     1094      MinDistance := D;
     1095    end;
    10151096  end;
    10161097end;
     
    12011282  for I := 0 to Trains.Count - 1 do
    12021283  with TMetroTrain(Trains[I]) do begin
     1284    if not Assigned(TargetStation) and Assigned(BaseTrackPoint) then begin
     1285      Direction := 1;
     1286      TargetStation := BaseTrackPoint.GetUp.LineStation;
     1287    end;
    12031288    if Assigned(Line) then begin
    12041289      if InStation then begin
     
    14261511  ShapePos: TPoint;
    14271512begin
    1428     // Draw trains
     1513  // Draw trains
    14291514  for I := 0 to Trains.Count - 1 do
    14301515  with TMetroTrain(Trains[I]) do begin
     
    15761661procedure TEngine.MouseUp(Button: TMouseButton; Position: TPoint);
    15771662var
    1578   Station: TMapStation;
    1579   Line: TMetroLine;
    1580   I: Integer;
     1663  I: Integer;
     1664  FocusedTrack: TTrack;
    15811665begin
    15821666  if Button = mbLeft then begin
     1667    // Place selected train if focused track
     1668    if Assigned(SelectedTrain) then begin
     1669      SelectedTrain.TargetStation := nil;
     1670      SelectedTrain.BaseTrackPoint := nil;
     1671      if Assigned(SelectedTrain.Line) then begin
     1672        SelectedTrain.Line.Trains.Remove(SelectedTrain);
     1673        SelectedTrain.Line := nil;
     1674      end;
     1675      FocusedTrack := GetTrackOnPos(Position);
     1676      if Assigned(FocusedTrack.PointDown) then begin
     1677        SelectedTrain.Line := FocusedTrack.PointDown.Line;
     1678        SelectedTrain.Line.Trains.Add(SelectedTrain);
     1679        SelectedTrain.BaseTrackPoint := FocusedTrack.PointDown;
     1680      end else
     1681      if Assigned(FocusedTrack.PointDown) then begin
     1682        SelectedTrain.Line := FocusedTrack.PointUp.Line;
     1683        SelectedTrain.Line.Trains.Add(SelectedTrain);
     1684        SelectedTrain.BaseTrackPoint := FocusedTrack.PointUp;
     1685      end;
     1686    end;
    15831687
    15841688    // Line color selection
    15851689    for I := 0 to Lines.Count - 1 do
    1586       if Distance(Point(View.Size.X div 2 - Length(LineColors) div 2 * LineColorsDist + I * LineColorsDist,
    1587         View.Size.Y - LineColorsDist), Position) < 20 then begin
     1690      if Distance(Point(View.DestRect.Right div 2 - Length(LineColors) div 2 * LineColorsDist + I * LineColorsDist,
     1691        View.DestRect.Bottom - LineColorsDist), Position) < 20 then begin
    15881692          SelectedLine := TMetroLine(Lines[I]);
    15891693          Exit;
     
    16041708  TrackStationDown := nil;
    16051709  TrackStationUp := nil;
     1710  SelectedTrain := nil;
    16061711end;
    16071712
     
    16181723    MouseHold := True;
    16191724    LastFocusedStation := nil;
     1725
     1726    // Train selection
     1727    SelectedTrain := GetTrainOnPos(Position);
     1728    if Assigned(SelectedTrain) then begin
     1729      Exit;
     1730    end;
     1731
     1732    // Select unused train
     1733    if (Distance(Position, Point(View.DestRect.Right div 2 - Length(LineColors) div 2 * LineColorsDist - 100,
     1734    View.DestRect.Bottom - LineColorsDist)) < 30) and
     1735    (Trains.GetUnusedCount > 0) then begin
     1736      SelectedTrain := Trains.GetUnusedTrain;
     1737      Exit;
     1738    end;
    16201739
    16211740    // Line selection
     
    16731792
    16741793  // Start with 3 stations with each different shape
    1675   InitialStationCount := 3;
     1794  InitialStationCount := 30;
    16761795  for I := 0 to InitialStationCount - 1 do begin
    16771796    NewStation := Stations.AddNew;
     
    17421861  PassengerPos: TPoint;
    17431862  Direction: Integer;
     1863  Points: array of TPoint;
    17441864const
    17451865  GameOverText = 'Game Over';
     
    18892009  end;
    18902010
    1891   // Interface
     2011  // Draw unused trains
     2012  Text := IntToStr(Trains.GetUnusedCount);
     2013  Canvas.Draw(Canvas.Width div 2 - Length(LineColors) div 2 * LineColorsDist - 100,
     2014    Canvas.Height - LineColorsDist - ImageLocomotive.Picture.Bitmap.Height div 2, ImageLocomotive.Picture.Bitmap);
     2015  Canvas.Brush.Style := bsClear;
     2016  Canvas.TextOut(Canvas.Width div 2 - Length(LineColors) div 2 * LineColorsDist - 50 - Canvas.TextWidth(Text),
     2017    Canvas.Height - LineColorsDist - Canvas.TextHeight(Text) div 2, Text);
     2018
     2019
     2020  // Status interface
    18922021  Text := IntToStr(ServedPassengerCount);
    18932022  Canvas.Draw(Canvas.Width - 140, 20, ImagePassenger.Picture.Bitmap);
     
    18952024  Canvas.TextOut(Canvas.Width - 146 - Canvas.TextWidth(Text), 25, Text);
    18962025
    1897   Text := IntToStr(Trains.GetUnusedCount);
    1898   Canvas.Draw(Canvas.Width - 240, 20, ImageLocomotive.Picture.Bitmap);
    1899   Canvas.Brush.Style := bsClear;
    1900   Canvas.TextOut(Canvas.Width - 246 - Canvas.TextWidth(Text), 25, Text);
    1901 
    19022026  DrawClock(Canvas);
     2027
     2028  if Assigned(SelectedTrain) then begin
     2029    Canvas.Brush.Color := clBlack; //SelectedTrain.Line.Color;
     2030    Canvas.Brush.Style := bsSolid;
     2031    Canvas.Pen.Style := psClear;
     2032    Pos := LastMousePos;
     2033    Angle := 0;
     2034
     2035    SetLength(Points, 4);
     2036    Points[0] := RotatePoint(Pos, Point(Pos.X - TrainSize div 2, Pos.Y - TrainSize div 3), Angle);
     2037    Points[1] := RotatePoint(Pos, Point(Pos.X + TrainSize div 2, Pos.Y - TrainSize div 3), Angle);
     2038    Points[2] := RotatePoint(Pos, Point(Pos.X + TrainSize div 2, Pos.Y + TrainSize div 3), Angle);
     2039    Points[3] := RotatePoint(Pos, Point(Pos.X - TrainSize div 2, Pos.Y + TrainSize div 3), Angle);
     2040    Canvas.Polygon(Points);
     2041  end;
    19032042
    19042043  // Game over
  • trunk/UFormMain.lfm

    r22 r28  
    1919    Width = 1139
    2020    Align = alClient
    21     OnClick = PaintBox1Click
    2221    OnMouseDown = PaintBox1MouseDown
    2322    OnMouseMove = PaintBox1MouseMove
  • trunk/UFormMain.pas

    r22 r28  
    2020    procedure FormKeyPress(Sender: TObject; var Key: char);
    2121    procedure FormShow(Sender: TObject);
    22     procedure PaintBox1Click(Sender: TObject);
    2322    procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
    2423      Shift: TShiftState; X, Y: Integer);
     
    6867begin
    6968  Randomize;
    70   Engine.View.Size := Point(PaintBox1.Width, PaintBox1.Height);
    71   Engine.Map.Size := Engine.View.Size;
     69  Engine.Map.Size := Point(PaintBox1.Width, PaintBox1.Height);
    7270  Engine.Reset;
    73 end;
    74 
    75 procedure TFormMain.PaintBox1Click(Sender: TObject);
    76 begin
    77 
    7871end;
    7972
     
    9891procedure TFormMain.PaintBox1Paint(Sender: TObject);
    9992begin
     93  Engine.View.DestRect := Rect(0, 0, PaintBox1.Width, PaintBox1.Height);
    10094  Engine.Paint(PaintBox1.Canvas);
    10195end;
     
    10397procedure TFormMain.PaintBox1Resize(Sender: TObject);
    10498begin
    105   //Engine.
    10699end;
    107100
  • trunk/UGeometric.pas

    r27 r28  
    2222function ArcTan2Point(Point: TPoint): Float;
    2323function ArcTanPoint(Point: TPoint): Float;
     24function RectEquals(A, B: TRect): Boolean;
    2425
    2526implementation
     
    125126end;
    126127
     128function RectEquals(A, B: TRect): Boolean;
     129begin
     130  Result := (A.Left = B.Left) and (A.Top = B.Top) and
     131    (A.Right = B.Right) and (A.Bottom = B.Bottom);
     132end;
     133
     134
    127135end.
    128136
Note: See TracChangeset for help on using the changeset viewer.