2024-05-29 17:38:50 +03:00
|
|
|
local pd <const> = playdate
|
|
|
|
local gfx <const> = playdate.graphics
|
|
|
|
|
|
|
|
class('Player').extends(AnimatedSprite)
|
|
|
|
|
|
|
|
function Player:init(x, y, gameManager)
|
|
|
|
self.gameManager = gameManager
|
|
|
|
|
|
|
|
local playerImageTable = gfx.imagetable.new("sprites/player-table-48-48")
|
|
|
|
Player.super.init(self, playerImageTable)
|
|
|
|
|
2024-05-30 11:45:27 +03:00
|
|
|
-- self:addState("run", 8,14, {tickStep = 2})
|
|
|
|
self:addState("run", 1,7, {tickStep = 2})
|
2024-05-29 17:38:50 +03:00
|
|
|
self:addState("up", 1,7, {tickStep = 6})
|
|
|
|
self:addState("down", 1,7, {tickStep = 6})
|
|
|
|
self:addState("boom", 15,21, {tickStep = 10, loop = false})
|
|
|
|
|
|
|
|
self:setDefaultState("down")
|
|
|
|
|
|
|
|
self:playAnimation()
|
|
|
|
|
|
|
|
-- Sprite properties
|
|
|
|
self:moveTo(x, y)
|
|
|
|
self:setZIndex(10)
|
|
|
|
self:setCollideRect(3, 19, 63, 33)
|
|
|
|
|
|
|
|
self:setTag(1)
|
|
|
|
|
|
|
|
self:changeState("down")
|
|
|
|
|
|
|
|
-- Physics properties
|
|
|
|
self.xVelocity = 0
|
|
|
|
self.yVelocity = 0
|
|
|
|
self.maxXSpeed = 2
|
|
|
|
self.maxYSpeed = 5
|
|
|
|
|
2024-05-31 13:19:42 +03:00
|
|
|
self.fallSpeed = 0.05
|
|
|
|
self.maxFallSpeed = 0.4
|
2024-05-29 17:38:50 +03:00
|
|
|
|
|
|
|
-- Player State
|
|
|
|
self.touchingGround = false
|
|
|
|
self.touchingCeiling = false
|
|
|
|
self.touchingWall = false
|
|
|
|
Player.dead = false
|
|
|
|
|
|
|
|
Player.bat = 10000
|
|
|
|
|
|
|
|
Player.dischargeRate = 1
|
|
|
|
|
|
|
|
self.cantDown = false
|
|
|
|
|
|
|
|
Player.moveRight = false
|
|
|
|
end
|
|
|
|
|
|
|
|
function Player:handleGroundInput(state)
|
|
|
|
if Player.bat <= 0 or Player.dead then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
local change, acceleratedChange = playdate.getCrankChange()
|
|
|
|
|
|
|
|
if pd.buttonJustReleased(pd.kButtonLeft) or pd.buttonJustReleased(pd.kButtonRight) then
|
|
|
|
self.cantDown = false
|
|
|
|
end
|
|
|
|
|
|
|
|
if pd.buttonIsPressed(pd.kButtonLeft) then
|
|
|
|
self:changeToRunState("left")
|
2024-05-30 11:45:27 +03:00
|
|
|
self:setRotation(10)
|
2024-05-29 17:38:50 +03:00
|
|
|
self.cantDown = true
|
|
|
|
Player.moveRight = false
|
|
|
|
elseif pd.buttonIsPressed(pd.kButtonRight) then
|
|
|
|
self:changeToRunState("right")
|
2024-05-30 11:45:27 +03:00
|
|
|
self:setRotation(10)
|
2024-05-29 17:38:50 +03:00
|
|
|
self.cantDown = true
|
|
|
|
Player.moveRight = true
|
|
|
|
end
|
|
|
|
|
|
|
|
if change ~= 0 then
|
|
|
|
local force = 0.01
|
|
|
|
if change > 0 then
|
|
|
|
self:changeState("up")
|
|
|
|
else
|
|
|
|
self:changeState("down")
|
|
|
|
force = 0.05
|
|
|
|
end
|
|
|
|
self.yVelocity = self.yVelocity - acceleratedChange * force
|
|
|
|
elseif self.cantDown == false then
|
|
|
|
self.cantDown = false
|
|
|
|
self:changeToDownState()
|
|
|
|
else
|
|
|
|
self.yVelocity = self.fallSpeed
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function Player:changeToDownState()
|
|
|
|
Player.moveRight = false
|
|
|
|
self.yVelocity = self.fallSpeed
|
|
|
|
self.xVelocity = 0
|
|
|
|
self:changeState("down")
|
2024-05-30 11:45:27 +03:00
|
|
|
self:setRotation(0)
|
2024-05-29 17:38:50 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
function Player:changeToRunState(direction)
|
|
|
|
if direction == "left" then
|
|
|
|
self.xVelocity = -self.maxXSpeed
|
|
|
|
self.globalFlip = 1
|
|
|
|
self:changeState("run")
|
|
|
|
elseif direction == "right" then
|
|
|
|
self.xVelocity = self.maxXSpeed
|
|
|
|
self.globalFlip = 0
|
|
|
|
self:changeState("run")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function Player:handleMovementAndCollisions()
|
2024-05-30 11:45:27 +03:00
|
|
|
local _
|
|
|
|
local collisions
|
|
|
|
local length = 0
|
|
|
|
|
2024-05-31 13:19:42 +03:00
|
|
|
if Player.dead then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
local xVel = self.xVelocity
|
|
|
|
|
|
|
|
if (self.x < 20 and xVel < 0) or (self.x > 380 and xVel > 0) then
|
|
|
|
xVel = 0
|
2024-05-30 11:45:27 +03:00
|
|
|
end
|
2024-05-29 17:38:50 +03:00
|
|
|
|
2024-05-31 13:19:42 +03:00
|
|
|
_, _, collisions, length = self:checkCollisions(self.x + xVel, self.y + self.yVelocity)
|
|
|
|
|
|
|
|
|
2024-05-29 17:38:50 +03:00
|
|
|
self.touchingGround = false
|
|
|
|
self.touchingCeiling = false
|
|
|
|
self.touchingWall = false
|
|
|
|
|
|
|
|
for i=1,length do
|
|
|
|
local collision = collisions[i]
|
|
|
|
local collisionType = collision.type
|
|
|
|
local collisionObject = collision.other
|
|
|
|
local collisionTag = collisionObject:getTag()
|
|
|
|
if collisionType == gfx.sprite.kCollisionTypeSlide then
|
|
|
|
if collision.normal.y == -1 then
|
|
|
|
self.touchingGround = true
|
|
|
|
elseif collision.normal.y == 1 then
|
|
|
|
self.touchingCeiling = true
|
|
|
|
end
|
|
|
|
|
|
|
|
if collision.normal.x ~= 0 then
|
|
|
|
self.touchingWall = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-05-31 13:19:42 +03:00
|
|
|
|
2024-05-29 17:38:50 +03:00
|
|
|
if collisionTag == 3 then
|
|
|
|
Player.dead = true
|
|
|
|
self:changeState("boom")
|
2024-05-31 13:19:42 +03:00
|
|
|
return
|
|
|
|
elseif collisionTag == 154 then
|
|
|
|
Player.dead = true
|
|
|
|
self:changeState("boom")
|
|
|
|
|
|
|
|
local particleB = ParticlePoly(self.x, self.y)
|
|
|
|
particleB:setThickness(2)
|
|
|
|
particleB:setAngular(-15,15)
|
|
|
|
particleB:setSize(1, 2)
|
|
|
|
particleB:setSpeed(1, 3)
|
|
|
|
particleB:setMode(Particles.modes.STAY)
|
|
|
|
particleB:setBounds(0,0,400,240)
|
|
|
|
particleB:setColour(gfx.kColorXOR)
|
|
|
|
particleB:add(20)
|
|
|
|
collisionObject:remove() -- TODO: add animation
|
|
|
|
return
|
2024-05-29 17:38:50 +03:00
|
|
|
end
|
|
|
|
end
|
2024-05-31 13:19:42 +03:00
|
|
|
self:moveTo(self.x + xVel, self.y + self.yVelocity)
|
2024-05-29 17:38:50 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
function Player:isMovingRight()
|
|
|
|
return Player.moveRight
|
|
|
|
end
|
|
|
|
|
|
|
|
function Player:isDead()
|
|
|
|
return Player.dead
|
|
|
|
end
|
|
|
|
|
|
|
|
function Player:getBat()
|
|
|
|
return Player.bat
|
|
|
|
end
|
|
|
|
|
|
|
|
function Player:handleDischarge(state)
|
|
|
|
if Player.dead then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
if Player.bat <= 0 then
|
|
|
|
Player.bat = 0
|
|
|
|
self.fallSpeed = 2
|
|
|
|
self:changeToDownState()
|
2024-05-31 13:19:42 +03:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
if Player.bat < 5000 then
|
|
|
|
self.fallSpeed = self.maxFallSpeed
|
2024-05-29 17:38:50 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
if state == "run" then
|
|
|
|
Player.dischargeRate = 5
|
|
|
|
elseif state == "up" then
|
|
|
|
Player.dischargeRate = 10
|
|
|
|
else
|
|
|
|
Player.dischargeRate = 1
|
|
|
|
end
|
|
|
|
|
2024-05-31 13:19:42 +03:00
|
|
|
if self.y < 5 then
|
|
|
|
Player.dischargeRate = 20
|
|
|
|
end
|
|
|
|
|
2024-05-29 17:38:50 +03:00
|
|
|
Player.bat = Player.bat - Player.dischargeRate
|
|
|
|
end
|
|
|
|
|
|
|
|
function Player:update()
|
|
|
|
self:updateAnimation()
|
2024-05-31 13:19:42 +03:00
|
|
|
self:handleMovementAndCollisions()
|
|
|
|
|
2024-05-29 17:38:50 +03:00
|
|
|
if Player.dead then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
local state = self:getCurrentState()["name"]
|
|
|
|
|
|
|
|
self:handleDischarge(state)
|
|
|
|
self:handleGroundInput(state)
|
|
|
|
end
|