我在delphi程序中有一个3d对象,我正在尝试使用箭头键控制他在3d空间中的移动。
第一个问题:对于单箭头键,运动正常 - 对象根据按下的键转动或向前移动,但它似乎不适用于多次按键。如果按下向上键和向左或向右键,它会旋转但不会前进。
第二个问题: UP键移动以某种方式延迟。按下UP键仅0.5秒后,对象开始向前移动。那是为什么?
以下是代码:
function KeyPressed(nKey: Integer): Boolean;
begin
Result := (GetAsyncKeyState(nKey) and $8000) <> 0;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if keypressed(VK_LEFT) then
if heroMove.angle < 360 then inc(heroMove.angle,5) else heroMove.angle:=0
else if keypressed(VK_RIGHT) then
if heroMove.angle < 360 then inc(heroMove.angle,-5) else heroMove.angle:=0 else
if keypressed(VK_UP) then
begin
heroMove.x:=heroMove.x+0.2*Sin(heroMove.angle*3.1415/180);
heroMove.y:=heroMove.y+0.2*Cos(heroMove.angle*3.1415/180);
pose:=1;
end;
if keypressed(VK_LEFT) and keypressed(VK_UP) then
begin
if heroMove.angle < 360 then inc(heroMove.angle,5) else heroMove.angle:=0;
heroMove.x:=heroMove.x+0.2*Sin(heroMove.angle*3.1415/180);
heroMove.y:=heroMove.y+0.2*Cos(heroMove.angle*3.1415/180);
pose:=1;
end else
if keypressed(VK_RIGHT) and keypressed(VK_UP) then
begin
if heroMove.angle < 360 then inc(heroMove.angle,-5) else heroMove.angle:=0;
heroMove.x:=heroMove.x+0.2*Sin(heroMove.angle*3.1415/180);
heroMove.y:=heroMove.y+0.2*Cos(heroMove.angle*3.1415/180);
pose:=1;
end;
end;
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if Key=VK_UP then
pose:=0;
end;
P.S。参数&#34; pose&#34;只控制对象的动画类型。
答案 0 :(得分:4)
这里需要的是停止使用事件驱动的编程方法。您需要切换到更传统的游戏编程风格。
您希望运行一个游戏循环,为您的程序提供稳定的脉冲。在此循环的每次迭代中,您都会检查键盘状态。请使用GetAsyncKeyState
。检查您感兴趣的每个键的状态。在游戏循环中,您还将驱动OpenGL画布的任何更新。
我可以从您的更新中看到您已在使用GetAsyncKeyState
。但是,当用于响应OnKeyDown
事件时,这确实没有多大意义。您可以使用事件驱动的同步I / O,也可以轮询异步I / O.我无法理解你为什么试图混合这两种范式。
您拨打GetAsyncKeyState
的方式看起来不对。你应该这样写:
function KeyPressed(nKey: Integer): Boolean;
begin
Result := GetAsyncKeyState(nKey) < 0;
end;
我还建议在主循环的每次迭代中,只为每个键调用GetAsyncKeyState
一次和一次。将返回的值保存到局部变量。这避免了在迭代开始时密钥被认为是关闭的情况,但是在迭代的某个稍后点处相同的密钥。这是一个需要与异步I / O保持一致的问题。