Determining if finger is within an object's content bounds

Hello everyone. This is a modified continuation of my last post, except I cut out everything extra and made everything much simpler.

Here is my code.

display.setStatusBar( display.HiddenStatusBar ) --Create button local button = display.newCircle(320,900, 150) button:setFillColor(255,0,0 ) --Do this when button is clicked local function buttonClick() button:setFillColor(55,10,0 ) transition.to( button, { time=1500, x=x, y=button.y - 700} ) end --Do this when button is released local function buttonRelease() button:setFillColor(255,0,0 ) end --Run this when button is clicked local function buttonPressed(e) if e.phase == "began" then buttonClick() elseif e.phase == "moved" then --If your finger's coordinates are outside of the buttons, trigger release --Content bounds DONT change... fix needed --print(e.target.contentBounds.xMin) if e.x \< e.target.contentBounds.xMin or e.x \> e.target.contentBounds.xMax or e.y \< e.target.contentBounds.yMin or e.y \> e.target.contentBounds.yMax then print("Its out") e.phase = "offTarget" e.target:dispatchEvent(e) end elseif e.phase == "offTarget" then buttonRelease() print("It ran off the button") elseif e.phase == "ended" then buttonRelease() print("It ended") elseif e.phase == "cancelled" then buttonRelease() print("It canceled") end end button:addEventListener("touch",buttonPressed)

What I want to happen–

When the user presses the button, buttonClick is executed. Then when the user either lets go of the object or moves off of the object, then buttonRelease is executed. 

What is actually happening–

Everything works, except for finger moved off of code (courtesy of jstrahan). In concept everything should work, however it doesn’t. 

Can anyone help me with this?

–On a side note when the object is moving the contentBounds stay the same. I need help with this too.

Thanks!

Summit Tech

the issue is using transition.to doesn’t update the x,y position of the object. the objects x,y remain the at the original position. to correct either move object manually or add an onComplete function to the transition.to that sets the objects x,y to the new location

Thanks for the reply. For the first method the only problem with manually moving the object is moving it randomly and at diagonals. And the problem with updating the position after is when trying to detect if your finger is on the object when it is moving.

Also, any way to get the offTarget code working?

Thanks

there shouldn’t be any reason you couldn’t do manually. May require a more math and calculations but very doable

True enough. I will get started on that ASAP. As for the off target, any help with that?

the offTarget code works. I use it in some of my own code to detect when your no longer touching an object. but it does require the correct x,y object values which transition.to doesn’t supply. if I remember correctly a year or two ago you could read the x,y during a transition, seems like I did it in an app but I may be wrong it’s been a while

heres a way that may work for you

create a variable, local currentObject

then in the touch event in the began phase set currentObject = e.target

then setup a runtime event like this

Runtime:addEventListener( "touch", function(e) &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; if e.x \< currentObject.contentBounds.xMin or &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; e.x \> currentObject.contentBounds.xMax or &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; e.y \< currentObject.contentBounds.yMin or &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; e.y \> currentObject.contentBounds.yMax then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; print("Its out") &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; end end)

now this doesnt work if they keep their finger still

Thanks a lot! Will give this a test tomorrow and see how it goes.

Update: Code worked perfectly! Problem is solved!

Thanks for the tremendous help jstrahan.

welcome

Quick little update.

I am now trying to test inside of a circle. Using the code you gave me allows for the user to touch slightly outside of the circle in the corners of the circle (its better suited for rectangles). I tried to make my own code, and I can’t say I have had much success. Instead of being able to go slightly outside of the circle without displaying “Its Out”(your code makes an inscribed square ), my code displays “Its Out” even if the user is still in the circle.

Here is the code.

Runtime:addEventListener( "touch", function(e) print(math.abs(e.x-button.x)+math.abs(e.y-button.y)) -- note that radius was created outside of this function and is value is 150 if math.abs(e.x-button.x)+math.abs(e.y-button.y) \>= radius then print("Its out") buttonRelease() end end)&nbsp;

Thanks for any help or suggestions!

Runtime:addEventListener( "touch", function(e) -- note that radius was created outside of this function and is value is 150 local dX = e.x-button.x; local dY = e.y-button.y; local distance = math.sqrt(dX\*dX+dY\*dY); print(distance, radius); if distance \>= radius then print("Its out") buttonRelease() end end)

This should work (;

Thanks man, code worked like a charm!

it more efficient to use

if radius\*radius \> dx\*dx + dy\*dy then

then to use math.sqrt

Hey one quick follow up question. When the player’s finger touches the object to start the movement but does not move their finger at all, the runtime event listener will not function until the player moves their their finger.

Is there any possible workaround to this issue? Possibly having another event listener that checks for player movement at the beginning of the game? 

local circle = display.newCircle( 160, 240, 50 ) local radius = circle.contentWidth/2 local function move() &nbsp; circle.x = (circle.x + 0.5)%640 end circle:addEventListener( "touch", function(e) &nbsp; if e.phase == "began" then &nbsp;&nbsp;&nbsp; myTimer = timer.performWithDelay( 100, function() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local dX = e.x-circle.x; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local dY = e.y-circle.y; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (radius\*radius)\<((dX\*dX)+(dY\*dY)) then &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print("Its out") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timer.cancel( myTimer ) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print("checking", e.x,e.y,circle.x,circle.y) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end &nbsp;&nbsp;&nbsp; end,0) &nbsp; end &nbsp; if e.phase == "ended" or e.phase == "cancelled" then &nbsp;&nbsp;&nbsp; timer.cancel( myTimer ) &nbsp; end end) Runtime:addEventListener("enterFrame", move)

Ok, so the reason that I even wanted to use the contentBounds method to check when the touch has moved off of an object was because the rectangle method wasn’t flawless…actually if the touch moves over that background rectangle/ object fast enough, that object will not recieve the moved phase.

So, here I tried out some more things, and this has worked:

function button:touch(event) if(event.phase == "began") then if(event.target == button) then print("holding the button") end elseif(event.phase == "moved") then if(event.x \< button.contentBounds.xMin) or (event.x \> button.contentBounds.xMax) or (event.y \< button.contentBounds.yMin) or (event.y \> button.contentBounds.yMax) then print("touch has moved off of the button") end elseif(event.phase == "ended") then if(event.target == button)then print("not holding the button") end end end button:addEventListener("touch", button) Runtime:addEventListener("touch", button)

You can see that button as well as runtime both have an event listener.

Button must have an event listener, so that you can check whether the touch is on the button or not.

Runtime must have an event listener, because when the touch has moved off of the button’s content bounds, the button can no longer detect it.

This way, you can detect where the touch has began, where it has ended, and you can detect if it has moved anywhere on the screen. If you can check these 3 things, you can program the buttons/ controls for your game to work like actual buttons.

This is so far overall the best option for controls in my game, it’s more dependable than the rectangle method.

As for dispatchEvent…nope I still don’t get it, not that it’s really important atm. I’ll need to see it in action and see exactly what it does, but there’s no hurry.

One more thing- erhm…this post was meant for the other topic (Detecting finger dragged off of moving object). I had both topics open in my browser and I accidentaly posted it here, but the posts are related so…

jstrahan- The code worked but now the event x any y coordinates are not updating. I have been playing with the code for a couple hours nows but have had no luck fixing this. Any advice?

local currentX, currentY = 0, 0; Runtime:addEventListener( "touch", function(e) currentX, currentY = e.x, e.y; end) Runtime:addEventListener("enterFrame", function() local dX = currentX-circle.x; local dY = currentY-circle.y; if (dX\*dX+dY\*dY) \> (radius\*radius) then print("Touch is out of circle"); else print("Touch is inside of circle"); end end);

This one should work (:

Thanks a million! I think I have FINALLY solved the issue once and for all.

Cheers to everyone who helped out!