- Timestamp:
- Sep 26, 2019, 11:29:03 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UGame.pas
r6 r9 6 6 7 7 uses 8 Classes, SysUtils, Dialogs, fgl, Graphics, Types ;8 Classes, SysUtils, Dialogs, fgl, Graphics, Types, Forms, Math; 9 9 10 10 type … … 14 14 TCell = class 15 15 Value: Integer; 16 NewValue: Integer; 16 17 Merged: Boolean; 18 Moving: Boolean; 19 Shift: TPoint; 17 20 procedure Assign(Source: TCell); 18 21 end; … … 204 207 ValueStr: string; 205 208 Frame: TRect; 209 CellRect: TRect; 206 210 TextSize: TSize; 207 211 TopBarHeight: Integer; 212 CellMargin: Integer; 208 213 begin 209 214 TopBarHeight := ScaleY(24, 96); 215 CellMargin := ScaleX(4, 96); 210 216 Canvas.Brush.Style := bsSolid; 211 217 Canvas.Brush.Color := clBlack; … … 228 234 Frame.Top + Frame.Height div 2 + (Size.Y * CellSize.Y) div 2); 229 235 236 { for Y := 0 to Size.Y - 1 do begin 237 Canvas.MoveTo(Frame.Left, Frame.Top + Y * CellSize.Y); 238 Canvas.LineTo(Frame.Left + Size.X * CellSize.X, Frame.Top + Y * CellSize.Y); 239 end; 240 for X := 0 to Size.X - 1 do begin 241 Canvas.MoveTo(Frame.Left + X * CellSize.X, Frame.Top); 242 Canvas.LineTo(Frame.Left + X * CellSize.X, Frame.Top + Size.Y * CellSize.Y); 243 end; 244 } 245 Canvas.Brush.Style := bsSolid; 246 Canvas.Brush.Color := clGray; 247 Canvas.FillRect(Frame); 248 230 249 Canvas.Font.Color := clBlack; 250 // Draw static cells 231 251 for Y := 0 to Size.Y - 1 do 232 252 for X := 0 to Size.X - 1 do begin 233 Canvas.Brush.Color := GetCellColor(Cells[Y, X].Value); 253 if Cells[Y, X].Moving then Canvas.Brush.Color := GetCellColor(0) 254 else Canvas.Brush.Color := GetCellColor(Cells[Y, X].Value); 234 255 Canvas.Brush.Style := bsSolid; 235 Canvas.FillRect(Rect(Frame.Left + X * CellSize.X, Frame.Top + Y * CellSize.Y, 236 Frame.Left + (X + 1) * CellSize.X, Frame.Top + (Y + 1) * CellSize.Y)); 237 if Cells[Y, X].Value <> 0 then begin 256 CellRect := Bounds( 257 Frame.Left + X * CellSize.X + CellMargin, 258 Frame.Top + Y * CellSize.Y + CellMargin, 259 CellSize.X - 2 * CellMargin, CellSize.Y - 2 * CellMargin); 260 Canvas.FillRect(CellRect); 261 if (Cells[Y, X].Value <> 0) and not Cells[Y, X].Moving then begin 238 262 ValueStr := IntToStr(Cells[Y, X].Value); 239 263 Canvas.Brush.Style := bsClear; … … 243 267 Canvas.Font.Height := Trunc(Canvas.Font.Height / TextSize.Width * CellSize.X); 244 268 TextSize := Canvas.TextExtent(ValueStr); 245 Canvas.TextOut( Frame.Left + X * CellSize.X+ CellSize.X div 2 -269 Canvas.TextOut(CellRect.Left + CellSize.X div 2 - 246 270 TextSize.Width div 2, 247 Frame.Top + Y * CellSize.Y+ CellSize.Y div 2 - TextSize.Height div 2, ValueStr);271 CellRect.Top + CellSize.Y div 2 - TextSize.Height div 2, ValueStr); 248 272 end; 249 273 end; 250 274 251 for Y := 0 to Size.Y - 1 do begin 252 Canvas.MoveTo(Frame.Left, Frame.Top + Y * CellSize.Y); 253 Canvas.LineTo(Frame.Left + Size.X * CellSize.X, Frame.Top + Y * CellSize.Y); 254 end; 255 for X := 0 to Size.X - 1 do begin 256 Canvas.MoveTo(Frame.Left + X * CellSize.X, Frame.Top); 257 Canvas.LineTo(Frame.Left + X * CellSize.X, Frame.Top + Size.Y * CellSize.Y); 258 end; 259 Canvas.Brush.Style := bsClear; 260 Canvas.Rectangle(Frame); 275 // Draw moving cells 276 for Y := 0 to Size.Y - 1 do 277 for X := 0 to Size.X - 1 do 278 if Cells[Y, X].Moving then begin 279 Canvas.Brush.Color := GetCellColor(Cells[Y, X].Value); 280 Canvas.Brush.Style := bsSolid; 281 CellRect := Bounds( 282 Frame.Left + X * CellSize.X + Trunc(Cells[Y, X].Shift.X / 100 * CellSize.X + CellMargin), 283 Frame.Top + Y * CellSize.Y + Trunc(Cells[Y, X].Shift.Y / 100 * CellSize.Y + CellMargin), 284 CellSize.X - 2 * CellMargin, CellSize.Y - 2 * CellMargin); 285 Canvas.FillRect(CellRect); 286 if Cells[Y, X].Value <> 0 then begin 287 ValueStr := IntToStr(Cells[Y, X].Value); 288 Canvas.Brush.Style := bsClear; 289 Canvas.Font.Height := Trunc(CellSize.Y * 0.7); // * (CellSize.X * 0.7) / Canvas.TextWidth(ValueStr)); 290 TextSize := Canvas.TextExtent(ValueStr); 291 if TextSize.Width > CellRect.Width then 292 Canvas.Font.Height := Trunc(Canvas.Font.Height / TextSize.Width * CellSize.X); 293 TextSize := Canvas.TextExtent(ValueStr); 294 Canvas.TextOut(CellRect.Left + CellRect.Width div 2 - 295 TextSize.Width div 2, 296 CellRect.Top + CellRect.Height div 2 - TextSize.Height div 2, ValueStr); 297 end; 298 end; 261 299 end; 262 300 … … 266 304 AreaSize: TPoint; 267 305 Increment: TPoint; 306 MoveDirection: TPoint; 268 307 P: TPoint; 269 PN : TPoint;308 PNew: TPoint; 270 309 PI: TPoint; 271 310 MovedCount: Integer; 311 X, Y: Integer; 312 Step: Integer; 313 I: Integer; 314 const 315 StepCount = 10; 316 AnimationDuration = 30; 272 317 begin 273 318 //Diff := DirectionDiff[Direction]; … … 277 322 AreaSize := Point(Size.X - 2, Size.Y - 1); 278 323 Increment := Point(1, 1); 324 MoveDirection := Point(-1, 0); 279 325 end; 280 326 drUp: begin … … 282 328 AreaSize := Point(Size.X - 1, Size.Y - 2); 283 329 Increment := Point(1, 1); 330 MoveDirection := Point(0, -1); 284 331 end; 285 332 drRight: begin … … 287 334 AreaSize := Point(Size.X - 2, Size.Y - 1); 288 335 Increment := Point(-1, 1); 336 MoveDirection := Point(1, 0); 289 337 end; 290 338 drDown: begin … … 292 340 AreaSize := Point(Size.X - 1, Size.Y - 2); 293 341 Increment := Point(1, -1); 294 end; 295 end; 342 MoveDirection := Point(0, 1); 343 end; 344 end; 345 MovedCount := 0; 296 346 ClearMerged; 297 MovedCount := 0; 298 PI.Y := 0; 299 while PI.Y <= AreaSize.Y do begin 300 PI.X := 0; 301 while PI.X <= AreaSize.X do begin 302 P := Point(StartPoint.X + PI.X * Increment.X, StartPoint.Y + PI.Y * Increment.Y); 303 PN.X := P.X + DirectionDiff[Direction].X; 304 PN.Y := P.Y + DirectionDiff[Direction].Y; 305 while IsValidPos(PN) do begin 306 if (Cells[P.Y, P.X].Value <> 0) then begin 307 if (Cells[PN.Y, PN.X].Value = 0) then begin 308 MoveCell(Cells[P.Y, P.X], Cells[PN.Y, PN.X]); 309 Inc(MovedCount); 310 end else 311 if (not Cells[P.Y, P.X].Merged) and (not Cells[PN.Y, PN.X].Merged) and 312 (Cells[PN.Y, PN.X].Value = Cells[P.Y, P.X].Value) then begin 313 Cells[PN.Y, PN.X].Value := Cells[PN.Y, PN.X].Value + Cells[P.Y, P.X].Value; 314 Cells[PN.Y, PN.X].Merged := True; 315 Cells[P.Y, P.X].Value := 0; 316 Cells[P.Y, P.X].Merged := False; 317 Inc(MovedCount); 347 for I := 0 to Max(Size.X, Size.Y) - 1 do begin 348 PI.Y := 0; 349 for Y := 0 to Size.Y - 1 do 350 for X := 0 to Size.X - 1 do begin 351 Cells[Y, X].NewValue := Cells[Y, X].Value; 352 Cells[Y, X].Moving := False; 353 end; 354 355 while PI.Y <= AreaSize.Y do begin 356 PI.X := 0; 357 while PI.X <= AreaSize.X do begin 358 P := Point(StartPoint.X + PI.X * Increment.X, StartPoint.Y + PI.Y * Increment.Y); 359 PNew.X := P.X + DirectionDiff[Direction].X; 360 PNew.Y := P.Y + DirectionDiff[Direction].Y; 361 if IsValidPos(PNew) then begin 362 if (Cells[P.Y, P.X].NewValue <> 0) then begin 363 if (Cells[PNew.Y, PNew.X].NewValue = 0) then begin 364 Cells[P.Y, P.X].Moving := True; 365 Cells[PNew.Y, PNew.X].NewValue := Cells[P.Y, P.X].NewValue; 366 Cells[PNew.Y, PNew.X].Merged := Cells[P.Y, P.X].Merged; 367 Cells[P.Y, P.X].NewValue := 0; 368 Cells[P.Y, P.X].Merged := False; 369 Inc(MovedCount); 370 end else 371 if (not Cells[P.Y, P.X].Merged) and (not Cells[PNew.Y, PNew.X].Merged) and 372 (Cells[PNew.Y, PNew.X].NewValue = Cells[P.Y, P.X].NewValue) then begin 373 Cells[P.Y, P.X].Moving := True; 374 Cells[PNew.Y, PNew.X].NewValue := Cells[PNew.Y, PNew.X].NewValue + Cells[P.Y, P.X].NewValue; 375 Cells[PNew.Y, PNew.X].Merged := True; 376 Cells[P.Y, P.X].NewValue := 0; 377 Cells[P.Y, P.X].Merged := False; 378 Inc(MovedCount); 379 end; 318 380 end; 381 P.X := PNew.X; 382 P.Y := PNew.Y; 383 PNew.X := P.X + DirectionDiff[Direction].X; 384 PNew.Y := P.Y + DirectionDiff[Direction].Y; 319 385 end; 320 P.X := PN.X; 321 P.Y := PN.Y; 322 PN.X := P.X + DirectionDiff[Direction].X; 323 PN.Y := P.Y + DirectionDiff[Direction].Y; 386 Inc(PI.X); 324 387 end; 325 Inc(PI.X); 326 end; 327 Inc(PI.Y); 328 end; 329 DoChange; 388 Inc(PI.Y); 389 end; 390 for Step := 0 to StepCount - 2 do begin 391 for Y := 0 to Size.Y - 1 do 392 for X := 0 to Size.X - 1 do begin 393 if Cells[Y, X].Moving then 394 Cells[Y, X].Shift := Point(Trunc(Step / StepCount * MoveDirection.X * 100), 395 Trunc(Step / StepCount * MoveDirection.Y * 100)); 396 end; 397 DoChange; 398 Application.ProcessMessages; 399 Sleep(AnimationDuration div StepCount); 400 end; 401 for Y := 0 to Size.Y - 1 do 402 for X := 0 to Size.X - 1 do begin 403 Cells[Y, X].Value := Cells[Y, X].NewValue; 404 Cells[Y, X].Shift := Point(0, 0); 405 end; 406 DoChange; 407 end; 330 408 Result := MovedCount; 331 409 end;
Note:
See TracChangeset
for help on using the changeset viewer.