Pascal游戏开发入门(四):移动和用户输入

Pascal游戏开发入门(四):移动和用户输入

前言

目前已经可以在屏幕上渲染图片,并使用OOP的特性管理组织不同类的游戏对象
接下来需要添加用户控制功能.
常见的输入设备有: 鼠标 键盘 手柄

移动与向量

游戏的很多对象,即使没有用户输入,也要能移动。比如背景层,敌人等等。

为了处理移动的距离与方向,需要引入向量

使用向量修改TGameObject

  TGameObject = class
  ....
  public
    position: TVector2; // 位置
    velocity: TVector2; // 速度
    acceleration: TVector2; //加速度
  end;

然后修改Update函数

procedure TGameObject.Update();
begin
  velocity := velocity + acceleration;
  position := position + velocity;
end;

用户输入捕获与管理

新增一个TInputHandle类专门用于管理用户的各种输入

  TInputHandle = class
  public
    isQuit: boolean;
    destructor Destroy(); override;
    procedure Update;
    procedure Reset;
    function IsKeyDown(scancode: TSDL_Scancode): boolean;

  private
    keyState: PUInt8;
    procedure OnKeyEvent();

  end;

为了简单,目前只处理键盘事件

procedure TInputHandle.Update;
var
  e: TSDL_Event;
begin
  while SDL_PollEvent(@e) = 1 do
  begin
    case e.Type_ of
      SDL_QUITEV: isQuit := True;    
      SDL_KEYUP, SDL_KEYDOWN: onKeyEvent;
    end;
  end;

end;

procedure TInputHandle.onKeyEvent();
begin
  keyState := SDL_GetKeyboardState(nil);
  if isKeyDown(SDL_SCANCODE_ESCAPE) then
    isQuit := True;
end;

function TInputHandle.isKeyDown(scancode: TSDL_ScanCode): boolean;
begin
  if keyState <> nil then
    Result := keyState[scancode] > 0
  else
    Result := False;
end;

有了这些,我们就可以在每个TGameObject子类中使用不同的代码响应事件

procedure TPlayer.HandleInput;

var
  v: TVector2;
  f: integer;
begin
  v.x := 0;
  v.y := 0;
  f := 0;
  if TInputHandle.Instance().IsKeyDown(SDL_SCANCODE_RIGHT) then
    v.x := v.x + 1;
  if TInputHandle.Instance().IsKeyDown(SDL_SCANCODE_LEFT) then
    v.x := v.x - 1;

  if v.x >= 0 then
    f := SDL_FLIP_NONE
  else
    f := SDL_FLIP_HORIZONTAL;

  if v.isZero then
    angle := 0
  else
    angle := round(RadToDeg(arccos(abs(v.x) / v.length)));

  writelnlog('angle:%f', [angle]);
  flip := f;

  if samevalue(v.x, 0) then
    velocity.x := lerp(velocity.x, 0, acceleration.x *2)
  else
    velocity.x := lerp(velocity.x, v.x * speed, acceleration.x);

  writelnlog('player v:%s,velocity:%s', [v.toString, velocity.toString]);
end;

完整代码

你可能感兴趣的:(pascal,游戏,pascal,sdl)