在Delphi和openGL中按下多个箭头键的对象移动

时间:2014-03-30 16:51:51

标签: delphi opengl 3d game-physics arrow-keys

我在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;只控制对象的动画类型。

1 个答案:

答案 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保持一致的问题。