MaxGamz wrote: ↑Tue Mar 21, 2023 9:57 pm
About the jumping mechanic, I thought it was a simple issue and I sort of managed to fix it. However now my character can't preform the getting up animation. Is there another variable I should add? I am also confused about the state stuff.
Since I don't have your modifications I can't understand either why after modifying `Player:jump` the player does not stand up anymore... But don't panic!
I gave you an example of what the Player: jump method could look like, it could be optimized but hey, given the little it does for now, it's still very suitable. Here's the full script because I also made a few other changes, like PGimeno's suggestion, which will save you from handling state transitions in conditions in `Player:update` (I also added isScancodeDown instead of isDown, because not easy with an AZERTY keyboard):
Code: Select all
Player = {}
function Player:load()
self.x = love.graphics.getWidth() / 2
self.y = love.graphics.getHeight() / 2 - 62
self.spriteSheet = love.graphics.newImage("Sprites/TheWizzl.png")
self.speed = 400
self.ground = self.y
self.yVel = 0
self.jump_height = -300
self.gravity = -500
-- Animation Information
local grid = anim8.newGrid( -- No need to store this function in the table
32,32, self.spriteSheet:getWidth(), self.spriteSheet:getHeight()
)
self.anim = {}
self.anim.idle = anim8.newAnimation(grid('1-4', 1), 0.2)
self.anim.hat = anim8.newAnimation(grid(28, 1), 0.1)
self.anim.run = anim8.newAnimation(grid('8-11', 1), 0.1)
self.anim.hatWalk = anim8.newAnimation(grid('29-33', 1), 0.1)
self.anim.jump = anim8.newAnimation(grid(19, 1), 0.2)
self.anim.fall = anim8.newAnimation(grid(20, 1), 0.2)
self.anim.hide = anim8.newAnimation(grid('22-27', 1), 0.1, function ()
self:setState("hat") -- Applies the "hat" state at the end of the animation
self.on_anim = false
end)
self.anim.getUp = anim8.newAnimation(grid('35-38', 1), 0.1, function ()
self:setState("idle") -- Applies the "idle" state at the end of the animation
self.on_anim = false
end)
self:setState("idle")
self.on_anim = false -- This variable will be used to not launch a walk animation while another is in progress (jump, fall, hide, getUp)
self.crouch = false
self.switch = 2
end
function Player:setState(state)
if state ~= self.state then
self.anim_curr = self.anim[state]
self.anim_curr:gotoFrame(1)
self.prev_state = self.state
self.state = state
end
end
function Player:update(dt)
if love.keyboard.isScancodeDown("s") then
if not self.crouch
and self.y == self.ground then -- To avoid squatting in the air
self:setState("hide")
self.on_anim = true
self.crouch = true
end
end
if love.keyboard.isScancodeDown("space") then
if self.crouch then
self:setState("getUp")
self.on_anim = true
self.crouch = false
end
end
if love.keyboard.isScancodeDown("escape") then
love.event.quit()
end
-- Movement and anim update --
Player:move(dt)
Player:jump(dt)
self.anim_curr:update(dt)
end
function Player:draw()
self.anim_curr:draw(self.spriteSheet, self.x, self.y, nil, self.switch, 2, 16)
end
function Player:move(dt)
local onMove;
if love.keyboard.isScancodeDown("a") then
self.x = self.x - self.speed * dt
self.switch = -2
onMove = true
elseif love.keyboard.isScancodeDown("d") then
self.x = self.x + self.speed * dt
self.switch = 2
onMove = true
end
if not self.on_anim then
if onMove then
self:setState((self.crouch) and "hatWalk" or "run")
else
self:setState((self.crouch) and "hat" or "idle")
end
end
end
function Player:jump(dt)
if self.crouch == false then
if love.keyboard.isScancodeDown("w") then
if self.yVel == 0 then -- Start jump action
self.yVel = self.jump_height
self:setState("jump")
self.on_anim = true -- To prevent the animation from changing in `Player:move`
end
end
if self.yVel ~= 0 then -- Perform the jumping movement
self.y = self.y + self.yVel * dt
self.yVel = self.yVel - self.gravity * dt
if self.yVel > 0 then self:setState("fall") end
end
if self.y > self.ground then -- Check if you touch the ground
self:setState("idle")
self.on_anim = false -- Animation can change again in `Player:move`
self.y = self.ground
self.yVel = 0
end
end
end
Note: I remind you that the `Player:setState` method is only launched if the state given as a parameter is not the current state, it is practical because you do not have to handled the fact whether it should be called or not in the rest of the code. However if the project becomes more substantial it will still be better to manage the condition before the call, because a call remains a little expensive. Well you're not at this stage yet, it's just to say that it's practical but you don't have to get used to it
So I advise you to understand how it works and write your own mechanic afterwards, you will need it anyway if you will use Windfield in the end.
If I ever answered wrong or something is still unclear for you, don't hesitate to ask.