How to detect multiple key inputs and apply "jump" into object controller?

Hi, my project is 95% done, unfortunately the following final problem is the most important one. Please generously help.

My game contains two players, let’s define them as “player 1” and “player 2”. In my coding, I used key.event function to detect what key is pressed on a real keyboard, then I used an enterFrame event function to control based on the key pressed.

The problem is:

(1) When one of the keys designed to control player 1, let’s say “left” key to control player 1 to move left, is pressed, all of the keys designed to control player 2, e.g. “a” key to control player 2 to move left, cannot be detected. I think it’s because the game can’t detect multiple key inputs, so when any one of the keys is pressed, all other keys can’t be used.

(2) I want to make both player 1 and player 2 able to jump, it’s like when I press “left” and “up” on keyboard at the same time, player 1 will jump to the left, and when I press “d” and “w” at the same time, player 2 will jump to the right.

The following is the related code so far:

function player1Control(event) if (event.phase == "up") then direction = "noMove" elseif (event.keyName == "left" and event.phase == "down") then direction = event.keyName elseif (event.keyName == "right" and event.phase == "down") then direction = event.keyName elseif (event.keyName == "up" and event.phase == "down") then direction = event.keyName end end function player2Control(event) if (event.phase == "up") then direction = "noMove" elseif (event.keyName == "a" and event.phase == "down") then direction = event.keyName elseif (event.keyName == "d" and event.phase == "down") then direction = event.keyName elseif (event.keyName == "w" and event.phase == "down") then direction = event.keyName end end function player1Update() if direction == "left" then player1.x = player1.x - moveSpeed \* 2 elseif direction == "right" then player1.x = player1.x + moveSpeed \* 2 elseif direction == "up" then player1.y = player1.y - moveSpeed \* 5 end end function player2Update() if direction == "a" then player2.x = player2.x - moveSpeed \* 2 elseif direction == "d" then player2.x = player2.x + moveSpeed \* 2 elseif direction == "w" then player2.y = player2.y - moveSpeed \* 5 end end Runtime:addEventListener("key", player1Control) Runtime:addEventListener("enterFrame", player1Update) Runtime:addEventListener("key", player2Control) Runtime:addEventListener("enterFrame", player2Update)
1 Like

You’re using the same variable, direction, for both players. I think that’s the cause of your problem. You need a separate variable for each player.

1 Like

OMG! I was so stupid to find that! Thank you very much hasty!

The first problem is solved. However, I am still stuck in solving the second problem about jumping.

1 Like

hasty, unfortunately I found another problem with my first problem.

After assigning different variables to player 1 and player 2 respectively, I found that sometimes the key pressed doesn’t work.

The situation happened (for example) when I press “left” to control player 1 to go left, and I hold “left” key pressed; meanwhile, I press “a” to control player 2 to go left, but I don’t hold “a” key pressed; then when I try to press “a” or “d” to control player 2 again, the key “left” which I have pressed and held no longer work, player 1 stops moving. How come would this happen?

Thank you.

Both your playerControl functions are triggered with each key event. When you lift up “left”, for example, both player1Control() and player2Control() are called. Since the phase is “up”, both directions are set to “noMove”. I would recommend that you use just one playerControl function and one playerUpdate function. With the playerControl function you can keep track of what keys are pressed down (perhaps in a table if you’re comfortable with keys/values), and with the playerUpdate function you can act on it accordingly.

As for jumping, that depends. Are you using the physics engine or not? That will make a big difference in how you proceed. Perhaps show more code?

1 Like

Thank you hasty.

Yes, I am using physics engine (using Physics Based Game template). Actually the above shown codes are all the related code which I wish to achieve jumping.

Like player1Update()

function player1Update() if direction == "left" then player1.x = player1.x - moveSpeed \* 2 elseif direction == "right" then player1.x = player1.x + moveSpeed \* 2 elseif direction == "up" then player1.y = player1.y - moveSpeed \* 5 end end

“elseif direction == “up” then player1.y = player1.y - moveSpeed * 5”

I thought this code would help achieving jumping…

Besides, I merged the control and update functions into one playerControl function and one playerUpdate function respectively like below:

function playerUpdate() if player1direction == "left" then player1.x = player1.x - player1Speed \* 2 elseif player1direction == "right" then player1.x = player1.x + player1Speed \* 2 elseif player1direction == "up" then player1.y = player1.y - player1Speed \* 5 end if player2direction == "a" then player2.x = player2.x - player2Speed \* 2 elseif player2direction == "d" then player2.x = player2.x + player2Speed \* 2 elseif player2direction == "w" then player2.y = player2.y - player2Speed \* 5 end if (player2.x \<= 0) then player2.x = 0 elseif (player2.x \>= display.contentWidth) then player2.x = display.contentWidth end player2.y = player2.y + player2Speed/4 if (player1.x \<= 0) then player1.x = 0 elseif (player1.x \>= display.contentWidth) then player1.x = display.contentWidth end player1.y = player1.y + player1Speed/4 end function playerControl(event) if (event.phase == "up") then player2direction = "noMove" player1direction = "noMove" elseif (event.keyName == "left" and event.phase == "down") then player1direction = event.keyName end if (event.phase == "up") then player2direction = "noMove" player1direction = "noMove" elseif (event.keyName == "a" and event.phase == "down") then player2direction = event.keyName end if (event.phase == "up") then player2direction = "noMove" player1direction = "noMove" elseif (event.keyName == "right" and event.phase == "down") then player1direction = event.keyName end if (event.phase == "up") then player2direction = "noMove" player1direction = "noMove" elseif (event.keyName == "d" and event.phase == "down") then player2direction = event.keyName end if (event.phase == "up") then player2direction = "noMove" player1direction = "noMove" elseif (event.keyName == "up" and event.phase == "down") then player1direction = event.keyName end if (event.phase == "up") then player2direction = "noMove" player1direction = "noMove" elseif (event.keyName == "w" and event.phase == "down") then player2direction = event.keyName end end

however, the control problem still occurred. Would you please help check my code? Thank you!

1 Like

In your playerControl function, whenever any key is lifted up, you’re setting both players direction to “noMove”.  That’s why the problem persists. Here’s an example of how I might approach something like this, though it’s not exactly what you are trying to do, but might give you some ideas:

 

[DELETED CODE: SEE NEXT COMMENT]

 

However, if you’re using the physics engine, you shouldn’t be moving things around like this. You should probably be using methods like setLinearVelocity and applyLinearImpulse. (Though I haven’t used physics in quite some time, I might be mistaken about the best way to use it.)

1 Like

Sorry, the edit feature seems to be bugging out on me. I’ll try to post the code again here.

local player1, player2 = display.newCircle(50, 150, 5), display.newCircle(100, 150, 5) local player1Direction, player2Direction = "noMove", "noMove" local moveSpeed = 1 local keyDownList = {} function keyHandler(event) if event.phase == "up" then keyDownList[event.keyName] = false elseif event.phase == "down" then keyDownList[event.keyName] = true end end function playerUpdate() if keyDownList["left"] then player1.x = player1.x - moveSpeed end if keyDownList["right"] then player1.x = player1.x + moveSpeed end if keyDownList["up"] then player1.y = player1.y - moveSpeed end if keyDownList["down"] then player1.y = player1.y + moveSpeed end if keyDownList["a"] then player2.x = player2.x - moveSpeed end if keyDownList["d"] then player2.x = player2.x + moveSpeed end if keyDownList["w"] then player2.y = player2.y - moveSpeed end if keyDownList["s"] then player2.y = player2.y + moveSpeed end end Runtime:addEventListener("key", keyHandler) Runtime:addEventListener("enterFrame", playerUpdate)
1 Like

O! M! G! You saved my life! The code you provided not just fixes the problem I mentioned, it helps me achieve jumping!!!

by the way sorry for late reply, I was taking a nap, it’s 06:43 in the morning in Hong Kong.

I know I should apply velocity or impulse, however I am too new and unfamiliar with Lua, searched and read many posts online but still don’t figure out how to use velocity and impulse correctly.

Anyway, I will study and try more to enhance my coding skills, thank you so much hasty!!!

1 Like

You’re welcome. No need to apologise. Best of luck with your learning.

1 Like