我正在尝试制作的游戏是蛇,在控制台应用程序中。我可以让蛇沿着屏幕移动但是我不知道如何读取用户输入密钥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的古老前身Turbo Pascal的时代,有一个CRT单元为控制台应用程序提供了一些有用的功能。键盘输入你感兴趣的两个这样的函数是KeyPressed()
,如果按下了一个键则返回true,按下返回键的GetKey()
。对于Delphi本身,有一些库提供兼容的功能。一个是鲁迪的Velthuis.Console unit。
我举例说明了一个事件驱动的控制台应用程序,它迭代地更新了屏幕。在这里写这个用户事件处理程序例程太长了,你可以在网上很多地方找到它。 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.