206 lines
4.8 KiB
Lua
206 lines
4.8 KiB
Lua
|
player = entity:newEntity(x,y)
|
||
|
|
||
|
function InitPlayer(id)
|
||
|
player.health = 3
|
||
|
player.coins = 0
|
||
|
|
||
|
-- physics
|
||
|
player.vel = {
|
||
|
x = 0,
|
||
|
y = 0
|
||
|
}
|
||
|
-- constants
|
||
|
player.acc = 90
|
||
|
player.friction = 20
|
||
|
player.gravity = 9.81
|
||
|
player.climbHeight = 3
|
||
|
player.jumpForce = 5
|
||
|
player.maxSpeed = 600
|
||
|
player.jumpMaxSpeed = 9.5
|
||
|
player.zeroSpeed = 0.001
|
||
|
-- bools
|
||
|
player.isJumping = false
|
||
|
player.isOnGround = false
|
||
|
player.isOnLadder = false
|
||
|
player.canJump = true
|
||
|
player.canFall = true
|
||
|
player.canFriction = true
|
||
|
|
||
|
-- sprite
|
||
|
player.offset = {x = -8, y = -16}
|
||
|
end
|
||
|
|
||
|
function player:DoInput()
|
||
|
-- PLATFORMER INPUT
|
||
|
if self.isOnGround then
|
||
|
-- apply friction
|
||
|
|
||
|
-- horizontal input (slide~~)
|
||
|
if love.keyboard.isDown('a',"left") then
|
||
|
self.vel.x = self.vel.x - self.acc*current_dt
|
||
|
end
|
||
|
if love.keyboard.isDown('d',"right") then
|
||
|
self.vel.x = self.vel.x + self.acc*current_dt
|
||
|
end
|
||
|
if self.canJump then
|
||
|
-- vertical input (jump!)
|
||
|
if love.keyboard.isDown("up", "w") and self.isJumping ~= true then
|
||
|
self.vel.y = self.vel.y - self.jumpForce
|
||
|
self.isOnGround = false
|
||
|
self.isJumping = true
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- fall if down input on platforms
|
||
|
if not isThereCollisionAt(
|
||
|
self.pos.x,
|
||
|
self.pos.y + self.vel.y
|
||
|
) and not isThereLadderAt(
|
||
|
self.pos.x,
|
||
|
self.pos.y + self.vel.y
|
||
|
) and isTherePlatformAt(
|
||
|
self.pos.x,
|
||
|
self.pos.y + self.vel.y
|
||
|
) and love.keyboard.isDown("down", "s")
|
||
|
then
|
||
|
self.pos.y = self.pos.y + tileProperties.height/3
|
||
|
self.isOnGround = false
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function player:HandleAnimation()
|
||
|
|
||
|
-- flip sprite to look in the direction is moving
|
||
|
if self.vel.x ~= 0 then self.flip.x = math.sign(self.vel.x) end
|
||
|
|
||
|
-- animation manager
|
||
|
if self.isOnLadder then
|
||
|
self:LoadAnimation(animation.nancy.jump)
|
||
|
elseif not self.isOnGround and self.isJumping and self.vel.y > 1.25 then
|
||
|
self:LoadAnimation(animation.nancy.fall)
|
||
|
elseif not self.isOnGround and self.vel.y < 0 then
|
||
|
self:LoadAnimation(animation.nancy.jump)
|
||
|
elseif self.vel.x ~= 0 then
|
||
|
self:LoadAnimation(animation.nancy.run)
|
||
|
else
|
||
|
self:LoadAnimation(animation.nancy.idle)
|
||
|
end
|
||
|
|
||
|
-- special case: idle animation gets slower by time
|
||
|
if self.anim_path == animation.nancy.idle.path then
|
||
|
if self.anim_speed < 0.5 then self.anim_speed = self.anim_speed + 0.001 end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function player:DoPhysics()
|
||
|
-- reset physics resolution
|
||
|
self.canFall = true
|
||
|
self.canJump = true
|
||
|
self.canFriction = true
|
||
|
-- reset flags
|
||
|
self.isOnGround = false
|
||
|
self.isOnLadder = false
|
||
|
-- truncate to max & min values
|
||
|
if math.abs(self.vel.x) > self.maxSpeed then
|
||
|
self.vel.x = self.maxSpeed * math.sign(self.vel.x)
|
||
|
end
|
||
|
if math.abs(self.vel.y) > self.maxSpeed then
|
||
|
self.vel.y = self.maxSpeed * math.sign(self.vel.y)
|
||
|
end
|
||
|
if math.abs(self.vel.x) < self.zeroSpeed then
|
||
|
self.vel.x = 0
|
||
|
end
|
||
|
if math.abs(self.vel.y) < self.zeroSpeed then
|
||
|
self.vel.y = 0
|
||
|
end
|
||
|
|
||
|
-- if on air, say so!
|
||
|
if self.vel.y > 5 then
|
||
|
self.isJumping = true
|
||
|
end
|
||
|
|
||
|
-- if its on ground, then say so.
|
||
|
if self.vel.y > 0 then
|
||
|
if isThereAnyCollisionAt(
|
||
|
self.pos.x,
|
||
|
self.pos.y + self.vel.y
|
||
|
) then
|
||
|
self.isOnGround = true
|
||
|
self.isJumping = false
|
||
|
end
|
||
|
end
|
||
|
-- horizontal collisions
|
||
|
if isThereAnyCollisionAt(self.pos.x + self.vel.x, self.pos.y) then
|
||
|
-- checks for ladders
|
||
|
if isThereLadderAt(self.pos.x + self.vel.x, self.pos.y)
|
||
|
and self.vel.x ~= 0
|
||
|
and not isThereLadderAt(self.pos.x, self.pos.y)
|
||
|
then
|
||
|
self.vel.y = 0
|
||
|
self.vel.x = 0
|
||
|
|
||
|
self.pos.y = self.pos.y - 4*game.scale * current_dt
|
||
|
|
||
|
self.canFall = false
|
||
|
self.canJump = false
|
||
|
self.canFriction = false
|
||
|
|
||
|
self.isOnLadder = true
|
||
|
self.isOnGround = true
|
||
|
end
|
||
|
|
||
|
-- checks for slopes
|
||
|
for i = 1, self.climbHeight do
|
||
|
if not isThereCollisionAt(self.pos.x + self.vel.x, self.pos.y - i * game.scale)
|
||
|
and self.isOnGround then
|
||
|
|
||
|
self.pos.x = self.pos.x + self.vel.x
|
||
|
self.pos.y = self.pos.y - i * game.scale
|
||
|
|
||
|
self.canFriction = false
|
||
|
break
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- hey, you arent permanently stopped while collisioning, just lose a bit of force!
|
||
|
if self.canFriction then
|
||
|
self.vel.x = self.vel.x * (1 - math.min(current_dt * self.friction/15, 1))
|
||
|
end
|
||
|
else
|
||
|
self.pos.x = self.pos.x + self.vel.x
|
||
|
end
|
||
|
|
||
|
-- vertical collision
|
||
|
if self.vel.y > 0
|
||
|
and isThereAnyCollisionAt(self.pos.x, self.pos.y + self.vel.y) then
|
||
|
self.isOnGround = true
|
||
|
self.isJumping = false
|
||
|
self.vel.y = 0
|
||
|
else
|
||
|
self.pos.y = self.pos.y + self.vel.y
|
||
|
end
|
||
|
|
||
|
-- drop.
|
||
|
if self.canFall then
|
||
|
self.vel.y = self.vel.y + 2*self.gravity * current_dt
|
||
|
end
|
||
|
|
||
|
-- friction hard in ground, soft in air
|
||
|
if self.isOnGround then
|
||
|
self.vel.x = self.vel.x * (1 - math.min(current_dt * self.friction, 1))
|
||
|
else
|
||
|
self.vel.x = self.vel.x * (1 - math.min(current_dt * self.friction/20, 1))
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
function player:newPlayer(x,y)
|
||
|
local o = entity:newEntity(x,y)
|
||
|
|
||
|
setmetatable(o, self)
|
||
|
self.__index = self
|
||
|
|
||
|
return o
|
||
|
end
|