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.
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.
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.
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?
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.
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.
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.
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.
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.
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).
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.
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.
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?
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.