Multitouch problems

I am making a game that uses buttons to move the player left and right and a button that makes the player jump. I am running into problems when I attempt to press the jump button while moving left or right. I have activated multitouch and am using the setFocus() function with the optional event.id parameter. I am using build 2393a and this happens on my 4th gen iPod touch and iPhone 5.

Several other things that may help find the problem:

  • It was working fine until I changed the config.lua file to change the display size depending on the device. 

  • The jump arrow touch listener does not run at all when the problem occurs.

  • At some point (I haven’t figured out what causes it) the problem stops and the touch system works fine until I restart the program.

  • Here is the code for the touch arrows:

    –multitouch must be activated system.activate(“multitouch”) --left arrow button leftArrow = display.newImage(“Tiles/Arrow.png”, 100, display.contentHeight-70) leftArrow:setFillColor(1, 0.4) leftArrow.rotation = 180 leftArrow.touch = function(self, event) --if button is pressed, move left if event.phase == “began” then --if there is a touch move left display.getCurrentStage():setFocus(self, event.id) player.vx = -200 elseif event.phase == “ended” or event.phase == “canceled” then --if it is released stop display.getCurrentStage():setFocus(nil) player.vx = 0 end end leftArrow:addEventListener(“touch”, leftArrow) --right arrow button rightArrow = display.newImage(“Tiles/Arrow.png”, 250, display.contentHeight - 70) rightArrow:setFillColor(1, 0.4) rightArrow.touch = function(self, event) --if button is pressed, move right if event.phase == “began” then --if there is a touch move right display.getCurrentStage():setFocus(self, event.id) player.vx = 200 elseif event.phase == “ended” or event.phase == “canceled” then --if it is released stop display.getCurrentStage():setFocus(nil) player.vx = 0 end end rightArrow:addEventListener(“touch”, rightArrow) --up arrow button upArrow = display.newImage(“Tiles/Arrow.png”, display.contentWidth - 150, display.contentHeight - 70) upArrow:setFillColor(1, 0.4) upArrow.rotation = 270 upArrow.touch = function(self, event) --if button is pressed, jump and stop further jumping if not player.isAlive or levelComplete then --if the game is not active, cancel function (this is not the problem, I have tested it) return end print(“jumping”, player.onGround) if player.onGround > 0 and not player.isJumping then --if player is on the ground player.gravityScale = 1 player:setLinearVelocity(select(1, player:getLinearVelocity()), 0) player:applyForce(0, -950, player.x, player.y) --apply jumping force player.isJumping = true end end upArrow:addEventListener(“touch”, upArrow)

  • My only ideas are that the system.activate(“multitouch”) function is not running until the problem stops later in the program or that this is a bug with Corona because I updated to build 2393a while trying to solve the problem.

If you have any ideas on how I can solve the problem please let me know!

In your touch functions, try adding:

re

return true

after the if statements (at the bottom of the function.  

It could be that you have another touchable object behind your buttons, and they are “stealing” the touch event.

No, that didn’t fix it. I added the return true line at the end of the touch listeners and there is nothing that listens for touch events behind the arrows but it still doesn’t work.

Hello Ian,

The first thing I suggest is the you don’t name your touch listener target functions the exact same thing as your objects. This could be causing some serious conflict in Lua. Meaning, you have an object “leftArrow” and then its own touch listener points to “leftArrow” as well, which is (I assume) a function that is named the same as the object? 

Best regards,

Brent

Oh, never mind my first response… I see what you’re doing with that part. What changes did you make to config.lua when it stopped working? Can you post the contents of that file please?

Brent

I changed config.lua to change the size of the stage depending on the device. 

Here is the code:

if string.sub(system.getInfo("model"), 1, 4) == "iPad" then application = { content = { width = 768, height = 1024, scale = "letterbox", fps = 60, imageSuffix = { ["@2x"] = 2, ["@15x"] = 1.5, } } } elseif string.sub(system.getInfo("model"), 1, 2) == "iP" and display.pixelHeight \> 960 then application = { content = { width = 640, height = 1136, scale = "letterbox", fps = 60, imageSuffix = { ["@2x"] = 2, ["@15x"] = 1.5, } } } elseif string.sub(system.getInfo("model"), 1, 2) == "iP" then application = { content = { width = 640, height = 960, scale = "letterbox", fps = 60, imageSuffix = { ["@2x"] = 2, ["@15x"] = 1.5, } } } elseif display.pixelHeight / display.pixelWidth \> 1.72 then application = { content = { width = 640, height = 1140, scale = "letterbox", fps = 60, imageSuffix = { ["@2x"] = 2, ["@15x"] = 1.5, } } } else application = { content = { width = 640, height = 960, scale = "letterbox", fps = 60, imageSuffix = { ["@2x"] = 2, ["@15x"] = 1.5, } } } end

I cannot find any reason that this would change how the touch detection works but everything was working fine before I did this. 

I have figured out that the problem does not involve the setFocus() function. The problem persists even when I remove the setFocus() function entirely.

The one idea I have on the cause of the problem is that the system.activate(“multitouch”) function is taking a long time to execute but is allowing the code after it to execute (possibly by executing in a seperate thread). My reasoning behind this is that the problem disappears, seemingly randomly, at some point in the game. Does anybody know if the system.activate() function allows the code after it to run before it finishes? Also is there a way to test whether or not this is the problem?

You upArrow.touch listener will get called twice for every touch since you are not checking event.phase. Not sure if this is causing your existing problem but it seems like it could depending on how long the finger is left on the button.

That was not the problem (although I am surprised that didn’t cause some kind of problem). I think that I have fixed the problem by moving the system.activate(“multitouch”) to main.lua rather than right before the touch listeners are declared. 

well just add the system.activate(“multitouch”) to the top of your lua file. Its a bad idea to add it in the main.lua file because there are scenes that are not meant to handle multitouch event. (e.i. in the menu). Rule of thumb: just add it where you need it and disable it when you are done using it. Hope it helps.

Jam

In your touch functions, try adding:

re

return true

after the if statements (at the bottom of the function.  

It could be that you have another touchable object behind your buttons, and they are “stealing” the touch event.

No, that didn’t fix it. I added the return true line at the end of the touch listeners and there is nothing that listens for touch events behind the arrows but it still doesn’t work.

Hello Ian,

The first thing I suggest is the you don’t name your touch listener target functions the exact same thing as your objects. This could be causing some serious conflict in Lua. Meaning, you have an object “leftArrow” and then its own touch listener points to “leftArrow” as well, which is (I assume) a function that is named the same as the object? 

Best regards,

Brent

Oh, never mind my first response… I see what you’re doing with that part. What changes did you make to config.lua when it stopped working? Can you post the contents of that file please?

Brent

I changed config.lua to change the size of the stage depending on the device. 

Here is the code:

if string.sub(system.getInfo("model"), 1, 4) == "iPad" then application = { content = { width = 768, height = 1024, scale = "letterbox", fps = 60, imageSuffix = { ["@2x"] = 2, ["@15x"] = 1.5, } } } elseif string.sub(system.getInfo("model"), 1, 2) == "iP" and display.pixelHeight \> 960 then application = { content = { width = 640, height = 1136, scale = "letterbox", fps = 60, imageSuffix = { ["@2x"] = 2, ["@15x"] = 1.5, } } } elseif string.sub(system.getInfo("model"), 1, 2) == "iP" then application = { content = { width = 640, height = 960, scale = "letterbox", fps = 60, imageSuffix = { ["@2x"] = 2, ["@15x"] = 1.5, } } } elseif display.pixelHeight / display.pixelWidth \> 1.72 then application = { content = { width = 640, height = 1140, scale = "letterbox", fps = 60, imageSuffix = { ["@2x"] = 2, ["@15x"] = 1.5, } } } else application = { content = { width = 640, height = 960, scale = "letterbox", fps = 60, imageSuffix = { ["@2x"] = 2, ["@15x"] = 1.5, } } } end

I cannot find any reason that this would change how the touch detection works but everything was working fine before I did this. 

I have figured out that the problem does not involve the setFocus() function. The problem persists even when I remove the setFocus() function entirely.

The one idea I have on the cause of the problem is that the system.activate(“multitouch”) function is taking a long time to execute but is allowing the code after it to execute (possibly by executing in a seperate thread). My reasoning behind this is that the problem disappears, seemingly randomly, at some point in the game. Does anybody know if the system.activate() function allows the code after it to run before it finishes? Also is there a way to test whether or not this is the problem?

You upArrow.touch listener will get called twice for every touch since you are not checking event.phase. Not sure if this is causing your existing problem but it seems like it could depending on how long the finger is left on the button.

That was not the problem (although I am surprised that didn’t cause some kind of problem). I think that I have fixed the problem by moving the system.activate(“multitouch”) to main.lua rather than right before the touch listeners are declared. 

well just add the system.activate(“multitouch”) to the top of your lua file. Its a bad idea to add it in the main.lua file because there are scenes that are not meant to handle multitouch event. (e.i. in the menu). Rule of thumb: just add it where you need it and disable it when you are done using it. Hope it helps.

Jam