Subversion Repositories AndroidProjects

Rev

Blame | Last modification | View Log | RSS feed

unit app_entity_paddle;

interface

uses sux_constant, sux_object, app_constant, app_entity_main,
     app_game_player;

type
  TPaddle=record
    belongtoplayer: SXInt;
    lastpos: SXFloat;
    inertia: SXFloat;
    timesincelastaction: SXFloat;
  end;
  SAEPaddle=class(SAEntity)
    paddle:TPaddle;

    procedure onRender; override;

    procedure connectToPlayer(const player: SXInt);
    function getPlayer:SAGPlayer;

    function getPaddleMaxSpeed:SXFloat;

    function getMovementSpeed:SXFloat;
    procedure clampPosToField;
    procedure movePaddle(const addy: SXFloat);
    procedure movePaddleByInertia;
    procedure onLocalInput;
    procedure processAI;
    procedure enterCurrentGame;
    procedure leaveCurrentGame;
    procedure onTimer; override;

    procedure initialize; override;
    constructor Create(parent:TObject);
    destructor Destroy; override;
  end;

implementation

uses main, app_entity_ball;


// --- SAEPaddle


procedure SAEPaddle.onRender;
begin
  if (app.game.settings.effects.concave > 0) then
  begin
    setFlipHorizontal(not (paddle.belongtoplayer = 2));
  end else setFlipHorizontal(paddle.belongtoplayer = 2);
 
  inherited;
end;




procedure SAEPaddle.connectToPlayer(const player: SXInt);
var addx:SXFloat;
begin
  paddle.belongtoplayer:=player;

  if (player=1) then addx:=-1 else addx:=1;
  settings.pos.x:=addx*240;
  settings.pos.y:=0;

  if (getPlayer.isCPUPlayer) then settings.pos.y:=sx.math.random.getRandomSign*4;

  if (player=2) then
  begin
    setFlipHorizontal(true);
  end;
end;


function SAEPaddle.getPlayer:SAGPlayer;
begin
  result:=app.game.getPlayer(paddle.belongtoplayer);
end;




function SAEPaddle.getPaddleMaxSpeed:SXFloat;
begin
  result:=app.ini.settings.gameplay.maxpaddlespeed;
end;




function SAEPaddle.getMovementSpeed:SXFloat;
var timer:SXFloat;
begin
  timer:=sx.timer.getTimer;
  result:=(settings.pos.y-paddle.lastpos)/timer;
end;


procedure SAEPaddle.clampPosToField;
begin
  if (settings.pos.y < -155) then paddle.inertia := 0;
  if (settings.pos.y > 155) then paddle.inertia := 0;
  sx.math.clampToRange(settings.pos.y,-155,155);
end;


procedure SAEPaddle.movePaddle(const addy: SXFloat);
begin
  if (app.game.settings.effects.slowmotion > 0) then
  begin
    sx.timer.incTimer(paddle.inertia, addy * app.ini.settings.gameplay.paddleinertiaincreasemultiplier);
    sx.math.clampToRange(paddle.inertia, -getPaddleMaxSpeed, getPaddleMaxSpeed);
  end else sx.timer.incTimer(settings.pos.y, addy);
end;


procedure SAEPaddle.movePaddleByInertia;
begin
  if (app.game.settings.effects.slowmotion <= 0) then exit;

  if (paddle.inertia > 0) then
  begin
    sx.timer.incTimer(settings.pos.y, paddle.inertia);
    sx.timer.decTimer(paddle.inertia, app.ini.settings.gameplay.paddleinertiadecrease);
    if (paddle.inertia < 0) then paddle.inertia := 0;
  end;
  if (paddle.inertia < 0) then
  begin
    sx.timer.incTimer(settings.pos.y, paddle.inertia);
    sx.timer.incTimer(paddle.inertia, app.ini.settings.gameplay.paddleinertiadecrease);
    if (paddle.inertia > 0) then paddle.inertia := 0;
  end;
end;


procedure SAEPaddle.onLocalInput;
var moveupdown:SXFloat;
    joyindex:SXInt;
begin
  moveupdown:=0;
  case paddle.belongtoplayer of
    1 : begin
          if (app.input.isPressed('Up','Player1')) then moveupdown := -1.0;
          if (app.input.isPressed('Down','Player1')) then moveupdown := 1.0;
          moveupdown := moveupdown * getPaddleMaxSpeed;

          joyindex := app.ini.settings.player1.joypad - 1;
          if (joyindex > SX_NONE) and (app.input.joysticks.maxjoystick >= joyindex) then
            moveupdown := moveupdown + app.input.getJoystick(joyindex).getMovementY * getPaddleMaxSpeed;
        end;
    2 : begin
          if (app.input.isPressed('Up','Player2')) then moveupdown := -1.0;
          if (app.input.isPressed('Down','Player2')) then moveupdown := 1.0;
          moveupdown := moveupdown * getPaddleMaxSpeed;

          joyindex := app.ini.settings.player2.joypad - 1;
          if (joyindex > SX_NONE) and (app.input.joysticks.maxjoystick >= joyindex) then
            moveupdown := moveupdown + app.input.getJoystick(joyindex).getMovementY * getPaddleMaxSpeed;
        end;
  end;

  if (moveupdown <> 0) then paddle.timesincelastaction := 0;
  sx.math.clampToRange(moveupdown, -getPaddleMaxSpeed, getPaddleMaxSpeed);
  movePaddle(moveupdown);

  sx.timer.incTimer(paddle.timesincelastaction);
  if (paddle.timesincelastaction > app.ini.settings.gameplay.playertimeoutduration) then leaveCurrentGame;
end;


procedure SAEPaddle.processAI;
var e:SXInt;
    entity:SAEntity;
    targety,speed:SXFloat;
begin
  targety:=-999;

  // Get the ball's y position and try to reach it.
  for e:=0 to app.game.entities.getMax do
  begin
    entity:=SAEntity(app.game.entities.getObject(e));
    if (entity is SAEBall) then targety:=entity.settings.pos.y;
  end;

  // If no ball is in the game the paddle resets to the center of the board.
  if (app.game.settings.state.state=SX_GAME_STATE_WAITFORBALL) then targety:=0;

  if (targety>-999) then
  begin
    speed:=abs(targety-settings.pos.y)*20;
    sx.math.clampToRange(speed,0,getPaddleMaxSpeed);
    if (targety<settings.pos.y-5) then movePaddle(-speed);
    if (targety>settings.pos.y+5) then movePaddle(speed);
  end;
end;


procedure SAEPaddle.enterCurrentGame;
var joyindex:SXInt;
begin
  case paddle.belongtoplayer of
    1 : begin
          if (app.input.isPressed('Up','Player1'))
          or (app.input.isPressed('Down','Player1')) then
          begin
            getPlayer.setupHumanControl;
            paddle.timesincelastaction := 0;
          end;

          joyindex := app.ini.settings.player1.joypad - 1;
          if (joyindex > SX_NONE) and (app.input.joysticks.maxjoystick >= joyindex) then
            if (app.input.getJoystick(joyindex).getMovementY <> 0) then
            begin
              getPlayer.setupHumanControl;
              paddle.timesincelastaction := 0;
            end;
        end;
    2 : begin
          if (app.input.isPressed('Up','Player2'))
          or (app.input.isPressed('Down','Player2')) then
          begin
            getPlayer.setupHumanControl;
            paddle.timesincelastaction := 0;
          end;

          joyindex := app.ini.settings.player2.joypad - 1;
          if (joyindex > SX_NONE) and (app.input.joysticks.maxjoystick >= joyindex) then
            if (app.input.getJoystick(joyindex).getMovementY <> 0) then
            begin
              getPlayer.setupHumanControl;
              paddle.timesincelastaction := 0;
            end;
        end;
  end;
end;


procedure SAEPaddle.leaveCurrentGame;
begin
  getPlayer.setupCPUControl;
end;


procedure SAEPaddle.onTimer;
begin
  paddle.lastpos:=settings.pos.y;
  movePaddleByInertia;
  case getPlayer.getControl of
    SX_PLAYER_CONTROL_LOCAL         : onLocalInput;
    SX_PLAYER_CONTROL_CPU           : begin
                                        processAI;
                                        enterCurrentGame;
                                      end;
  end;

  clampPosToField;
end;




procedure SAEPaddle.initialize;
begin
end;


constructor SAEPaddle.Create(parent:TObject);
begin
  inherited Create(parent);

  setupAppearance(app.scene.board.settings.paddle, 35);
  paddle.belongtoplayer := SX_NONE;
  paddle.inertia := 0;
end;


destructor SAEPaddle.Destroy;
begin
  inherited;
end;


end.