Changeset 30 for trunk/UEngine.pas
- Timestamp:
- Apr 18, 2015, 6:17:34 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UEngine.pas
r29 r30 6 6 7 7 uses 8 Classes, SysUtils, Contnrs, Graphics, Controls, ExtCtrls, Math, DateUtils; 8 Classes, SysUtils, Contnrs, Graphics, Controls, ExtCtrls, Math, DateUtils, 9 UMetaCanvas; 9 10 10 11 type … … 209 210 private 210 211 FDestRect: TRect; 212 FSourceRect: TRect; 211 213 FZoom: Double; 212 214 procedure SetDestRect(AValue: TRect); 215 procedure SetSourceRect(AValue: TRect); 213 216 procedure SetZoom(AValue: Double); 214 217 public 215 SourceRect: TRect; 218 function PointDestToSrc(Pos: TPoint): TPoint; 219 function PointSrcToDest(Pos: TPoint): TPoint; 216 220 constructor Create; 221 property SourceRect: TRect read FSourceRect write SetSourceRect; 217 222 property DestRect: TRect read FDestRect write SetDestRect; 218 223 property Zoom: Double read FZoom write SetZoom; … … 237 242 FTime: TDateTime; 238 243 FLastTime: TDateTime; 244 MetaCanvas: TMetaCanvas; 245 procedure ResizeView; 239 246 function GetExistStationShapes: TStationShapeSet; 240 247 function GetStationOnPos(Pos: TPoint): TMapStation; … … 273 280 constructor Create; 274 281 destructor Destroy; override; 275 procedure Paint( Canvas: TCanvas);282 procedure Paint(TargetCanvas: TCanvas); 276 283 property Time: TDateTime read FTime; 277 284 end; … … 307 314 NewTrainPeriod = 7; // Each week 308 315 NewPassengerPeriod = 0.3 * OneSecond; 309 NewPassengerProbability = 0.00 2;316 NewPassengerProbability = 0.003; 310 317 VisiblePassengersPerLine = 6; 311 318 … … 350 357 Trunc((DestRect.Bottom - DestRect.Top) / Zoom - (AValue.Bottom - AValue.Top) / Zoom) div 2); 351 358 FDestRect := AValue; 352 SourceRect := Bounds(SourceRect.Left + Diff.X,SourceRect.Top + Diff.Y,359 FSourceRect := Bounds(FSourceRect.Left + Diff.X, FSourceRect.Top + Diff.Y, 353 360 Trunc((DestRect.Right - DestRect.Left) / Zoom), 354 361 Trunc((DestRect.Bottom - DestRect.Top) / Zoom)); 362 end; 363 364 procedure TView.SetSourceRect(AValue: TRect); 365 var 366 ZX: Double; 367 ZY: Double; 368 begin 369 if RectEquals(FSourceRect, AValue) then Exit; 370 FSourceRect := AValue; 371 ZX := (FDestRect.Right - FDestRect.Left) / (FSourceRect.Right - FSourceRect.Left); 372 ZY := (FDestRect.Bottom - FDestRect.Top) / (FSourceRect.Bottom - FSourceRect.Top); 373 if ZX > ZY then 374 Zoom := ZY 375 else Zoom := ZX; 355 376 end; 356 377 … … 361 382 raise Exception.Create(SZeroZoomNotAlowed); 362 383 FZoom := AValue; 363 SourceRect := Bounds(Trunc(SourceRect.Left + (SourceRect.Right -SourceRect.Left) div 2 - (DestRect.Right - DestRect.Left) / Zoom / 2),364 Trunc( SourceRect.Top + (SourceRect.Bottom - SourceRect.Top) div 2 - (DestRect.Bottom - DestRect.Top) / Zoom / 2),384 FSourceRect := Bounds(Trunc(FSourceRect.Left + (FSourceRect.Right - FSourceRect.Left) div 2 - (DestRect.Right - DestRect.Left) / Zoom / 2), 385 Trunc(FSourceRect.Top + (FSourceRect.Bottom - FSourceRect.Top) div 2 - (FDestRect.Bottom - DestRect.Top) / Zoom / 2), 365 386 Trunc((DestRect.Right - DestRect.Left) / Zoom), 366 387 Trunc((DestRect.Bottom - DestRect.Top) / Zoom)); 367 388 end; 368 389 390 function TView.PointDestToSrc(Pos: TPoint): TPoint; 391 begin 392 Result := Point(Trunc(Pos.X / FZoom + FSourceRect.Left), 393 Trunc(Pos.Y / FZoom + FSourceRect.Top)); 394 end; 395 396 function TView.PointSrcToDest(Pos: TPoint): TPoint; 397 begin 398 Result := Point(Trunc((Pos.X - FSourceRect.Left) * FZoom), 399 Trunc((Pos.Y - FSourceRect.Top) * FZoom)); 400 end; 401 369 402 constructor TView.Create; 370 403 begin 371 Zoom := 1 .5;404 Zoom := 1; 372 405 end; 373 406 … … 1083 1116 1084 1117 { TEngine } 1118 1119 procedure TEngine.ResizeView; 1120 var 1121 StationRect: TRect; 1122 NewPoint: TPoint; 1123 begin 1124 // Need to see all stations on screen 1125 View.SourceRect := RectEnlarge(Stations.GetRect, 100); 1126 1127 NewPoint := Point( 1128 Trunc((View.SourceRect.Left + (View.SourceRect.Right - View.SourceRect.Left) / 2) - 1129 (View.DestRect.Left + (View.DestRect.Right - View.DestRect.Left) / 2 / View.Zoom)), 1130 Trunc((View.SourceRect.Top + (View.SourceRect.Bottom - View.SourceRect.Top) / 2) - 1131 (View.DestRect.Top + (View.DestRect.Bottom - View.DestRect.Top) / 2 / View.Zoom))); 1132 View.SourceRect := Bounds(NewPoint.X, NewPoint.Y, Trunc((View.DestRect.Right - View.DestRect.Left) / View.Zoom), 1133 Trunc((View.DestRect.Bottom - View.DestRect.Top) / View.Zoom)); 1134 end; 1085 1135 1086 1136 function TEngine.GetExistStationShapes: TStationShapeSet; … … 1618 1668 LastNewStationTime := Time; 1619 1669 Stations.AddNew; 1620 // Need to see all stations on screen 1621 View.SourceRect := RectEnlarge(Stations.GetRect, 70); 1670 ResizeView; 1622 1671 end; 1623 1672 … … 1676 1725 LastMousePos := Position; 1677 1726 if MouseHold then begin 1678 FocusedStation := GetStationOnPos( Position);1727 FocusedStation := GetStationOnPos(View.PointDestToSrc(Position)); 1679 1728 Line := nil; 1680 1729 if Assigned(TrackStationDown) then Line := TrackStationDown.Line; … … 1728 1777 SelectedTrain.Line := nil; 1729 1778 end; 1730 FocusedTrack := GetTrackOnPos( Position);1779 FocusedTrack := GetTrackOnPos(View.PointDestToSrc(Position)); 1731 1780 if Assigned(FocusedTrack.PointDown) then begin 1732 1781 SelectedTrain.Line := FocusedTrack.PointDown.Line; … … 1781 1830 1782 1831 // Train selection 1783 SelectedTrain := GetTrainOnPos( Position);1832 SelectedTrain := GetTrainOnPos(View.PointDestToSrc(Position)); 1784 1833 if Assigned(SelectedTrain) then begin 1785 1834 Exit; … … 1795 1844 1796 1845 // Line selection 1797 Track := GetTrackOnPos( Position);1846 Track := GetTrackOnPos(View.PointDestToSrc(Position)); 1798 1847 if Assigned(Track) and Assigned(Track.PointDown) and Assigned(Track.PointUp) then begin 1799 1848 SelectedLine := Track.PointDown.Line; … … 1820 1869 1821 1870 // New track creation from selected station as start 1822 Station := GetStationOnPos( Position);1871 Station := GetStationOnPos(View.PointDestToSrc(Position)); 1823 1872 if Assigned(Station) then begin 1824 1873 if Assigned(SelectedLine) and (SelectedLine.LineStations.Count = 0) then NewLine := SelectedLine … … 1862 1911 Trains.Add(NewTrain); 1863 1912 end; 1913 1914 ResizeView; 1864 1915 1865 1916 SelectedLine := nil; … … 1891 1942 if FileExists(ImageLocomotiveName) then 1892 1943 ImageLocomotive.Picture.LoadFromFile(ImageLocomotiveName); 1944 MetaCanvas := TMetaCanvas.Create; 1893 1945 end; 1894 1946 1895 1947 destructor TEngine.Destroy; 1896 1948 begin 1949 MetaCanvas.Free; 1897 1950 Trains.Free; 1898 1951 ImageLocomotive.Free; … … 1906 1959 end; 1907 1960 1908 procedure TEngine.Paint( Canvas: TCanvas);1961 procedure TEngine.Paint(TargetCanvas: TCanvas); 1909 1962 var 1910 1963 I: Integer; … … 1915 1968 Text: string; 1916 1969 Angle: Double; 1917 EndPoint: TPoint;1918 1970 PassengerPos: TPoint; 1919 1971 Direction: Integer; 1920 1972 Points: array of TPoint; 1973 Canvas: TMetaCanvas; 1921 1974 const 1922 1975 GameOverText = 'Game Over'; … … 1924 1977 GameOverStatistic = '%d passengers travelled on your metro over %d days.'; 1925 1978 begin 1926 Canvas .Brush.Color := $eff0e0;1927 Canvas. Brush.Style := bsSolid;1928 Canvas. Clear;1979 Canvas := MetaCanvas; 1980 Canvas.SetSize(Point(TargetCanvas.Width, TargetCanvas.Height)); 1981 Canvas.Reset; 1929 1982 1930 1983 // Draw station passenger overload … … 1988 2041 Canvas.Pen.Color := TrackStationDown.Line.Color; 1989 2042 Canvas.MoveTo(TrackStationDown.LineStation.TrackPoint.Position); 1990 DrawLine(Canvas, LastMousePos);2043 DrawLine(Canvas, View.PointDestToSrc(LastMousePos)); 1991 2044 end; 1992 2045 if Assigned(TrackStationUp) and Assigned(TrackStationUp.LineStation) then begin 1993 2046 Canvas.Pen.Color := TrackStationUp.Line.Color; 1994 2047 Canvas.MoveTo(TrackStationUp.LineStation.TrackPoint.Position); 1995 DrawLine(Canvas, LastMousePos);2048 DrawLine(Canvas, View.PointDestToSrc(LastMousePos)); 1996 2049 end; 1997 2050 … … 2006 2059 Canvas.Brush.Style := bsClear; 2007 2060 Canvas.Pen.Color := SelectedLine.Color; 2008 DrawShape(Canvas, Position, Shape, StationSize + Canvas.Pen.Width + 6, 0);2061 DrawShape(Canvas, Position, Shape, StationSize + Canvas.Pen.Width + 4, 0); 2009 2062 end; 2010 2063 … … 2046 2099 end; 2047 2100 2101 // Clear background 2102 TargetCanvas.Brush.Color := $eff0e0; 2103 TargetCanvas.Brush.Style := bsSolid; 2104 TargetCanvas.Clear; 2105 2106 MetaCanvas.Move(Point(-View.SourceRect.Left, -View.SourceRect.Top)); 2107 MetaCanvas.Zoom(View.Zoom); 2108 2109 // Draw meta canvas to real target canvas 2110 MetaCanvas.DrawTo(TargetCanvas); 2111 2048 2112 // Line selection 2049 2113 for I := 0 to High(LineColors) do begin 2050 2114 if Assigned(Lines.SearchByColor(LineColors[I])) then begin 2051 Canvas.Brush.Color := LineColors[I];2115 TargetCanvas.Brush.Color := LineColors[I]; 2052 2116 Size := 15; 2053 2117 end else begin 2054 Canvas.Brush.Color := clSilver;2118 TargetCanvas.Brush.Color := clSilver; 2055 2119 Size := 5; 2056 2120 end; 2057 Canvas.Pen.Color := clBlack;2121 TargetCanvas.Pen.Color := clBlack; 2058 2122 if Assigned(SelectedLine) and (SelectedLine.Color = LineColors[I]) then begin 2059 Canvas.Pen.Style := psSolid;2123 TargetCanvas.Pen.Style := psSolid; 2060 2124 end else begin 2061 Canvas.Pen.Style := psClear;2062 end; 2063 2064 Canvas.EllipseC(Canvas.Width div 2 - Length(LineColors) div 2 * LineColorsDist + I * LineColorsDist,2065 Canvas.Height - LineColorsDist, Size, Size);2125 TargetCanvas.Pen.Style := psClear; 2126 end; 2127 2128 TargetCanvas.EllipseC(TargetCanvas.Width div 2 - Length(LineColors) div 2 * LineColorsDist + I * LineColorsDist, 2129 TargetCanvas.Height - LineColorsDist, Size, Size); 2066 2130 end; 2067 2131 2068 2132 // Draw unused trains 2069 2133 Text := IntToStr(Trains.GetUnusedCount); 2070 Canvas.Draw(Canvas.Width div 2 - Length(LineColors) div 2 * LineColorsDist - 100, 2071 Canvas.Height - LineColorsDist - ImageLocomotive.Picture.Bitmap.Height div 2, ImageLocomotive.Picture.Bitmap); 2072 Canvas.Brush.Style := bsClear; 2073 Canvas.TextOut(Canvas.Width div 2 - Length(LineColors) div 2 * LineColorsDist - 50 - Canvas.TextWidth(Text), 2074 Canvas.Height - LineColorsDist - Canvas.TextHeight(Text) div 2, Text); 2075 2134 TargetCanvas.Draw(Canvas.Width div 2 - Length(LineColors) div 2 * LineColorsDist - 100, 2135 TargetCanvas.Height - LineColorsDist - ImageLocomotive.Picture.Bitmap.Height div 2, ImageLocomotive.Picture.Bitmap); 2136 TargetCanvas.Brush.Style := bsClear; 2137 TargetCanvas.TextOut(TargetCanvas.Width div 2 - Length(LineColors) div 2 * LineColorsDist - 50 - TargetCanvas.TextWidth(Text), 2138 TargetCanvas.Height - LineColorsDist - TargetCanvas.TextHeight(Text) div 2, Text); 2076 2139 2077 2140 // Status interface 2078 2141 Text := IntToStr(ServedPassengerCount); 2079 Canvas.Draw(Canvas.Width - 140, 20, ImagePassenger.Picture.Bitmap); 2080 Canvas.Brush.Style := bsClear; 2081 Canvas.TextOut(Canvas.Width - 146 - Canvas.TextWidth(Text), 25, Text); 2082 2083 DrawClock(Canvas); 2084 2142 TargetCanvas.Draw(TargetCanvas.Width - 140, 20, ImagePassenger.Picture.Bitmap); 2143 TargetCanvas.Brush.Style := bsClear; 2144 TargetCanvas.TextOut(TargetCanvas.Width - 146 - TargetCanvas.TextWidth(Text), 25, Text); 2145 2146 DrawClock(TargetCanvas); 2147 2148 // Show grabbed train by mouse 2085 2149 if Assigned(SelectedTrain) then begin 2086 Canvas.Brush.Color := clBlack; //SelectedTrain.Line.Color;2087 Canvas.Brush.Style := bsSolid;2088 Canvas.Pen.Style := psClear;2150 TargetCanvas.Brush.Color := clBlack; //SelectedTrain.Line.Color; 2151 TargetCanvas.Brush.Style := bsSolid; 2152 TargetCanvas.Pen.Style := psClear; 2089 2153 Pos := LastMousePos; 2090 2154 Angle := 0; … … 2095 2159 Points[2] := RotatePoint(Pos, Point(Pos.X + TrainSize div 2, Pos.Y + TrainSize div 3), Angle); 2096 2160 Points[3] := RotatePoint(Pos, Point(Pos.X - TrainSize div 2, Pos.Y + TrainSize div 3), Angle); 2097 Canvas.Polygon(Points);2161 TargetCanvas.Polygon(Points); 2098 2162 end; 2099 2163 … … 2101 2165 if State = gsGameOver then 2102 2166 begin 2103 Canvas.Font.Size := 40;2104 Canvas.Font.Color := clBlack;2105 Canvas.TextOut((Canvas.Width -Canvas.TextWidth(GameOverText)) div 2, 100, GameOverText);2106 Canvas.Font.Size := 14;2107 Canvas.TextOut((Canvas.Width -Canvas.TextWidth(GameOverReason)) div 2, 160, GameOverReason);2167 TargetCanvas.Font.Size := 40; 2168 TargetCanvas.Font.Color := clBlack; 2169 TargetCanvas.TextOut((TargetCanvas.Width - TargetCanvas.TextWidth(GameOverText)) div 2, 100, GameOverText); 2170 TargetCanvas.Font.Size := 14; 2171 TargetCanvas.TextOut((TargetCanvas.Width - TargetCanvas.TextWidth(GameOverReason)) div 2, 160, GameOverReason); 2108 2172 Text := Format(GameOverStatistic, [ServedPassengerCount, Trunc(Time)]); 2109 Canvas.TextOut((Canvas.Width -Canvas.TextWidth(Text)) div 2, 180, Text);2173 TargetCanvas.TextOut((TargetCanvas.Width - TargetCanvas.TextWidth(Text)) div 2, 180, Text); 2110 2174 end; 2111 2175 end;
Note:
See TracChangeset
for help on using the changeset viewer.