TAP and TOUCH reaction and priority

Hi all,

I have the following code on my “play” button :

local function launchGame() -- launch my game end playButton:addEventListener("tap", launchGame) playButton:addEventListener("touch", SHAREFCT.clicSound)

SHAREFCT is a lua file containing my shared function named clicSound()

clicSound() do a “clic” sound when you press the button.

Something is strange :

if i click normally (not to speed, not to slowly) on my playButton with my finger in the top right corner (so really far from the middle), the touch function works and i hear a “clic”. BUT the tap function doesn’t work… and i need to refocus my finger towards the middle of the button to, at the same time, hear a clic and launch the game.

How is it possible that a “touch” event is launched when a “tap” event is not, if i just do a “normal” click ?

and this is the same pb for my 20 buttons in all my lua files…

Paste this in main.lua and you will see both events fire just fine

local circle = display.newCircle(display.contentCenterX, display.contentCenterX, 100) local function tapListener(event) print("tap") end local function touchListener(event) print("touch", event.phase) end circle:addEventListener( "tap", tapListener ) circle:addEventListener( "touch", touchListener )

you right !

your test is ok !

but if i test it with an image : a round button , a png file : if i click on the " transparent" part of the button ( in the top right corner ), the touch event is ok but not the tap event !

is it a bug ?

try the same with :

local circle = display.newImageRect( "button.png", 256, 256 )

using a button.png file which is a rounded button with transparent outline… and click the transparent part in the top right corner… only “touch” is printed…

that doesnt make sense, i use a lot of transparent area touches withhout issues.

tap require a release to take action though, touch dont.

Hi @triogical,

Exactly as @anaqim says, a tap requires a touch and release in the same place (within some tiny fraction of drift). You won’t get a tap response if you touch, drag, and then release… mobile devices don’t work that way… in that case you’ll get a touch response.

This tutorial explains the entire thing in more detail:

https://docs.coronalabs.com/tutorial/events/tapTouchAnatomy/index.html

Brent

thanks brent,

thanksfull to you and others, i found the problem.

in my “tap” function, i had the following code :

 display.getCurrentStage():setFocus( nil ) event.target.isFocus = false

but, “touch” is the first function to be loaded (in all case), and then “tap” the second one.

but the 2 below coded lines delete the focus , so “tap” is no more executed.

i just have to delete this 2 lines and it solves the pb.

thanks to all !

hum… but delete theses 2 lines generated other focus pb…

is there a way to make that the “tap” function will not be cancelled by the 2 lines of code below ?

Like I said before don’t mix tap and touch on the same element. Do everything in touch.  You can time the difference between began and ended and if under say 300 ms then treat as tap otherwise treat as touch.

i added a timer and now it really seems to solve the pb :

local function clicSound_before(event)

  timer.performWithDelay(1, function() clicSound(event) end)
 
end

i made little tests, and the “tap” function seems to be never more cancelled !

sgs : the problem if you count 300 ms during began and ended in “touch” event, is that you don’t know if, when the “ended” event is executed, the users has always is pointer above your button or not ?

I think this would all be so much easier solved if you used a widget button instead of your own home-brewed button…

https://docs.coronalabs.com/api/library/widget/newButton.html

Use both the “onPress” and “onRelease” options in the button constructor. In the “onPress” listener function, play your click sound. In the “onRelease” listener function, start the game. Simple and done.

Brent

from what i have noticed, it seems that having both tap and touch on the same object will trigger both if you want or not.

you can handle conditions in code but you cant prevent the event.

i have cases where i need touch to be able to handle drag events for the object while at the same time i need tap on the same object to be able to handle double tap (win32 app).

If you dont have to, using one or the other per object makes life easier.

I agree with Brent.  Use exiting core functionality whenever possible - it saves all this!

To address your question… don’t “set focus” to the button/image and then you will not have this problem.  That is only required if you want to direct touch events to an object when the touch points exist outside the bounds of the object for things like dragging.  

For a simple button implementation setting focus is NOT required and NOT advised.

Paste this in main.lua and you will see both events fire just fine

local circle = display.newCircle(display.contentCenterX, display.contentCenterX, 100) local function tapListener(event) print("tap") end local function touchListener(event) print("touch", event.phase) end circle:addEventListener( "tap", tapListener ) circle:addEventListener( "touch", touchListener )

you right !

your test is ok !

but if i test it with an image : a round button , a png file : if i click on the " transparent" part of the button ( in the top right corner ), the touch event is ok but not the tap event !

is it a bug ?

try the same with :

local circle = display.newImageRect( "button.png", 256, 256 )

using a button.png file which is a rounded button with transparent outline… and click the transparent part in the top right corner… only “touch” is printed…

that doesnt make sense, i use a lot of transparent area touches withhout issues.

tap require a release to take action though, touch dont.

Hi @triogical,

Exactly as @anaqim says, a tap requires a touch and release in the same place (within some tiny fraction of drift). You won’t get a tap response if you touch, drag, and then release… mobile devices don’t work that way… in that case you’ll get a touch response.

This tutorial explains the entire thing in more detail:

https://docs.coronalabs.com/tutorial/events/tapTouchAnatomy/index.html

Brent

thanks brent,

thanksfull to you and others, i found the problem.

in my “tap” function, i had the following code :

 display.getCurrentStage():setFocus( nil ) event.target.isFocus = false

but, “touch” is the first function to be loaded (in all case), and then “tap” the second one.

but the 2 below coded lines delete the focus , so “tap” is no more executed.

i just have to delete this 2 lines and it solves the pb.

thanks to all !