Touch Pressure

Hi,

I am trying to use the event.pressure (https://docs.coronalabs.com/daily/api/event/touch/pressure.html) module, however, am having issues figuring out how it exactly works (as there is no sample code).

Basically, I want to make it so that when more pressure is applied on tap, an object is spawned in the taps position (3d touch on position spawns object).

Here’s my code:

local function onTap(event) if spawnNum \< 3 then if event.pressure == 2.0 then local object = display.newRect( event.x, event.y, 60, 20 ) object:setFillColor( 0, 0, 0 ) spawnNum = spawnNum + 1 end end end Runtime:addEventListener( "tap", onTap )

If anybody has any thoughts as to how to get this to work that’d be great.

Thanks.

The event.pressure value can be any where from 0 to 3 or more but it’s going to be a floating point value, like 0.96384736 or 1.43847. It almost will never be 1.0 exactly or 2.0 exactly. Your test for event pressure will only trigger if the pressure is exactly 2.0. You will need to adapt that if statement to handle ranges, like perhaps:

if event.pressure \>= 2.0 then

But you have another problem that will even prevent that from working.

You’re event listener is setup as a Tap listener. Tap events do not contain touch information. You need to be listing for “touch” events instead. That means your onTap function will also now have to watch for event.phase values for “began”, “ended”, “moved” etc. You won’t get an event.pressure at all with a “tap” event.

Rob

Thank you for the quick reply!  I got it all functioning properly now.

One more question-- does Corona have any way to cause the vibration to occur on the phone like 3D touch normally triggers?

There is a system.vibrate() API call that you can use.  https://docs.coronalabs.com/api/library/system/vibrate.html

But we provide no controls over duration or intensity. I think there is a vibrate plugin in the store that has more features, but I’m pretty sure it’s Android only.

Rob

https://store.coronalabs.com/plugin/vibrator

Hi,

Despite getting the pressure touch working, I have been receiving some issues with events firing.

My goal is to make it so that on each subsequent pressure press, one more physics body is removed.

For example, pressure press 1, removes level1 body, pressure press 2 removes level2 body. The code I have (to my knowledge) has it working in theory, however, it is often triggered multiple times on each touch.

Here’s my code:

local level = 1 local function onTap(event) if event.pressure \>= 2.0 then if level == 9 then physics.removeBody( level9 ) level = level + 1 end if level == 8 then physics.removeBody( level8 ) level = level + 1 end if level == 7 then physics.removeBody( level7 ) level = level + 1 end if level == 6 then physics.removeBody( level6 ) level = level + 1 end if level == 5 then physics.removeBody( level5 ) level = level + 1 end if level == 4 then physics.removeBody( level4 ) level = level + 1 end if level == 3 then physics.removeBody( level3 ) level = level + 1 end if level == 2 then physics.removeBody( level2 ) level = level + 1 end if level == 1 then physics.removeBody( level1 ) level = level + 1 end end end Runtime:addEventListener( "touch", onTap )

Is there a way to make it so that the onTap function is only triggered once per touch event?

Thanks.

I know I’m coming into this thread late, but I see that you are using a touch listener now instead of the tap, but you aren’t listening for the touch phase at any point. Therefore, the touch listener is going to fire for every “began”, “moved” and “ended” phase in that touch listener, which is probably why you are seeing it fire multiple times. Rob references this in his first comment above.

Oh now understand what he was referencing above. The only issue I have found with targeting one of the touch listeners (such as began) is that it does not detect the pressure properly. Sometimes it works (if I apply the pressure very fast), and other times it doesn’t.

Is there any way around this?

If you’re expecting a tap type action (no movement), then it might be best to use the “ended” phase and it might have the max pressure of the touch. I don’t have a pressure sensitive device to know how this works in reality.

Rob

I haven’t worked with event.pressure so I can’t speak to what other folks do/would do, but a simple flag seems like it would be the best way to address this, like you would anything else within a touch listener in this fashion. Something like:

local levelTable = { level1, level2, level3, level4, level5, level6, level7, level8, level9, } local level = 1 local levelOn = 1 local canDetectPressure = true local function handlePressureRemoval(set) if set == 1 then if level \< 10 then canDetectPressure = false physics.removeBody( levelTable[level] ) level = level + 1 end elseif set == 2 then end end local function detectTouchPressure(event) if ((event.phase ~= "ended") and canDetectPressure then if event.pressure \>= 2.0 then handlePressureRemoval(1) return true end end if (event.phase == "ended") and not canDetectPressure then handlePressureRemoval(2) return true end end Runtime:addEventListener("touch",detectTouchPressure ) 

Untested as I don’t have a device that detects pressure at my disposal right now, but I believe that’s the basic gist. The above assumes that you have declared your physics bodies above this touch function.

EDIT: Updating to add a comment that I agree with Rob, in that I have zero idea where a event.pressure event is triggered in a touch listener. I assume it’s phase independent, as you referenced your listener conditions above being fired several times throughout your physical touch. This is all hypothesis on my part though.

Hey Alex,

Thank you very much for providing this!

After some small modifications, I got your code working flawlessly on my device. In case other users want to use this, I basically just added the following inside the handlePressureRemoval event.

elseif set == 2 then canDetectPressure = true end

Thanks!

That’s what I get for not taking my time! Glad you got it working!

event.pressure isn’t so much an event, and isn’t “triggered”. It’s just data you get alongside your touch event x/y/phase/etc if the device supports it. You are right, it’s phase-independent.

Hi Alex,

I had a quick question you (or anybody else) could help me out on.  Right now I have the 3d touch working flawlessly (with the code above), however, I would like to trigger a function once if the pressure is not fully applied (grater than or equal to 2.0).

Basically, so that if a normal touch is released, a function is triggered once, whereas if a 3D touch occurs, a second function is triggered once (which works in the code above in this thread).

Thanks

The event.pressure value can be any where from 0 to 3 or more but it’s going to be a floating point value, like 0.96384736 or 1.43847. It almost will never be 1.0 exactly or 2.0 exactly. Your test for event pressure will only trigger if the pressure is exactly 2.0. You will need to adapt that if statement to handle ranges, like perhaps:

if event.pressure \>= 2.0 then

But you have another problem that will even prevent that from working.

You’re event listener is setup as a Tap listener. Tap events do not contain touch information. You need to be listing for “touch” events instead. That means your onTap function will also now have to watch for event.phase values for “began”, “ended”, “moved” etc. You won’t get an event.pressure at all with a “tap” event.

Rob

Thank you for the quick reply!  I got it all functioning properly now.

One more question-- does Corona have any way to cause the vibration to occur on the phone like 3D touch normally triggers?

There is a system.vibrate() API call that you can use.  https://docs.coronalabs.com/api/library/system/vibrate.html

But we provide no controls over duration or intensity. I think there is a vibrate plugin in the store that has more features, but I’m pretty sure it’s Android only.

Rob

https://store.coronalabs.com/plugin/vibrator

Hi,

Despite getting the pressure touch working, I have been receiving some issues with events firing.

My goal is to make it so that on each subsequent pressure press, one more physics body is removed.

For example, pressure press 1, removes level1 body, pressure press 2 removes level2 body. The code I have (to my knowledge) has it working in theory, however, it is often triggered multiple times on each touch.

Here’s my code:

local level = 1 local function onTap(event) if event.pressure \>= 2.0 then if level == 9 then physics.removeBody( level9 ) level = level + 1 end if level == 8 then physics.removeBody( level8 ) level = level + 1 end if level == 7 then physics.removeBody( level7 ) level = level + 1 end if level == 6 then physics.removeBody( level6 ) level = level + 1 end if level == 5 then physics.removeBody( level5 ) level = level + 1 end if level == 4 then physics.removeBody( level4 ) level = level + 1 end if level == 3 then physics.removeBody( level3 ) level = level + 1 end if level == 2 then physics.removeBody( level2 ) level = level + 1 end if level == 1 then physics.removeBody( level1 ) level = level + 1 end end end Runtime:addEventListener( "touch", onTap )

Is there a way to make it so that the onTap function is only triggered once per touch event?

Thanks.

I know I’m coming into this thread late, but I see that you are using a touch listener now instead of the tap, but you aren’t listening for the touch phase at any point. Therefore, the touch listener is going to fire for every “began”, “moved” and “ended” phase in that touch listener, which is probably why you are seeing it fire multiple times. Rob references this in his first comment above.