So I created an account to ask how to add the ability to double jump, in the process I noticed that I could shorten my code a bit and I accidentally solved the problem. But I'm not here to tell you a success story because I found another problem, if you can time your jumps correctly then you can jump infinitely. So I'm not wondering how to double jump but to restrict it.
One thing worth of note is that the code is from: https://michagamedev.wordpress.com/2014 ... mp-height/ and it was the only code that worked for me (thanks micha). I modified it a bit (off course) to try to add double jumping, and I commented a lot of the code to give you the idea of what I was trying, hopefully this helps.
function mode_jump(mode)
--Sets jump
if mode == 'ground' then
player.mode = 'jump'
player.yvel = -400
end
--Idea is to double jump with this
if mode == 'double jump' then
player.mode = 'dJump'
player.yvel = player.y - 400
end
end
function player.jump(dt)
player.yvel = player.yvel + gravity * dt
-- player.mode is set to ground, when space is pressed it runs mode_jump('ground')
if love.keyboard.isDown(' ') and player.mode == 'ground' then
mode_jump('ground')
end
--the idea of this script is to grant the ability to double jump
--checks if player is in the air
if player.mode == 'jump' and player.yvel > 0 then
player.mode = 'air'
--if player is in the air
if player.mode == 'air' then
--idea is to let them jump again while player.dJump = true
--my idea is to make double jump a power-up
if love.keyboard.isDown(' ') and player.dJump == true then
mode_jump('double jump')
end
end
--resets player.mode so you can jump again
elseif player.mode == 'air' or 'dJump' and player.y == ground_level - player.height and player.yvel >= 0 then
player.mode = 'ground'
end
player.x = player.x + player.xvel * dt
player.y = player.y + player.yvel * dt
end
So I tried to clean the script a bit and tried what Ruirize suggested (but most likely did it completely wrong ) and I did make the script cleaner but I can't get the game to double jump. Here is what I have:
function jump_mode(mode)
if mode == 'ground' then
if player.mode == 'ground' then
player.mode = 'jump'
player.yv = -400
end
end
end
function player.jump(dt)
player.yv = player.yv + gravity * dt
if player.mode == 'jump' and player.yv > 0 then
player.mode = 'air'
end
if player.mode == 'air' then
if player.dJump == false and player.y == ground_level - player.height and player.yv > 0 then
player.jumpsleft = 1
player.mode = 'ground'
elseif player.dJump == true and player.y == ground_level - player.height and player.yv > 0 then
player.jumpsleft = 2
player.mode = 'ground'
end
end
player.x = player.x + player.xv * dt
player.y = player.y + player.yv * dt
end
function love.keypressed(key, isrepeat)
if gameState == "playing" then
if player.dJump == false then
player.jumpsleft = 1
end
if player.dJump == true then
player.jumpsleft = 2
end
if key == ' ' then
jump_mode('ground')
player.jumpsleft = player.jumpsleft - 1
if player.jumpsleft == 1 then
jump_mode('ground')
player.jumpsleft = 0
end
end
end
end
In general, this becomes easier when you move most of the code into a function called once a frame, like love.update. Much of the code in player.jump, like the movement code, should probably go into a function called player.update(dt) or player:update(dt). Your jump_mode function is similar to player:jump, and your player.jump is similar to player:update. I renamed them to make it clearer to me, but you can rename them if you want.
EDIT: looking at your original post and the link to the Meat Boy jump implementation, this doesn't do variable height jumps, but it does do double jumps quite well.
function player:jump()
if self.jumpsLeft > 0 and self.mode ~= 'jump' then
self.jumpsLeft = self.jumpsLeft - 1
self.mode = 'jump'
self.yv = -400
end
end
function player:update(dt)
-- Move player based on velocity and gravity
self.yv = self.yv + gravity * dt
self.x = self.x + self.xv * dt
self.y = self.y + self.yv * dt
-- move to ground if necesarry
if self.y + self.height >= ground_level then
self.mode = 'ground'
self.yv = 0
self.y = ground_level - self.height
end
-- reset jump count if on ground
if self.mode == 'ground' then
if self.dJump then
self.jumpsLeft = 2
else
self.jumpsLeft = 1
end
end
-- switch mode to 'air' if moving down and not on ground.
if self.mode == 'jump' and self.yv > 0 then
self.mode = 'air'
end
end
Instead of setting the jump counter to two when the character is on the ground, always set it to one (regardless of double jumping). Right when the character jumps, check if the character starts on the ground and can double jump, and if so, increment the jump counter to two before decrementing it (or just leave it unchanged). That way, when the character falls of a ledge, the jump counter is still at the default 1.