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.