local pd = playdate local gfx = 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) self:addState("run", 8,14, {tickStep = 2}) 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 self.fallSpeed = 0.4 -- 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") self.cantDown = true Player.moveRight = false elseif pd.buttonIsPressed(pd.kButtonRight) then self:changeToRunState("right") 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") 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() local _, _, collisions, length = self:moveWithCollisions(self.x + self.xVelocity, self.y + self.yVelocity) 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 if collisionTag == 3 then Player.dead = true self:changeState("boom") -- elseif collisionTag == TAGS.Pickup then -- collisionObject:pickUp(self) end end 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() end if state == "run" then Player.dischargeRate = 5 elseif state == "up" then Player.dischargeRate = 10 else Player.dischargeRate = 1 end Player.bat = Player.bat - Player.dischargeRate end function Player:update() self:updateAnimation() if Player.dead then return end local state = self:getCurrentState()["name"] self:handleDischarge(state) self:handleGroundInput(state) self:handleMovementAndCollisions() end