Guest User

Neko / Kat implemented using Free Pascal and Lazarus IDE (d-_-b 2024)

a guest
Oct 31st, 2024
291
-1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 5.01 KB | Gaming | 0 1
  1. // Neko / Kat implemented using Free Pascal and Lazarus IDE (d-_-b 2024)
  2. // https://forum.lazarus.freepascal.org/index.php/topic,34038.msg222021.html
  3. unit Unit1;
  4.  
  5. {$mode objfpc}{$H+}
  6.  
  7. interface
  8.  
  9. uses
  10.   Windows, Classes, SysUtils, Forms, Controls, Graphics, ExtCtrls, BGRABitmap, Dialogs ;
  11.  
  12. type
  13.  
  14.   { TForm1 }
  15.  
  16.   TForm1 = class(TForm)
  17.     Timer1: TTimer;
  18.     procedure FormCreate(Sender: TObject);
  19.     procedure Timer1Timer(Sender: TObject);
  20.   private
  21.     bfBlend: TBlendFunction;
  22.     pPos: TPoint;
  23.     sSize: TSize;
  24.     dwStyle: DWORD;
  25.     DeltaTime: Integer;
  26.     Frame: Integer;
  27.     procedure DrawImage(StateKey: String);
  28.     procedure UpdatePosition(MouseX, MouseY: Integer; aFrame: Integer);
  29.   public
  30.   end;
  31.  
  32. var
  33.   Form1: TForm1;
  34.  
  35. const
  36.   CatStates: array [0..40] of String = (
  37.     'awake', 'down1.png', 'down2.png', 'downclaw1.png', 'downclaw2.png',
  38.     'downleft1.png', 'downleft2.png', 'downright1.png', 'downright2.png',
  39.     'fp_down.png', 'fp_downleft.png', 'fp_downright.png', 'fp_left.png',
  40.     'fp_right.png', 'fp_up.png', 'fp_upleft.png', 'fp_upright.png', 'left1.png',
  41.     'left2.png', 'leftclaw1.png', 'leftclaw2.png', 'right1.png', 'right2.png',
  42.     'rightclaw1.png', 'rightclaw2.png', 'scratch1.png', 'scratch2.png',
  43.     'sleep1.png', 'sleep2.png', 'up1.png', 'up2.png', 'upclaw1.png', 'upclaw2.png',
  44.     'upleft1.png', 'upleft2.png', 'upright1.png', 'upright2.png', 'wash1.png',
  45.     'wash2.png', 'yawn1.png', 'yawn2.png'
  46.   );
  47.  
  48.   function UpdateLayeredWindow (hwnd   : HWND;
  49.                                 hdcDst : HDC;
  50.                                 pptDst : PPoint;
  51.                                 psize  : PSize;
  52.                                 hdcSrc : HDC;
  53.                                 pptSrc : PPoint;
  54.                                 crKey  : TColor;
  55.                                 pblend : PBlendFunction;
  56.                                 dwFlags: DWORD): BOOL; StdCall; External 'user32';
  57.  
  58. Implementation
  59.  {$R *.lfm}
  60.  
  61. procedure TForm1.FormCreate(Sender: TObject);
  62.  Begin
  63.   FormStyle  := fsStayOnTop;
  64.   Borderstyle:= bsNone;
  65.   dwStyle:= GetWindowLongA(Self.Handle, GWL_EXSTYLE);
  66.   if (dwStyle And WS_EX_LAYERED = 0) then
  67.   begin
  68.     SetWindowLong(Self.Handle, GWL_EXSTYLE, dwStyle Or
  69.                                    WS_EX_LAYERED Or
  70.                                    WS_EX_TOPMOST);
  71.   end;
  72.   Frame := 1;
  73.   DrawImage('awake');
  74.  End;
  75.  
  76. procedure TForm1.Timer1Timer(Sender: TObject);
  77. const
  78.   AnimationSpeed = 200;
  79. var
  80.   MousePos: TPoint;
  81. begin
  82.   // Increment the delta time
  83.   Inc(DeltaTime, Timer1.Interval);
  84.   // Check if x ms has been reached or exceeded
  85.   if DeltaTime >= AnimationSpeed then
  86.   begin
  87.     // Toggle the frame between 1 and 2
  88.     Frame := (Frame mod 2) + 1;
  89.     // Reset the delta time
  90.     DeltaTime := 0;
  91.   end;
  92.   // Get the current mouse position
  93.   GetCursorPos(MousePos);
  94.   // Update the form position and image
  95.   UpdatePosition(MousePos.X, MousePos.Y, Frame);
  96. end;
  97.  
  98. procedure TForm1.DrawImage(StateKey: String);
  99. var
  100.   PNG: TBGRABitmap;
  101.   ImagePath: String;
  102. begin
  103.   // Construct the file path
  104.   ImagePath := 'assets\' + StateKey + '.png';
  105.   // Check if the file exists
  106.   if not FileExists(ImagePath) then
  107.   begin
  108.     ShowMessage('Image file "' + ImagePath + '" not found.');
  109.     Exit;
  110.   end;
  111.   // Load and Draw
  112.   PNG:= TBGRABitmap.Create;
  113.   try
  114.     // must be a premultiplied PNG
  115.     PNG.LoadFromFile(ImagePath);
  116.     // Setup Pos and Size
  117.     pPos    := Point(0, 0);
  118.     sSize.cx:= PNG.Width;
  119.     sSize.cy:= PNG.Height;
  120.     // Alpha Blending
  121.     bfBlend.BlendOp            := AC_SRC_OVER;
  122.     bfBlend.BlendFlags         := 0;
  123.     bfBlend.SourceConstantAlpha:= 255;
  124.     bfBlend.AlphaFormat        := AC_SRC_ALPHA;
  125.     // Handle Window Blit
  126.     UpdateLayeredWindow(Self.Handle, 0, Nil, @sSize,
  127.                       PNG.Bitmap.Canvas.Handle,
  128.                       @pPos, 0, @bfBlend, ULW_ALPHA);
  129.   finally
  130.     PNG.Free;
  131.   end;
  132. end;
  133.  
  134. procedure TForm1.UpdatePosition(MouseX, MouseY: Integer; aFrame: Integer);
  135. const
  136.   DistanceThreshold = 32;
  137.   Speed = 5;
  138. var
  139.   DeltaX, DeltaY: Integer;
  140.   Distance: Double;
  141.   LeftOrRight, DownOrUp: String;
  142. begin
  143.   DeltaX := MouseX - (Left + Width div 2);
  144.   DeltaY := MouseY - (Top + Height div 2);
  145.   // Calculate the Euclidean distance safely
  146.   Distance := Sqrt(Sqr(DeltaX) + Sqr(DeltaY));
  147.   if (Distance > DistanceThreshold) and (Distance <> 0) then
  148.   begin
  149.     // Determine horizontal direction
  150.     if DeltaX > 0 then
  151.       LeftOrRight := 'right'
  152.     else if DeltaX < 0 then
  153.       LeftOrRight := 'left'
  154.     else
  155.       LeftOrRight := '';
  156.     // Determine vertical direction
  157.     if DeltaY > 0 then
  158.       DownOrUp := 'down'
  159.     else if DeltaY < 0 then
  160.       DownOrUp := 'up'
  161.     else
  162.       DownOrUp := '';
  163.     // Update the position
  164.     Left := Left + Round(DeltaX / Distance * Speed);
  165.     Top := Top + Round(DeltaY / Distance * Speed);
  166.     // Draw Animation
  167.     DrawImage(DownOrUp + LeftOrRight + IntToStr(aFrame));
  168.   end else
  169.   begin
  170.      DrawImage('awake');
  171.   end;
  172. end;
  173.  
  174. end.
  175.  
Advertisement
Add Comment
Please, Sign In to add comment