Player = {} class("Player").extends(AnimatedSprite) local playerImageTable = Graphics.imagetable.new("assets/sprites/player") function Player:init(x, y) Player.super.init(self, playerImageTable) -- Animation properties self:addState("run", 1, 7, { 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() -- Collision properties self:moveTo(x, y) self:setZIndex(10) self:setCollideRect(3, 19, 63, 33) self:setTag(1) -- Physics properties self.xVelocity = 0 self.yVelocity = 0 self.maxXSpeed = 2 self.maxYSpeed = 5 self.fallSpeed = 0.05 self.maxFallSpeed = 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:handleInput() if Player.bat <= 0 or Player.dead then return end local crankChange, acceleratedChange = playdate.getCrankChange() if playdate.buttonJustReleased(playdate.kButtonLeft) or playdate.buttonJustReleased(playdate.kButtonRight) then self.cantDown = false end if playdate.buttonIsPressed(playdate.kButtonLeft) then self:changeToRunState("left") self:setRotation(10) self.cantDown = true Player.moveRight = false elseif playdate.buttonIsPressed(playdate.kButtonRight) then self:changeToRunState("right") self:setRotation(10) self.cantDown = true Player.moveRight = true end if crankChange ~= 0 then local force = 0.01 if crankChange > 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") self:setRotation(0) 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:boom(collisionObject) 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(Graphics.kColorXOR) particleB:add(20) if collisionObject then collisionObject:remove() end end function Player:handleMovementAndCollisions() 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 -- Screen bounds xVel = 0 end local _, _, collisions, length = self:checkCollisions(self.x + xVel, 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 == Graphics.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 -- Ground self:boom() return elseif collisionTag == 154 then -- Baleba -- self:boom(collisionObject) return elseif collisionTag == 2 then -- Tank self:boom() local particleC = ParticlePoly(collisionObject.x, collisionObject.y) particleC:setThickness(5) particleC:setAngular(-15, 15) particleC:setSize(1, 5) particleC:setSpeed(1, 3) particleC:setMode(Particles.modes.STAY) particleC:setBounds(0, 0, 400, 240) particleC:setColour(Graphics.kColorXOR) particleC:add(50) collisionObject:fadeout() return end end self:moveTo(self.x + xVel, self.y + self.yVelocity) end function Player:handleDischarge(state) if Player.dead then return end if Player.bat <= 0 then Player.bat = 0 self.fallSpeed = 2 self:changeToDownState() return end if Player.bat < 5000 then self.fallSpeed = self.maxFallSpeed end if state == "run" then Player.dischargeRate = 5 elseif state == "up" then Player.dischargeRate = 10 else Player.dischargeRate = 1 end if self.y < 5 then Player.dischargeRate = 20 end Player.bat = Player.bat - Player.dischargeRate end function Player:update() self:updateAnimation() self:handleMovementAndCollisions() if Player.dead then return end local state = self:getCurrentState()["name"] self:handleDischarge(state) self:handleInput() end function Player:isMovingRight() return Player.moveRight end function Player:isDead() return Player.dead end function Player:getBat() return Player.bat end