Character jumping problem ("a" and "d" makes character double jump in the middle of holding "space")

The problem that kept scratching my head is that whenever I press and hold the spacebar to jump, it will jump, but since my code does double jumping, pressing “a” or “d” would also cause it to jump.

Here’s the code:

aye = display.newGroup() physics = require("physics") physics.start() --physics.setDrawMode("hybrid") offset = 520 rect = display.newRect(display.contentCenterX,display.contentCenterY,100,100) rect2 = display.newRect(display.contentCenterX+offset,display.contentCenterY+200,1000,20) physics.addBody(rect,"dynamic", {density = 1,bounce = 0}, {box = {halfWidth = 50,halfHeight = 3,x = 0,y = 50},isSensor = true} ) ground1 = display.newRect(display.contentCenterX+offset+1500,display.contentCenterY+100,1000,20) physics.addBody(rect,"dynamic", {density = 1,bounce = 0}, {box = {halfWidth = 50,halfHeight = 6,x = 0,y = 50},isSensor = true} ) ground1.objType = 'ground' rect2.objType = "ground" physics.addBody(rect2,"static",{bounce = 0,friction = 0.4}) physics.addBody(ground1,"static",{bounce = 0,friction = 0.4}) rect.isFixedRotation = true rect.sensorOverlaps = 0 function lerp(a,b,t) return a \* (1-t) + b \* t end -- OUTSOURCING TO THE MAX! physicsGroup = display.newGroup() camera = display.newGroup() physicsGroup:insert(rect) physicsGroup:insert(rect2) physicsGroup:insert(ground1) camera:insert(physicsGroup) function ayeet() distanceX,distanceY = (0+rect.x),(0+rect.y) transition.to(camera,{time = 20,x = -distanceX+display.actualContentWidth/64,y = -distanceY+display.actualContentHeight/64,onComplete = ayeet}) end --- CAMERA AND CHARACTER physics.setGravity(0,55.6) -- CAMERA function lerpTo() transition.to(camera,{time = 65,x = lerp(camera.x,-rect.x,0.32)+display.actualContentWidth/6.5,y = lerp(camera.y,-rect.y,0.32)+display.actualContentHeight/6.5,onComplete = lerpTo}) end --- CHARACTER ---- CHARACTER ANIMATIONS ---- CHARACTER MOVEMENT double = 2 local X,Y = rect:getLinearVelocity() isColliding = false keyed = false allow = false currentlyDown = {a = false,d = false,space = false} local function move(press) local X,Y = rect:getLinearVelocity() local kp = press.phase local k = press.keyName if kp == "down" then if k == "a" then currentlyDown.a = true elseif k == "d" then currentlyDown.d = true end else if k == "a" then currentlyDown.a = false elseif k == "d" then currentlyDown.d = false end end print("Moving left = " .. tostring(currentlyDown.a) .. " | Moving right = " .. tostring(currentlyDown.d)) if kp == "down" and k == "space" then currentlyDown.space = true print("spaceDown") end if kp == "up" and k == "space" then currentlyDown.space = false print("spaceUp") end if currentlyDown.a == true then rect:setLinearVelocity(-500,Y) allow = false rect.linearDamping = 0 elseif currentlyDown.d == true then rect:setLinearVelocity(500,Y) allow = false rect.linearDamping = 0 end -------------------------------------------------------------------------------------------------------------- JUMP -------------------------------------------------------------------------------------------------------------- if currentlyDown.space == true and double \> 0 then print("Moving left = " .. tostring(currentlyDown.a) .. " | Moving right = " .. tostring(currentlyDown.d) .. " JUMP") if (currentlyDown.a == false or currentlyDown.d == false) then allow = false rect:setLinearVelocity(X,-600) double = double - 1 rect.linearDamping = 0 end end -------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------- end --[[NOTHING SPECIAL a rect:setLinearVelocity(-500,Y) allow = false rect.linearDamping = 0 d rect:setLinearVelocity(500,Y) allow = false rect.linearDamping = 0 space allow = false rect:setLinearVelocity(X,-600) double = double - 1]]-- local function jumper(self,press) if press.selfElement == 2 and press.other.objType == "ground" then if press.phase == "began" then isColliding = true double = 2 elseif press.phase == "ended" then isColliding = false end end end function rect.key(event) active = 0 for \_,v in pairs(currentlyDown) do if v == true then active = 1 allow = false end end if active == 1 then keyed = true allow = false else keyed = false allow = true end end function rect.enterFrame() if allow and not keyed then if isColliding then rect.linearDamping = 8 else rect.linearDamping = 0 end end end lerpTo() rect.collision = jumper rect:addEventListener("collision") Runtime:addEventListener("key",move) Runtime:addEventListener("key",rect) Runtime:addEventListener("enterFrame",rect)

Really frustates me, I’ve been working on this issue for almost 3 days, probably? But I need answers.

Thanks in advance.

(I’m new to posting topics, so I’m not really sure if I did the topic format right.)

There’s quite a lot to improve here.

First, you should use locals.

Secondly, avoid unnecessary code that doesn’t really do anything. At best, it does nothing, but at worst it may lead to bugs and other issues. For instance,

 

 if kp == "down" then if k == "a" then currentlyDown.a = true elseif k == "d" then currentlyDown.d = true end else if k == "a" then currentlyDown.a = false elseif k == "d" then currentlyDown.d = false end end

All that this following code does is identify if keys “a” or “d” are being being pressed or not. Later on you then check if these values are true, but this really seems like unnecessary work to me. You could write the a single movement function that you call whenever a specific key is pressed down, etc.

Now, thirdly, the reason as to why you are encountering your double jump problem is because a misunderstanding of how the key function actually works. Runtime:addEventListener(“key”,move) means that your function move runs every time any key is pressed, not just the ones that you’ve written some functionality for. If you look at your code:

 

 if currentlyDown.space == true and double \> 0 then print("Moving left = " .. tostring(currentlyDown.a) .. " | Moving right = " .. tostring(currentlyDown.d) .. " JUMP") if (currentlyDown.a == false or currentlyDown.d == false) then allow = false rect:setLinearVelocity(X,-600) double = double - 1 rect.linearDamping = 0 end end

First you check if the user is pressing down the spacebar and if the double jump counter is within limits. This means that pressing spacebar once or holding spacebar down and then pressing any other key on the keyboard will both satisfy this requirement.

Next you check if (currentlyDown.a == false or currentlyDown.d == false) then, which is true as long as the user is not pressing down both a and d keys at the same time. So, in total, your rect will jump as long as the user presses spacebar, or holds down the spacebar while pressing any key on their keyboard, as long as they don’t hold spacebar, a and d keys (all three keys) down at the same time.

This entire issue would be prevented if you ran the jumping code only in the event that spacebar is pressed instead of tracking whether or not spacebar is held down or not.

There’s quite a lot to improve here.

First, you should use locals.

Secondly, avoid unnecessary code that doesn’t really do anything. At best, it does nothing, but at worst it may lead to bugs and other issues. For instance,

 

 if kp == "down" then if k == "a" then currentlyDown.a = true elseif k == "d" then currentlyDown.d = true end else if k == "a" then currentlyDown.a = false elseif k == "d" then currentlyDown.d = false end end

All that this following code does is identify if keys “a” or “d” are being being pressed or not. Later on you then check if these values are true, but this really seems like unnecessary work to me. You could write the a single movement function that you call whenever a specific key is pressed down, etc.

Now, thirdly, the reason as to why you are encountering your double jump problem is because a misunderstanding of how the key function actually works. Runtime:addEventListener(“key”,move) means that your function move runs every time any key is pressed, not just the ones that you’ve written some functionality for. If you look at your code:

 

 if currentlyDown.space == true and double \> 0 then print("Moving left = " .. tostring(currentlyDown.a) .. " | Moving right = " .. tostring(currentlyDown.d) .. " JUMP") if (currentlyDown.a == false or currentlyDown.d == false) then allow = false rect:setLinearVelocity(X,-600) double = double - 1 rect.linearDamping = 0 end end

First you check if the user is pressing down the spacebar and if the double jump counter is within limits. This means that pressing spacebar once or holding spacebar down and then pressing any other key on the keyboard will both satisfy this requirement.

Next you check if (currentlyDown.a == false or currentlyDown.d == false) then, which is true as long as the user is not pressing down both a and d keys at the same time. So, in total, your rect will jump as long as the user presses spacebar, or holds down the spacebar while pressing any key on their keyboard, as long as they don’t hold spacebar, a and d keys (all three keys) down at the same time.

This entire issue would be prevented if you ran the jumping code only in the event that spacebar is pressed instead of tracking whether or not spacebar is held down or not.