Rakete1111
Rakete1111

Reputation: 49008

Remove delay when continuously pressing a key

I want to move an image when I press a button, Up, but there is a slight delay:

Assuming I continuously hold down Up, the image moves up, stops for ~1s, and then goes up continuously.

I want to remove that 1s delay. I read that I can use GetAsyncKeyState, but because I'm on Linux this win32 function is not available. Also, a cross platform solution is better.

This is currently my code:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if Key = VK_LEFT then
      Image1.Left := Image1.Left - 1
  else if Key = VK_RIGHT then
      Image1.Left := Image1.Left + 1;
end;

So, how can I solve this problem?

Upvotes: 0

Views: 295

Answers (3)

Rakete1111
Rakete1111

Reputation: 49008

You can use get GetKeyState function included in LCLIntf. It calls the Win32 API function GetKeyState on Windows, and there is a custom implementation on other platforms. And so it is cross-platform.

procedure TForm1.checkKeyboard();
begin
    // When a key is down, the return value of GetKeyState has the high bit set,
    // making the result negative.
    if GetKeyState(VK_LEFT) < 0 then
        moveLeft(); // whatever
    //...
end;

Upvotes: 1

Vuio
Vuio

Reputation: 140

You need add Repaint to your code to refresh new location of image.

Upvotes: 0

srcstorm
srcstorm

Reputation: 11

You can start an independent movement on first key down event. Instead of relying on subsequent key down events, just continue to move the image until key up event is fired.

You've already found some solution, but this also works:

type
  TMovement = (movNone, movLeft, movRight);

var
  movement: TMovement = movNone;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if movement <> movNone then
    exit;

  case Key of
    VK_LEFT: MoveLeft;
    VK_RIGHT: MoveRight;
  else
    movement := movNone;
  end;
end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  movement := movNone;
end;

procedure TForm1.MoveLeft;
begin
  movement := movLeft;
  repeat
    if Image1.Left > 0 then
      Image1.Left := Image1.Left - 1;
    sleep(1);
    Application.ProcessMessages;
  until movement <> movLeft;
end;

Upvotes: 1

Related Questions