消除连续按键时的延迟

Remove delay when continuously pressing a key

我想在按下按钮时移动图像,向上,但有一点延迟:

假设我连续按住Up,图像向上移动,停止~1s,然后连续向上。

我想去掉那个 1s 的延迟。我读到我可以使用 GetAsyncKeyState,但是因为我在 Linux 上,这个 win32 功能不可用。另外,跨平台解决方案更好。

这是我目前的代码:

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;

那么,我该如何解决这个问题呢?

您可以使用 LCLIntf 中包含的 get GetKeyState 函数。它在 Windows 上调用 Win32 API 函数 GetKeyState,并且在其他平台上有自定义实现。所以它是跨平台的。

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;

您可以在第一次按下事件时开始独立移动。不再依赖后续的按键按下事件,只需继续移动图像直到按键弹起事件被触发。

您已经找到了一些解决方案,但这也有效:

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;

您需要在您的代码中添加 Repaint 以刷新图像的新位置。