Delphi-在其他代码段运行时,如何请求用户输入

时间:2018-09-10 10:30:34

标签: delphi

在控制台应用程序中,我要制作的游戏是蛇。我可以使蛇沿着屏幕移动,但是我不确定如何读取输入WASD键的用户,代码如下所示。

write (StoredTrail); //This would be writing the snake, each segment is '[]'
repeat
clearScreen; // This is calling a clear screen procedure, if there is a simple way to make the snake disappear from the console that avoids such a lengthy procedure that would be great to know.
delete (StoredTrail ,0,2); 
StoredTrail:= A+StoredTrail; //This makes the trail move along(A is '  ')
write(StoredTrail);
Xcord:= Xcord + 1;
sleep(150);
until 1=2;

我也知道睡眠效率很低,所以如果有人有更好的方法来延迟蛇的运动,那也将受到欢迎。尚未增加用于增加蛇的长度的编码。

非常感谢能够提供帮助的人。

2 个答案:

答案 0 :(得分:3)

我举一个事件驱动控制台应用程序的示例,该应用程序迭代更新屏幕。 在这里编写用户事件处理程序例程太长了,您可以在网上的很多地方找到它。 This是一个很好的例子,它也处理键盘和鼠标事件:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
    System.SysUtils
  , Vcl.ExtCtrls
  ;

type
  TSnakeApp = class
    private
      fTimer : TTimer;
      fExit : boolean;
    protected
      function createTimer : TTimer; virtual;
      procedure releaseTimer; virtual;
      procedure drawSnake( timer_ : TObject ); virtual;
      procedure handleKeyBoardEvents; virtual;

    public
      constructor create;
      destructor destroy; override;
      procedure run;
  end;

var
 app : TSnakeApp;

function TSnakeApp.createTimer : TTimer;
begin
  result := TTimer.Create( NIL );
end;

procedure TSnakeApp.releaseTimer;
begin
  fTimer.Free;
end;

procedure TSnakeApp.drawSnake( timer_ : TObject );
begin
  // if it takes too long time (>= times.interval), then disable+enable the timer
  fTimer.enabled := FALSE;
  try
  finally
    fTimer.enabled := TRUE;
  end;
end;

procedure TSnakeApp.handleKeyBoardEvents;
begin
  // It would be too long to write here, but you can find a very nice keyboard/mouse event handler for console applications here:
  // https://docs.microsoft.com/en-us/windows/console/reading-input-buffer-events
  //  case ( keyPressed ) of
  //    VK_ESC:
  //      fExit := TRUE;
  //  ...
end;

constructor TSnakeApp.create;
begin
  inherited create;
  fTimer := createTimer;
  fTimer.Interval := 20;
  fTimer.OnTimer := drawSnake;
end;

destructor TSnakeApp.destroy;
begin
  releaseTimer;
  inherited destroy;
end;

procedure TSnakeApp.run;
begin
  fTimer.enabled := TRUE;
  while ( not fExit ) do
  begin
    handleKeyBoardEvents;
  end;
  fTimer.enabled := FALSE;
end;

begin
  try
    try
      app := TSnakeApp.create;
      app.run;
    finally
      app.Free;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

答案 1 :(得分:2)

在Turbo Pascal时代(德尔福的前身)时代,有一个CRT单元为控制台应用程序提供了一些有用的功能。您可能会对键盘输入感兴趣的两个这样的功能是:KeyPressed()(如果已按下某个键,则返回true)和GetKey()(其返回已按下的键)。对于Delphi本身,有一些提供兼容功能的库资源。一个是鲁迪的Velthuis.Console unit