Delphi - 如何在代码的其他部分运行时请求用户输入

问题描述 投票:0回答:2

我正在尝试制作的游戏是蛇,在控制台应用程序中。我可以让蛇沿着屏幕移动但是我不知道如何读取用户输入密钥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;

我也知道睡眠是非常低效的,所以如果有人有更好的方法来推迟蛇的运动,也会受到欢迎。用于增加蛇长度的编码还没有实现。

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

delphi
2个回答
2
投票

在Delphi的古老前身Turbo Pascal的时代,有一个CRT单元为控制台应用程序提供了一些有用的功能。键盘输入你感兴趣的两个这样的函数是KeyPressed(),如果按下了一个键则返回true,按下返回键的GetKey()。对于Delphi本身,有一些库提供兼容的功能。一个是鲁迪的Velthuis.Console unit


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.
© www.soinside.com 2019 - 2024. All rights reserved.