project-witchy/imperium-porcorum.love/scenes/levels/entities/player.lua

258 lines
5.6 KiB
Lua

local Entity = require "scenes.levels.entities.parent"
local Player = Entity:extend()
-- INIT functions
-- Initialize the player
function Player:new(level, x, y, playerID)
local w, h = 32, 24
self.direction = 1
self.startx, self.starty = x, y
Player.super.new(self, level, "player", x - (w / 2), y - (h / 2), w, h)
self.manager = level.playermanager
self.center = {
x = self.x,
y = self.y,
}
self.stats = {}
self:getStats(playerID)
self:lifeInit()
self:initWeapon()
self.currentWeapon = 1
self:initMovement()
self:setDebugColor(0,255,0)
end
function Player:getStats(playerID)
self.pigID = self.manager.players[playerID].pigID
self.stats = game.pigmanager:getPig(1)
self.playerID = playerID
end
function Player:lifeInit()
self.hp = self.stats.maxHP
self.mp = self.stats.maxMP
end
function Player:initMovement()
self.maxxsp = 16*60
self.maxysp = self.maxxsp
self.topsp = 4.5*60
self.acc = 0.046875*60*1.5
self.dec = 0.5*60
self.frc = self.acc
self.grav = 1
self.jmp = -5*60
self.isJumping = false
end
function Player:initWeapon()
self.weaponID = 1
self:setWeapon()
end
-- UPDATE and COLLISION functions
-- Physics and function called every game update
function Player:update(dt)
self.keys = self.scene.sources[1].keys
self.scene.assets.sprites[self.stats.race]:setCustomSpeed(math.abs(self.xsp / 60))
self:actionMove(dt)
self:shoot(dt)
self:gravity(dt)
self:limitMovement()
self:setFilter()
local cols, cols_len = self:move(dt)
self:resolveCollisions(cols, cols_len)
self.center.x, self.center.y = self:getCenter()
self:getDirection()
local _, height = self.world:getDimensions()
if self.y >= (height + 64) then
self:die()
end
end
function Player:setFilter()
self.filter = function(item, other)
if (other.collType == "wall") then return 'slide'
elseif (other.collType == "block") then return 'slide'
elseif (other.collType == "platform") and
(self.ysp > 0) and
((self.y+24) <= other.y) then return 'slide'
elseif (other.collType == "loot") then return 'cross'
else return nil
end
end
end
function Player:resolveCollisions(cols, cols_len)
local cols, cols_len = cols, cols_len
for j=1,cols_len do
local other = cols[j].other
if (other.collType == "loot") then
other:takeLoot()
end
end
end
function Player:limitMovement()
if (math.abs(self.xsp) >= self.maxxsp) then
self.xsp = self.maxxsp * math.sign(self.xsp)
end
if (math.abs(self.ysp) >= self.maxysp) then
self.ysp = self.maxysp * math.sign(self.ysp)
end
end
-- GAMEPLAY functions
-- Where the player act and move
function Player:shoot()
if self.keys["B"].isPressed then
self:launchWeapon()
end
if self.keys["C"].isPressed then
self:changeWeapon(self.weaponID+1)
end
end
function Player:actionMove(dt)
local dx, dy = 0, 0
if self.keys["right"].isDown and not (self.keys["left"].isDown) then
if (self.xsp < self.topsp) then
if (self.xsp < 0) then
self.xsp = self.xsp + self.dec
else
self.xsp = self.xsp + self.acc
end
end
elseif self.keys["left"].isDown and not (self.keys["right"].isDown) then
if (self.xsp > -self.topsp) then
if (self.xsp > 0) then
self.xsp = self.xsp - self.dec
else
self.xsp = self.xsp - self.acc
end
end
else
self:friction(dt)
end
if (self.grav == 0) then
if self.keys["down"].isPressed and (self.y < 1000) then
self.ysp = 160
elseif self.keys["up"].isPressed and (self.y > 0) then
self.ysp = -160
end
end
if (self.onGround == true) then
self.isJumping = false
end
multijump = true
if ((self.onGround == true) or multijump) and self.keys["A"].isPressed then
self.ysp = self.jmp
self.isJumping = true
self.scene.assets:playSFX("jump")
end
if (self.isJumping == true) and (self.ysp < (-4 * 60)) and (not (self.keys["A"].isDown)) then
self.ysp = -4 * 60
end
return dx, dy
end
function Player:launchWeapon()
self.obj.Weapon(self.scene, self.center.x, self.center.y, self.weapon, 350 * utils.math.sign(self.direction))
end
function Player:changeWeapon(id)
local maxWeapon = #self.stats.weaponList
self.weaponID = utils.math.wrap(id, 1, maxWeapon)
self:setWeapon()
end
function Player:setWeapon()
self.weapon = self.stats.weaponList[self.weaponID]
end
-- DRAW functions
function Player:getAnimation()
local animation = "idle"
if (self.onGround) then
if (self.xsp == 0) then
animation = "idle"
else
if (self.keys["left"].isDown and (self.xsp > 0)) or
(self.keys["right"].isDown and (self.xsp < 0)) then
animation = "brake"
else
animation = "walk"
end
end
else
if (self.ysp < 0) and (self.isJumping) then
animation = "jump"
else
animation = "fall"
end
end
if not (self.scene.assets.sprites[self.stats.race]:animationExist(animation)) then
animation = "idle"
end
self.scene.assets.sprites[self.stats.race]:changeAnimation(animation, false)
return animation
end
function Player:draw(dt)
local drawx, drawy = utils.math.floorCoord(self.center.x, self.center.y)
local animation = self:getAnimation()
self.scene.assets.sprites[self.stats.race]:drawAnimation(drawx, drawy, 0, self.direction, 1, 16, 36)
end
-- DEATH and HIT functions
-- All function related to damage management
function Player:takeHit(damage)
if (self.hp <= damage) then
self:die()
else
self.hp = self.hp - damage
end
end
function Player:die()
self.manager:setDeathTimer(1)
self:destroy()
end
return Player