onKeyEvent and multiple key presses in simulator (Windows)

I’m working on a platformer for Android devices and I’m using the built in simulator.  My development environment is Windows.

In my UI module I have “on screen” controls, that seem to work great.  I can’t test multi-touch (or I don’t know how to simulate multi-touch).

For ease, I added an “onKeyEvent”.

The arrow keys on the keyboard move the player character.  Clicking the jump “button” while moving is seamless.  You move AND jump.

Using the arrow keys on the keyboard to move AND using the space bar to jump clunks out.  You move OR jump.

There has to be a way to seamless response, I’m just having a gnarly brain block and don’t know the right phrase to search for an answer, or I’ve gotten so excited things are working out so well that the obvious is escaping me and I’ve gotten a little lazy.

Here is my “onKeyEvent” function:

local function onKeyEvent(event) local eventPhase = event.phase local nameOfKey = event.keyName local debugString = "Idle" if (eventPhase == "down") then if nameOfKey == "up" then setMovement( 0, -1 ) debugString = "Up" elseif nameOfKey == "down" then setMovement( 0, 1 ) debugString = "Down" elseif nameOfKey == "left" then setMovement( -1, 0 ) debugString = "Left" elseif nameOfKey == "right" then setMovement( 1, 0 ) debugString = "Right" end elseif (eventPhase == "up") then if nameOfKey == "up" or nameOfKey == "down" then setMovement( nil, 0 ) elseif nameOfKey == "left" or nameOfKey == "right"then setMovement( 0, nil ) else setMovement( 0, 0 ) end end if showDebugData == true then data\_dPadText.text = debugString end if nameOfKey == "space" then if (eventPhase == "down") then Runtime:dispatchEvent({name = jumpEvent, target=uiTarget, true}) if showDebugData == true then data\_jumpButtonText.text = "On" end else if showDebugData == true then data\_jumpButtonText.text = "Off" end end end -- If the "back" key was pressed on Android or Windows Phone, prevent it from backing out of the app if ( event.keyName == "back" ) then local platformName = system.getInfo( "platformName" ) if ( platformName == "Android" ) or ( platformName == "WinPhone" ) then return true end end -- IMPORTANT! Return false to indicate that this app is NOT overriding the received key -- This lets the operating system execute its default handling of the key return false end

and the “setMovement” function called from the onKeyEvent and the onTouchEvent:

local function setMovement( x, y ) local updatedMovement = false if movement\_X ~= x and x ~= nil then -- Horizontal movement checks movement\_X = x updatedMovement = true end if movement\_Y ~= y and y ~= nil then -- Vertical movement checks movement\_Y = y updatedMovement = true end if not updatedMovement then -- Since key events can fire multiple times with the same values, just return if nothing is actually changing. return end if movement\_X ~= 0 then -- If the player is moving along X - determine direction. if movement\_X \> 0 then Runtime:dispatchEvent({name = rightEvent, target=uiTarget, true}) else Runtime:dispatchEvent({name = leftEvent, target=uiTarget, true}) end end if movement\_Y ~= 0 then -- If the player is moving along Y - determine direction. if movement\_Y \> 0 then Runtime:dispatchEvent({name = downEvent, target=uiTarget, true}) else Runtime:dispatchEvent({name = upEvent, target=uiTarget, true}) end end if movement\_X == 0 then -- If the player is not moving along X - reset left and right. Runtime:dispatchEvent({name = leftEvent, target=uiTarget, false}) Runtime:dispatchEvent({name = rightEvent, target=uiTarget, false}) end if movement\_Y == 0 then -- If the player is not moving along Y - reset up and down. Runtime:dispatchEvent({name = upEvent, target=uiTarget, false}) Runtime:dispatchEvent({name = downEvent, target=uiTarget, false}) end end

Anything obvious I’m just missing?

… elseif (eventPhase == “up”) then … else setMovement( 0, 0 )

that says “if ANY other key (including space) is released then reset movement”, which is presumably killing your jump.  (test:  releasing any other “random” key also ought to kill all movement)  i think the “confusion” is that the first set of tests is by phase, and the second set by keyName, so there is potential overlap - try structuring them all under a single logic, might resolve the problem.

fwiw, what i tend to do is decouple ui events from game objects.  for simulator keys i do something like:

-- let's say you have an "app" (or "system", or whatever) class to hold this stuff app = {} -- then.. app.keyStates = {} app.key = function(self, event) -- (could filter subset of keys, not shown here) self.keyStates[event.keyName] = (event.phase=="down") end Runtime:addEventListener("key", app)

that will give you your “multitouch” key states, which you could later/elsewhere “inspect” by your player and/or its controller, fe…

movement\_X = (app.keyStates.left and -1 or 0) + (app.keyStates.right and 1 or 0)

I feel so ashamed…  Thanks Dave…  I’m going to go flog myself, then crucify myself on the tree of Woe…  I see it now.  :/

… elseif (eventPhase == “up”) then … else setMovement( 0, 0 )

that says “if ANY other key (including space) is released then reset movement”, which is presumably killing your jump.  (test:  releasing any other “random” key also ought to kill all movement)  i think the “confusion” is that the first set of tests is by phase, and the second set by keyName, so there is potential overlap - try structuring them all under a single logic, might resolve the problem.

fwiw, what i tend to do is decouple ui events from game objects.  for simulator keys i do something like:

-- let's say you have an "app" (or "system", or whatever) class to hold this stuff app = {} -- then.. app.keyStates = {} app.key = function(self, event) -- (could filter subset of keys, not shown here) self.keyStates[event.keyName] = (event.phase=="down") end Runtime:addEventListener("key", app)

that will give you your “multitouch” key states, which you could later/elsewhere “inspect” by your player and/or its controller, fe…

movement\_X = (app.keyStates.left and -1 or 0) + (app.keyStates.right and 1 or 0)

I feel so ashamed…  Thanks Dave…  I’m going to go flog myself, then crucify myself on the tree of Woe…  I see it now.  :/