消除连续按键时的延迟
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 以刷新图像的新位置。
我想在按下按钮时移动图像,向上,但有一点延迟:
假设我连续按住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 以刷新图像的新位置。