source: trunk/class/mazepainter.pas

Last change on this file was 7, checked in by chronos, 11 years ago
  • Added: Allow terminate solving process.
  • Fixed: Disable actions which can change maze during solving.
File size: 6.3 KB
Line 
1{
2 Maze painter class of the Lazarus Mazes program
3
4 Copyright (C) 2012 G.A. Nijland (eny @ lazarus forum http://www.lazarus.freepascal.org/)
5
6 This source is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
8 version.
9
10 This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
11 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 details.
13
14 A copy of the GNU General Public License is available on the World Wide Web at
15 <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17}
18unit MazePainter;
19
20{$mode objfpc}{$H+}
21
22interface
23
24uses
25 Maze,
26 Graphics, Classes, SysUtils;
27
28type
29
30 { TMazePainter }
31 TMazePainter = class
32 private
33 FCellDrawWidth: integer;
34 FCellDrawHeight: integer;
35 FisDirty: boolean;
36 Maze: TMaze;
37 FCanvas: TCanvas;
38 bmp: TBitMap;
39
40 FWallColor: TColor;
41 FWallShadowColor: TColor;
42 FCellColors: array[TCellState] of TColor;
43
44 function GetCellColor(const pState: TCellState): TColor;
45 procedure SetCellColor(const pState: TCellState; pColor: TColor);
46 procedure Grow(var pRect: TRect; const pdx, pdy: integer);
47
48 public
49 constructor Create(const pMaze: TMaze; pCanvas: TCanvas);
50 destructor Destroy; override;
51
52 procedure Paint(const pOffsetX: integer = 0; const pOffsetY: integer = 0);
53
54 function Width : integer;
55 function Height: integer;
56
57 property CellDrawWidth: integer read FCellDrawWidth write FCellDrawWidth;
58 property CellDrawHeight: integer read FCellDrawHeight write FCellDrawHeight;
59
60 property CellColor[const pState: TCellState]: TColor read GetCellColor write SetCellColor;
61 property WallColor: TColor read FWallColor write FWallColor;
62 property WallShadowColor: TColor read FWallShadowColor write FWallShadowColor;
63 property IsDirty: boolean read FisDirty write FisDirty;
64 end;
65
66implementation
67
68{ TMazePainter }
69
70constructor TMazePainter.Create(const pMaze: TMaze; pCanvas: TCanvas);
71begin
72 Bmp := TBitMap.Create;
73
74 // Init the default drawing width and height
75 FCellDrawWidth := 15;
76 FCellDrawHeight := 15;
77
78 // Set default colors
79 WallColor := clBlue;
80 CellColor[csEmpty] := clSkyBlue;
81 CellColor[csStart] := clYellow;
82 CellColor[csVisited] := clMaroon;
83 CellColor[csExit] := clGreen;
84
85 // Store maze and canvas for future reference
86 Maze := pMaze;
87 FCanvas := pCanvas;
88
89 // Refresh on the next draw
90 isDirty := true;
91end;
92
93destructor TMazePainter.Destroy;
94begin
95 FreeAndNil(Bmp);
96 inherited Destroy;
97end;
98
99function TMazePainter.GetCellColor(const pState: TCellState): TColor;
100begin
101 result := FCellColors[pState];
102end;
103
104procedure TMazePainter.SetCellColor(const pState: TCellState; pColor: TColor);
105begin
106 FCellColors[pState] := pColor
107end;
108
109procedure TMazePainter.Grow(var pRect: TRect; const pdx, pdy: integer);
110begin
111 dec(pRect.Left, pdx);
112 dec(pRect.Top, pdy);
113 inc(pRect.Right, pdx);
114 inc(pRect.Bottom, pdy);
115end;
116
117procedure TMazePainter.Paint(const pOffsetX: integer; const pOffsetY: integer);
118const C_LINE_THICK = 1;
119var row,col: integer;
120 square : TRect;
121 Canvas : TCanvas;
122 dx,dy : integer;
123begin
124 if isDirty then
125 begin
126 bmp.SetSize(Width + 1, Height + 1);
127 Canvas := bmp.Canvas;
128 try
129 Bmp.BeginUpdate(True);
130 for row := 0 to Maze.Height-1 do
131 for col := 0 to Maze.Width-1 do
132 begin
133 // Draw the empty cell frame
134 Canvas.Brush.Color := CellColor[csEmpty];
135 Canvas.Pen.Color := Canvas.Brush.Color;
136
137 square.Top := row * CellDrawHeight;
138 square.Left := col * CellDrawWidth;
139 square.Right := square.Left + CellDrawWidth;
140 square.Bottom := square.Top + CellDrawHeight;
141 Canvas.Rectangle(square);
142
143 // draw walls
144 Canvas.Pen.color := FWallColor;
145 Canvas.Pen.Width := C_LINE_THICK;
146 Canvas.Pen.JoinStyle := pjsBevel;
147 with Maze[row,col] do
148 begin
149 if not CanGo[dirNorth] then
150 begin
151 Canvas.Line(square.Left, Square.Top, square.right, square.Top);
152 Canvas.Pen.color := clMoneyGreen;
153 Canvas.Line(square.Left+1, Square.Top+1, square.right-1, square.Top+1);
154 Canvas.Pen.color := clBlue;
155 end;
156 if not CanGo[dirSouth] then Canvas.Line(square.Left, Square.Bottom, square.right, square.Bottom);
157 if not CanGo[dirWest] then
158 begin
159 Canvas.Line(square.Left, Square.Top, square.Left, square.Bottom);
160 Canvas.Pen.color := clMoneyGreen;
161 Canvas.Line(square.Left+1, Square.Top+1, square.Left+1, square.Bottom-1);
162 Canvas.Pen.color := clBlue;
163 end;
164 if not CanGo[dirEast] then Canvas.Line(square.Right, Square.Top, square.Right, square.Bottom);
165 end;
166
167 // Draw inside when the cell is not empty
168 if Maze[row,col].State <> csEmpty then
169 begin
170 // Determine a visibly pleasing margin with the walls
171 if FCellDrawWidth < 13 then dx := -1 else dx := -3;
172 if FCellDrawHeight < 13 then dy := -1 else dy := -3;
173 // Shring by this margin and draw the cell's inside
174 Grow(square, dx, dy);
175 Canvas.Brush.Color := CellColor[Maze[row,col].State];
176 Canvas.Pen.Color := CellColor[Maze[row,col].State];
177 Canvas.Rectangle(square);
178 end;
179 end;
180
181 finally
182 Bmp.EndUpdate;
183 end;
184 // Fully refreshed
185 isDirty := false;
186 end;
187
188 // Draw bitmap
189 FCanvas.Draw(pOffsetX, pOffsetY, Bmp); // Stretch draw should be faster
190 //FCanvas.CopyRect(Rect(pOffsetX,pOffsetY,pOffsetX+Width+1,pOffsetY+Height+1), bmp.Canvas, Rect(0,0,Width+1,Height+1));
191end;
192
193function TMazePainter.Width: integer;
194begin
195 result := Maze.Width * CellDrawWidth;
196end;
197
198function TMazePainter.Height: integer;
199begin
200 result := Maze.Height * CellDrawHeight;
201end;
202
203end.
204
Note: See TracBrowser for help on using the repository browser.