source: tags/1.3.0/Forms/UFormMain.pas

Last change on this file was 72, checked in by chronos, 4 years ago
File size: 6.3 KB
Line 
1unit UFormMain;
2
3{$mode delphi}{$H+}
4
5interface
6
7uses
8 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Menus, Math,
9 ActnList, ExtCtrls, StdCtrls, UGame, UPersistentForm, UApplicationInfo,
10 LCLType, Syncobjs, DateUtils;
11
12type
13 TFormMain = class;
14
15 { TMoveThread }
16
17 TMoveThread = class(TThread)
18 FormMain: TFormMain;
19 procedure Execute; override;
20 end;
21
22 { TFormMain }
23
24 TFormMain = class(TForm)
25 MainMenu1: TMainMenu;
26 MenuItem1: TMenuItem;
27 MenuItem2: TMenuItem;
28 MenuItem3: TMenuItem;
29 MenuItem4: TMenuItem;
30 MenuItemMovesHistory: TMenuItem;
31 MenuItemTools: TMenuItem;
32 MenuItemNew: TMenuItem;
33 MenuItemExit: TMenuItem;
34 MenuItemHelp: TMenuItem;
35 MenuItemAbout: TMenuItem;
36 MenuItemGame: TMenuItem;
37 TimerDraw: TTimer;
38 procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
39 procedure FormCreate(Sender: TObject);
40 procedure FormDestroy(Sender: TObject);
41 procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
42 procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
43 Shift: TShiftState; X, Y: Integer);
44 procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
45 procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
46 Shift: TShiftState; X, Y: Integer);
47 procedure FormPaint(Sender: TObject);
48 procedure FormShow(Sender: TObject);
49 procedure TimerDrawTimer(Sender: TObject);
50 procedure EraseBackground(DC: HDC); override;
51 private
52 DrawDuration: TDateTime;
53 MouseStart: TPoint;
54 MouseDown: Boolean;
55 RedrawPending: Boolean;
56 MoveBuffer: array of TMoveDirection;
57 MoveBufferLock: TCriticalSection;
58 procedure AddToMoveBuffer(Direction: TMoveDirection);
59 procedure ProcessMoveBuffer;
60 public
61 MoveThread: TMoveThread;
62 procedure Redraw;
63 procedure UpdateInterface;
64 end;
65
66var
67 FormMain: TFormMain;
68
69implementation
70
71{$R *.lfm}
72
73uses
74 UCore;
75
76{ TMoveThread }
77
78procedure TMoveThread.Execute;
79begin
80 while not Terminated do begin
81 FormMain.ProcessMoveBuffer;
82 Sleep(10);
83 end;
84end;
85
86{ TFormMain }
87
88procedure TFormMain.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
89begin
90 if Core.Game.Running then begin
91 case Key of
92 37: AddToMoveBuffer(drLeft);
93 38: AddToMoveBuffer(drUp);
94 39: AddToMoveBuffer(drRight);
95 40: AddToMoveBuffer(drDown);
96 end;
97 //ProcessMoveBuffer;
98 end;
99end;
100
101procedure TFormMain.FormMouseDown(Sender: TObject; Button: TMouseButton;
102 Shift: TShiftState; X, Y: Integer);
103begin
104 MouseStart := Point(X, Y);
105 MouseDown := True;
106end;
107
108function AngleOfLine(const P1, P2: TPoint): Double;
109begin
110 if P2.X = P1.X then
111 if P2.Y > P1.Y then
112 Result := 90
113 else
114 Result := 270
115 else
116 Result := RadToDeg(ArcTan2(P2.Y - P1.Y, P2.X - P1.X));
117 if Result < 0 then
118 Result := Result + 360;
119end;
120
121procedure TFormMain.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
122 Y: Integer);
123var
124 D: Real;
125 Angle: Real;
126begin
127 if MouseDown then begin;
128 D := MouseStart.Distance(Point(X, Y));
129 if D > ScaleX(100, 96) then begin
130 MouseDown := False;
131 Angle := AngleOfLine(MouseStart, Point(X, Y));
132 if (Angle > 315) or (Angle <= 45) then AddToMoveBuffer(drRight)
133 else if (Angle > 45) and (Angle <= 135) then AddToMoveBuffer(drDown)
134 else if (Angle > 135) and (Angle <= 225) then AddToMoveBuffer(drLeft)
135 else if (Angle > 225) and (Angle <= 315) then AddToMoveBuffer(drUp);
136 //ProcessMoveBuffer;
137 end;
138 end;
139end;
140
141procedure TFormMain.FormMouseUp(Sender: TObject; Button: TMouseButton;
142 Shift: TShiftState; X, Y: Integer);
143begin
144 MouseDown := False;
145end;
146
147procedure TFormMain.FormPaint(Sender: TObject);
148var
149 TimeStart: TDateTime;
150begin
151 {$IFDEF DEBUG}
152 TimeStart := Now;
153 {$ENDIF}
154 Core.Game.Render(Canvas, Point(Width, Height - MainMenu1.Height));
155 {$IFDEF DEBUG}
156 DrawDuration := Now - TimeStart;
157 {$ENDIF}
158end;
159
160procedure TFormMain.FormClose(Sender: TObject; var CloseAction: TCloseAction);
161begin
162 Core.PersistentForm1.Save(Self);
163end;
164
165procedure TFormMain.FormCreate(Sender: TObject);
166begin
167 Core.Translator1.TranslateComponentRecursive(Self);
168 MoveBufferLock := TCriticalSection.Create;
169 MoveThread := TMoveThread.Create(True);
170 MoveThread.FormMain := Self;
171 MoveThread.FreeOnTerminate := False;
172 MoveThread.Start;
173 ControlStyle := ControlStyle + [csOpaque];
174end;
175
176procedure TFormMain.FormDestroy(Sender: TObject);
177begin
178 FreeAndNil(MoveThread);
179 FreeAndNil(MoveBufferLock);
180end;
181
182procedure TFormMain.FormShow(Sender: TObject);
183begin
184 Core.PersistentForm1.RegistryContext := Core.ApplicationInfo1.GetRegistryContext;
185 Core.PersistentForm1.Load(Self);
186 Core.ThemeManager1.UseTheme(Self);
187 UpdateInterface;
188 if Core.Game.Board.GetEmptyTilesCount > Core.Game.Board.Size.X * Core.Game.Board.Size.Y -
189 InitialTileCount then
190 Core.Game.New;
191end;
192
193procedure TFormMain.TimerDrawTimer(Sender: TObject);
194begin
195 if RedrawPending then begin
196 RedrawPending := False;
197 Repaint;
198{$IFDEF DEBUG}
199 //Caption := FloatToStr(Round(DrawDuration / OneMillisecond));
200{$ENDIF}
201 end;
202end;
203
204procedure TFormMain.EraseBackground(DC: HDC);
205begin
206 // Do nothing
207end;
208
209procedure TFormMain.AddToMoveBuffer(Direction: TMoveDirection);
210begin
211 MoveBufferLock.Acquire;
212 try
213 SetLength(MoveBuffer, Length(MoveBuffer) + 1);
214 MoveBuffer[Length(MoveBuffer) - 1] := Direction;
215 finally
216 MoveBufferLock.Release;
217 end;
218end;
219
220procedure TFormMain.ProcessMoveBuffer;
221begin
222 if not Core.Game.Moving then begin
223 MoveBufferLock.Acquire;
224 while Length(MoveBuffer) > 0 do begin
225 MoveBufferLock.Release;
226 Core.Game.MoveAllAndUpdate(MoveBuffer[0], Core.Game.AnimationDuration > 0);
227 MoveBufferLock.Acquire;
228 if Length(MoveBuffer) > 1 then
229 Move(MoveBuffer[1], MoveBuffer[0], (Length(MoveBuffer) - 1) * SizeOf(TMoveDirection));
230 if Length(MoveBuffer) > 0 then
231 SetLength(MoveBuffer, Length(MoveBuffer) - 1);
232 end;
233 MoveBufferLock.Release;
234 end;
235end;
236
237procedure TFormMain.Redraw;
238begin
239 RedrawPending := True;
240end;
241
242procedure TFormMain.UpdateInterface;
243var
244 I: Integer;
245 ToolsVisible: Boolean;
246begin
247 MenuItemMovesHistory.Visible := Core.Game.RecordHistory;
248 ToolsVisible := False;
249 for I := 0 to MenuItemTools.Count - 1 do
250 if MenuItemTools.Items[I].Visible then begin
251 ToolsVisible := True;
252 Break;
253 end;
254 MenuItemTools.Visible := ToolsVisible;
255end;
256
257end.
258
Note: See TracBrowser for help on using the repository browser.