2024-06-01 16:52:11 +03:00
|
|
|
Player = {}
|
2024-06-02 20:25:27 +03:00
|
|
|
class("Player").extends(NobleSprite)
|
2024-06-01 16:52:11 +03:00
|
|
|
|
|
|
|
function Player:init(x, y)
|
2024-06-02 20:25:27 +03:00
|
|
|
Player.super.init(self, "assets/sprites/player", true)
|
2024-06-01 16:52:11 +03:00
|
|
|
|
|
|
|
-- Animation properties
|
2024-06-03 00:31:15 +03:00
|
|
|
self.animation:addState("run", 8, 14)
|
2024-06-02 20:25:27 +03:00
|
|
|
self.animation.run.frameDuration = 2
|
|
|
|
self.animation:addState("up", 1, 7)
|
|
|
|
self.animation.up.frameDuration = 6
|
|
|
|
self.animation:addState("down", 1, 7)
|
|
|
|
self.animation.down.frameDuration = 6
|
|
|
|
self.animation:addState("boom", 15, 21)
|
|
|
|
self.animation.boom.frameDuration = 10
|
|
|
|
self.animation.boom.loop = false
|
|
|
|
|
|
|
|
self.animation:setState("down")
|
|
|
|
|
|
|
|
self:add()
|
2024-06-01 16:52:11 +03:00
|
|
|
|
|
|
|
-- Collision properties
|
2024-06-02 20:25:27 +03:00
|
|
|
self:setSize(64, 64)
|
2024-06-01 16:52:11 +03:00
|
|
|
self:moveTo(x, y)
|
2024-06-03 00:31:15 +03:00
|
|
|
self:setZIndex(ZIndex.player)
|
|
|
|
self:setGroups(CollideGroups.player)
|
|
|
|
self:setCollidesWithGroups(
|
|
|
|
{
|
|
|
|
CollideGroups.enemy,
|
|
|
|
CollideGroups.wall
|
|
|
|
})
|
|
|
|
self:setCollideRect(3, 19, 60, 33)
|
2024-06-01 16:52:11 +03:00
|
|
|
self:setTag(1)
|
|
|
|
|
|
|
|
-- Physics properties
|
2024-06-03 00:31:15 +03:00
|
|
|
self.fallSpeed = 0.05
|
2024-06-03 00:34:03 +03:00
|
|
|
self.xVelocity = -0.5
|
2024-06-03 00:31:15 +03:00
|
|
|
self.yVelocity = self.fallSpeed
|
2024-06-01 16:52:11 +03:00
|
|
|
self.maxXSpeed = 2
|
|
|
|
self.maxYSpeed = 5
|
2024-06-03 00:31:15 +03:00
|
|
|
self.acceleration = 0.05
|
|
|
|
self.friction = 0.95
|
|
|
|
self.yInertia = 0
|
|
|
|
self.maxFallSpeed = 0.7
|
|
|
|
self.frictionAccel = 0.3
|
2024-06-01 16:52:11 +03:00
|
|
|
|
|
|
|
-- Player State
|
|
|
|
self.touchingGround = false
|
|
|
|
self.touchingCeiling = false
|
|
|
|
self.touchingWall = false
|
|
|
|
Player.dead = false
|
2024-06-03 20:08:46 +03:00
|
|
|
Player.fullBat = 10000
|
|
|
|
Player.bat = Player.fullBat
|
2024-06-01 16:52:11 +03:00
|
|
|
Player.dischargeRate = 1
|
|
|
|
Player.moveRight = false
|
2024-06-03 00:31:15 +03:00
|
|
|
self.lastDirection = nil
|
|
|
|
self.targetDone = false
|
2024-06-01 16:52:11 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
function Player:handleInput()
|
|
|
|
if Player.bat <= 0 or Player.dead then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
local crankChange, acceleratedChange = playdate.getCrankChange()
|
|
|
|
|
2024-06-03 00:31:15 +03:00
|
|
|
-- X velocity
|
|
|
|
if not playdate.buttonIsPressed(playdate.kButtonLeft) and not playdate.buttonIsPressed(playdate.kButtonRight) then
|
|
|
|
self.xVelocity = self.xVelocity * self.friction
|
|
|
|
Player.moveRight = false
|
2024-06-03 00:34:03 +03:00
|
|
|
self.animation:setState("down")
|
2024-06-01 16:52:11 +03:00
|
|
|
end
|
|
|
|
|
2024-06-03 00:31:15 +03:00
|
|
|
local isChangingDirection = false
|
2024-06-01 16:52:11 +03:00
|
|
|
if playdate.buttonIsPressed(playdate.kButtonLeft) then
|
2024-06-03 00:31:15 +03:00
|
|
|
if self.lastDirection == "right" then
|
|
|
|
isChangingDirection = true
|
|
|
|
end
|
2024-06-01 16:52:11 +03:00
|
|
|
self:changeToRunState("left")
|
2024-06-03 00:31:15 +03:00
|
|
|
self.lastDirection = "left"
|
|
|
|
self.xVelocity = self.xVelocity - self.acceleration
|
2024-06-01 16:52:11 +03:00
|
|
|
elseif playdate.buttonIsPressed(playdate.kButtonRight) then
|
2024-06-03 00:31:15 +03:00
|
|
|
if self.lastDirection == "left" then
|
|
|
|
isChangingDirection = true
|
|
|
|
end
|
2024-06-01 16:52:11 +03:00
|
|
|
self:changeToRunState("right")
|
|
|
|
Player.moveRight = true
|
2024-06-03 00:31:15 +03:00
|
|
|
self.lastDirection = "right"
|
|
|
|
self.xVelocity = self.xVelocity + self.acceleration
|
|
|
|
end
|
|
|
|
|
|
|
|
if isChangingDirection then
|
|
|
|
self.xVelocity = self.xVelocity * self.frictionAccel
|
2024-06-01 16:52:11 +03:00
|
|
|
end
|
|
|
|
|
2024-06-03 00:31:15 +03:00
|
|
|
-- Y velocity
|
2024-06-01 16:52:11 +03:00
|
|
|
if crankChange ~= 0 then
|
|
|
|
if crankChange > 0 then
|
2024-06-02 20:25:27 +03:00
|
|
|
self.animation:setState("up")
|
2024-06-01 16:52:11 +03:00
|
|
|
else
|
2024-06-02 20:25:27 +03:00
|
|
|
self.animation:setState("down")
|
2024-06-01 16:52:11 +03:00
|
|
|
end
|
2024-06-03 00:31:15 +03:00
|
|
|
self.yInertia = self.yInertia - (acceleratedChange * 0.007)
|
2024-06-01 16:52:11 +03:00
|
|
|
else
|
2024-06-03 00:31:15 +03:00
|
|
|
self.yInertia = self.yInertia * self.friction
|
2024-06-01 16:52:11 +03:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function Player:changeToRunState(direction)
|
|
|
|
if direction == "left" then
|
2024-06-02 20:25:27 +03:00
|
|
|
self.animation.direction = Noble.Animation.DIRECTION_LEFT
|
|
|
|
self.animation:setState("run")
|
2024-06-01 16:52:11 +03:00
|
|
|
elseif direction == "right" then
|
2024-06-02 20:25:27 +03:00
|
|
|
self.animation.direction = Noble.Animation.DIRECTION_RIGHT
|
|
|
|
self.animation:setState("run")
|
2024-06-01 16:52:11 +03:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-06-01 22:46:36 +03:00
|
|
|
function Player:boom(collisionObject)
|
|
|
|
Player.dead = true
|
2024-06-02 20:25:27 +03:00
|
|
|
self.animation:setState("boom")
|
2024-06-01 22:46:36 +03:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2024-06-01 16:52:11 +03:00
|
|
|
function Player:handleMovementAndCollisions()
|
|
|
|
if Player.dead then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
local xVel = self.xVelocity
|
2024-06-03 00:31:15 +03:00
|
|
|
local yVel = self.yVelocity + self.yInertia + self.fallSpeed
|
2024-06-01 16:52:11 +03:00
|
|
|
|
|
|
|
if (self.x < 20 and xVel < 0) or (self.x > 380 and xVel > 0) then -- Screen bounds
|
|
|
|
xVel = 0
|
|
|
|
end
|
|
|
|
|
2024-06-03 00:31:15 +03:00
|
|
|
local _, _, collisions, length = self:checkCollisions(self.x + xVel, self.y + yVel)
|
2024-06-01 16:52:11 +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 == 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
|
2024-06-01 22:46:36 +03:00
|
|
|
self:boom()
|
2024-06-01 16:52:11 +03:00
|
|
|
return
|
|
|
|
elseif collisionTag == 154 then -- Baleba
|
2024-06-03 20:08:46 +03:00
|
|
|
--self:boom(collisionObject)
|
2024-06-01 22:46:36 +03:00
|
|
|
return
|
|
|
|
elseif collisionTag == 2 then -- Tank
|
|
|
|
self:boom()
|
2024-06-02 20:25:27 +03:00
|
|
|
BigBoom()
|
2024-06-01 22:46:36 +03:00
|
|
|
|
2024-06-03 00:31:15 +03:00
|
|
|
self.targetDone = true
|
2024-06-01 22:46:36 +03:00
|
|
|
local particleC = ParticlePoly(collisionObject.x, collisionObject.y)
|
|
|
|
particleC:setThickness(5)
|
|
|
|
particleC:setAngular(-15, 15)
|
2024-06-02 20:25:27 +03:00
|
|
|
particleC:setSize(1, 10)
|
2024-06-01 22:46:36 +03:00
|
|
|
particleC:setSpeed(1, 3)
|
|
|
|
particleC:setMode(Particles.modes.STAY)
|
|
|
|
particleC:setBounds(0, 0, 400, 240)
|
|
|
|
particleC:setColour(Graphics.kColorXOR)
|
|
|
|
particleC:add(50)
|
|
|
|
collisionObject:fadeout()
|
2024-06-01 16:52:11 +03:00
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
2024-06-03 00:31:15 +03:00
|
|
|
|
|
|
|
self:moveTo(self.x + xVel, self.y + yVel)
|
2024-06-01 16:52:11 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
function Player:handleDischarge(state)
|
|
|
|
if Player.dead then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
if Player.bat <= 0 then
|
|
|
|
Player.bat = 0
|
|
|
|
self.fallSpeed = 2
|
2024-06-03 00:31:15 +03:00
|
|
|
self.animation:setState("down")
|
2024-06-01 16:52:11 +03:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
if Player.bat < 5000 then
|
|
|
|
self.fallSpeed = self.maxFallSpeed
|
|
|
|
end
|
|
|
|
|
2024-06-03 00:31:15 +03:00
|
|
|
if Player.bat < 3000 then
|
|
|
|
self.frictionAccel = 0.4
|
|
|
|
end
|
|
|
|
|
2024-06-01 16:52:11 +03:00
|
|
|
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:handleMovementAndCollisions()
|
|
|
|
if Player.dead then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2024-06-02 20:25:27 +03:00
|
|
|
self:handleDischarge(self.animation.currentName)
|
2024-06-01 16:52:11 +03:00
|
|
|
self:handleInput()
|
|
|
|
end
|
|
|
|
|
|
|
|
function Player:isMovingRight()
|
|
|
|
return Player.moveRight
|
|
|
|
end
|
|
|
|
|
|
|
|
function Player:isDead()
|
|
|
|
return Player.dead
|
|
|
|
end
|
|
|
|
|
|
|
|
function Player:getBat()
|
|
|
|
return Player.bat
|
|
|
|
end
|