Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Touch Pressure
Started by hi1 Apr 19 2016 09:22 AM

13 replies to this topic

Best Answer Alex@Panc , 19 April 2016 - 03:17 PM

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.

[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

hi1

[GLOBAL: userInfoPane.html]
hi1
  • Observer

  • 19 posts
  • Corona SDK

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.



[TOPIC: post.html]
#2

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,378 posts
  • Enterprise

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



[TOPIC: post.html]
#3

hi1

[GLOBAL: userInfoPane.html]
hi1
  • Observer

  • 19 posts
  • Corona SDK

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?



[TOPIC: post.html]
#4

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,378 posts
  • Enterprise

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



[TOPIC: post.html]
#5

Michael W.

[GLOBAL: userInfoPane.html]
Michael W.
  • Contributor

  • 276 posts
  • Alumni

I think there is a vibrate plugin in the store that has more features, but I'm pretty sure it's Android only.


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

[TOPIC: post.html]
#6

hi1

[GLOBAL: userInfoPane.html]
hi1
  • Observer

  • 19 posts
  • Corona SDK

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.



[TOPIC: post.html]
#7

Alex@Panc

[GLOBAL: userInfoPane.html]
Alex@Panc
  • Corona Geek

  • 1,731 posts
  • Corona SDK

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.



[TOPIC: post.html]
#8

hi1

[GLOBAL: userInfoPane.html]
hi1
  • Observer

  • 19 posts
  • Corona SDK

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?



[TOPIC: post.html]
#9

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,378 posts
  • Enterprise

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



[TOPIC: post.html]
#10

Alex@Panc

[GLOBAL: userInfoPane.html]
Alex@Panc
  • Corona Geek

  • 1,731 posts
  • Corona SDK

  Best Answer

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.



[TOPIC: post.html]
#11

hi1

[GLOBAL: userInfoPane.html]
hi1
  • Observer

  • 19 posts
  • Corona SDK

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!



[TOPIC: post.html]
#12

Alex@Panc

[GLOBAL: userInfoPane.html]
Alex@Panc
  • Corona Geek

  • 1,731 posts
  • Corona SDK

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



[TOPIC: post.html]
#13

Michael W.

[GLOBAL: userInfoPane.html]
Michael W.
  • Contributor

  • 276 posts
  • Alumni

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.

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.



[TOPIC: post.html]
#14

hi1

[GLOBAL: userInfoPane.html]
hi1
  • Observer

  • 19 posts
  • Corona SDK

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

 

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




[topic_controls]
[/topic_controls]