Changeset 55 for trunk/UGame.pas


Ignore:
Timestamp:
Nov 5, 2019, 12:47:08 AM (5 years ago)
Author:
chronos
Message:
  • Added: Animation of appearence of new tiles.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UGame.pas

    r53 r55  
    1212  TGame = class;
    1313  TMoveDirection = (drNone, drLeft, drUp, drRight, drDown);
     14  TTileAction = (taNone, taMove, taMerge, taAppear);
    1415
    1516  { TTile }
     
    2021    NewValue: Integer;
    2122    Merged: Boolean;
    22     Moving: Boolean;
     23    Action: TTileAction;
    2324    Shift: TPoint;
    2425    procedure Assign(Source: TTile);
     
    118119    procedure SetSkin(AValue: TTileSkin);
    119120    procedure Win;
    120     function FillRandomTile(Value4Change: Double = 0.1): TTile;
     121    function FillRandomTile: TTile;
    121122    function GetMoveArea(Direction: TMoveDirection): TArea;
    122123    procedure MoveAllAnimate(Direction: TMoveDirection);
    123124    function CanMergeTile(Value1, Value2: Integer): Boolean;
    124125    function MergeTile(Value1, Value2: Integer): Integer;
     126    procedure AnimateTiles;
    125127  public
    126128    Board: TBoard;
     
    131133    History: THistory;
    132134    BackgroundColor: TColor;
     135    Value2Chance: Double;
    133136    function CanUndo: Boolean;
    134137    procedure Undo;
     
    519522end;
    520523
    521 function TGame.FillRandomTile(Value4Change: Double = 0.1): TTile;
     524function TGame.FillRandomTile: TTile;
    522525var
    523526  EmptyTiles: TTiles;
     
    528531  Board.GetEmptyTiles(EmptyTiles);
    529532  if EmptyTiles.Count > 0 then begin
    530     if Random < Value4Change then NewValue := 2 else NewValue := 1;
     533    if Random < Value2Chance then NewValue := 2 else NewValue := 1;
    531534    Result := EmptyTiles[Random(EmptyTiles.Count)];
    532535    Result.Value := NewValue;
     536    Result.Action := taAppear;
    533537  end;
    534538  EmptyTiles.Free;
     
    579583    for I := 0 to InitialTileCount - 1 do begin
    580584      SetLength(History.InitialTiles, Length(History.InitialTiles) + 1);
    581       Tile := FillRandomTile(0);
     585      Tile := FillRandomTile;
    582586      History.InitialTiles[Length(History.InitialTiles) - 1].Pos := Tile.Index;
    583587      History.InitialTiles[Length(History.InitialTiles) - 1].Value := Tile.Value;
     
    585589  end else begin
    586590    for I := 0 to InitialTileCount - 1 do
    587       FillRandomTile(0);
    588   end;
     591      FillRandomTile;
     592  end;
     593  AnimateTiles;
    589594  DoChange;
    590595end;
     
    599604  TopBarHeight: Integer;
    600605  TileMargin: Integer;
     606  TileCenter: TPoint;
     607  S: TPoint;
    601608begin
    602609  TopBarHeight := ScaleY(24, 96);
     
    643650  for Y := 0 to Board.Size.Y - 1 do
    644651    for X := 0 to Board.Size.X - 1 do begin
    645       if Board.Tiles[Y, X].Moving then Canvas.Brush.Color := GetTileColor(0)
     652      if (Board.Tiles[Y, X].Action <> taNone) then Canvas.Brush.Color := GetTileColor(0)
    646653        else Canvas.Brush.Color := GetTileColor(Board.Tiles[Y, X].Value);
    647654      Canvas.Brush.Style := bsSolid;
     
    650657        Frame.Top + Y * TileSize.Y + TileMargin,
    651658        TileSize.X - 2 * TileMargin, TileSize.Y - 2 * TileMargin);
    652       RenderTile(Canvas, Board.Tiles[Y, X], TileRect, not Board.Tiles[Y, X].Moving);
    653     end;
    654 
    655   // Draw moving Tiles
     659      RenderTile(Canvas, Board.Tiles[Y, X], TileRect, Board.Tiles[Y, X].Action = taNone);
     660    end;
     661
     662  // Draw moving tiles
    656663  for Y := 0 to Board.Size.Y - 1 do
    657664    for X := 0 to Board.Size.X - 1 do
    658     if Board.Tiles[Y, X].Moving then begin
     665    if Board.Tiles[Y, X].Action = taMove then begin
    659666      Canvas.Brush.Color := GetTileColor(Board.Tiles[Y, X].Value);
    660667      Canvas.Brush.Style := bsSolid;
     
    663670        Frame.Top + Y * TileSize.Y + Trunc(Board.Tiles[Y, X].Shift.Y / 100 * TileSize.Y + TileMargin),
    664671        TileSize.X - 2 * TileMargin, TileSize.Y - 2 * TileMargin);
     672      RenderTile(Canvas, Board.Tiles[Y, X], TileRect, True);
     673    end;
     674
     675  // Draw moving tiles
     676  for Y := 0 to Board.Size.Y - 1 do
     677    for X := 0 to Board.Size.X - 1 do
     678    if Board.Tiles[Y, X].Action = taAppear then begin
     679      Canvas.Brush.Color := GetTileColor(Board.Tiles[Y, X].Value);
     680      Canvas.Brush.Style := bsSolid;
     681      TileRect := Bounds(
     682        Frame.Left + X * TileSize.X + TileMargin,
     683        Frame.Top + Y * TileSize.Y + TileMargin,
     684        TileSize.X - 2 * TileMargin,
     685        TileSize.Y - 2 * TileMargin);
     686      TileCenter := TileRect.CenterPoint;
     687      S := Point(
     688        Trunc(Board.Tiles[Y, X].Shift.X / 100 * (TileSize.X - TileMargin)),
     689        Trunc(Board.Tiles[Y, X].Shift.Y / 100 * (TileSize.Y - TileMargin))
     690      );
     691      TileRect := Rect(TileCenter.X - S.X div 2, TileCenter.Y - S.Y div 2,
     692        TileCenter.X + S.X div 2, TileCenter.Y + S.Y div 2);
    665693      RenderTile(Canvas, Board.Tiles[Y, X], TileRect, True);
    666694    end;
     
    694722          if (Board.Tiles[P.Y, P.X].Value <> 0) then begin
    695723            if (Board.Tiles[PNew.Y, PNew.X].Value = 0) then begin
    696               Board.Tiles[P.Y, P.X].Moving := True;
    697724              Board.Tiles[PNew.Y, PNew.X].Value := Board.Tiles[P.Y, P.X].Value;
    698725              Board.Tiles[PNew.Y, PNew.X].Merged := Board.Tiles[P.Y, P.X].Merged;
     
    702729            if (not Board.Tiles[P.Y, P.X].Merged) and (not Board.Tiles[PNew.Y, PNew.X].Merged) and
    703730            CanMergeTile(Board.Tiles[PNew.Y, PNew.X].Value, Board.Tiles[P.Y, P.X].Value) then begin
    704               Board.Tiles[P.Y, P.X].Moving := True;
    705731              Board.Tiles[PNew.Y, PNew.X].Value := MergeTile(Board.Tiles[PNew.Y, PNew.X].Value, Board.Tiles[P.Y, P.X].Value);
    706732              Board.Tiles[PNew.Y, PNew.X].Merged := True;
     
    846872      for X := 0 to Board.Size.X - 1 do begin
    847873        Board.Tiles[Y, X].NewValue := Board.Tiles[Y, X].Value;
    848         Board.Tiles[Y, X].Moving := False;
     874        Board.Tiles[Y, X].Action := taNone;
    849875      end;
    850876
     
    858884          if (Board.Tiles[P.Y, P.X].NewValue <> 0) then begin
    859885            if (Board.Tiles[PNew.Y, PNew.X].NewValue = 0) then begin
    860               Board.Tiles[P.Y, P.X].Moving := True;
     886              Board.Tiles[P.Y, P.X].Action := taMove;
    861887              Board.Tiles[PNew.Y, PNew.X].NewValue := Board.Tiles[P.Y, P.X].NewValue;
    862888              Board.Tiles[PNew.Y, PNew.X].Merged := Board.Tiles[P.Y, P.X].Merged;
     
    867893            if (not Board.Tiles[P.Y, P.X].Merged) and (not Board.Tiles[PNew.Y, PNew.X].Merged) and
    868894            CanMergeTile(Board.Tiles[PNew.Y, PNew.X].NewValue, Board.Tiles[P.Y, P.X].NewValue) then begin
    869               Board.Tiles[P.Y, P.X].Moving := True;
     895              Board.Tiles[P.Y, P.X].Action := taMove;
    870896              Board.Tiles[PNew.Y, PNew.X].NewValue := MergeTile(Board.Tiles[PNew.Y, PNew.X].NewValue, Board.Tiles[P.Y, P.X].NewValue);
    871897              Board.Tiles[PNew.Y, PNew.X].Merged := True;
     
    893919      for Y := 0 to Board.Size.Y - 1 do
    894920        for X := 0 to Board.Size.X - 1 do begin
    895           if Board.Tiles[Y, X].Moving then
     921          if Board.Tiles[Y, X].Action = taMove then
    896922            Board.Tiles[Y, X].Shift := Point(Trunc(Part * DirectionDiff[Direction].X * 100),
    897923              Trunc(Part * DirectionDiff[Direction].Y * 100));
     
    913939    for X := 0 to Board.Size.X - 1 do begin
    914940      Board.Tiles[Y, X].Shift := Point(0, 0);
    915       Board.Tiles[Y, X].Moving := False;
     941      Board.Tiles[Y, X].Action := taNone;
    916942      Board.Tiles[Y, X].Value := Board.Tiles[Y, X].NewValue;
    917943    end;
     
    929955  if Value1 = Value2 then Result := Value1 + 1
    930956  else Result := -1;
     957end;
     958
     959procedure TGame.AnimateTiles;
     960var
     961  I: Integer;
     962  StartTime: TDateTime;
     963  EndTime: TDateTime;
     964  Time: TDateTime;
     965  Part: Double;
     966  X, Y: Integer;
     967begin
     968  FMoving := True;
     969
     970  // Animate tiles move
     971  StartTime := Now;
     972  EndTime := StartTime + AnimationDuration / 300 * OneSecond / Max(Board.Size.X, Board.Size.Y);
     973  if AnimationDuration > 0 then
     974  repeat
     975    Time := Now;
     976    Part := (Time - StartTime) / (EndTime - StartTime);
     977    if Part > 1 then Part := 1;
     978    for Y := 0 to Board.Size.Y - 1 do
     979      for X := 0 to Board.Size.X - 1 do begin
     980        if Board.Tiles[Y, X].Action = taAppear then
     981          Board.Tiles[Y, X].Shift := Point(Trunc(Part * 100), Trunc(Part * 100));
     982      end;
     983    DoChange;
     984    Application.ProcessMessages;
     985    Sleep(1);
     986  until Time > EndTime;
     987
     988  for Y := 0 to Board.Size.Y - 1 do
     989    for X := 0 to Board.Size.X - 1 do
     990      if Board.Tiles[Y, X].Action = taAppear then begin
     991        Board.Tiles[Y, X].Action := taNone;
     992        Board.Tiles[Y, X].Shift := Point(0, 0);
     993      end;
     994  DoChange;
     995  FMoving := False;
    931996end;
    932997
     
    9621027
    9631028    NewTile := FillRandomTile;
     1029    if Animation then AnimateTiles;
     1030
    9641031    if RecordHistory then begin
    9651032      HistoryMove := THistoryMove.Create;
     
    10491116  History := THistory.Create;
    10501117  History.Game := Self;
     1118  Value2Chance := 0.1;
    10511119end;
    10521120
Note: See TracChangeset for help on using the changeset viewer.