Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Determining if finger is within an object's content bounds
Started by Summit Tech Jan 22 2014 11:37 AM

19 replies to this topic
touch event phase moved button
[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

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



[TOPIC: post.html]
#2

jstrahan

[GLOBAL: userInfoPane.html]
jstrahan
  • Pro
  • PipPipPipPipPipPip
  • 1,922 posts
  • Jedi

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

[TOPIC: post.html]
#3

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

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

[TOPIC: post.html]
#4

jstrahan

[GLOBAL: userInfoPane.html]
jstrahan
  • Pro
  • PipPipPipPipPipPip
  • 1,922 posts
  • Jedi

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

[TOPIC: post.html]
#5

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

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

[TOPIC: post.html]
#6

jstrahan

[GLOBAL: userInfoPane.html]
jstrahan
  • Pro
  • PipPipPipPipPipPip
  • 1,922 posts
  • Jedi

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

[TOPIC: post.html]
#7

jstrahan

[GLOBAL: userInfoPane.html]
jstrahan
  • Pro
  • PipPipPipPipPipPip
  • 1,922 posts
  • Jedi

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)
             if e.x < currentObject.contentBounds.xMin or
                e.x > currentObject.contentBounds.xMax or
                e.y < currentObject.contentBounds.yMin or
                e.y > currentObject.contentBounds.yMax then
                print("Its out")
             end
end)

now this doesnt work if they keep their finger still



[TOPIC: post.html]
#8

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

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

[TOPIC: post.html]
#9

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

Update: Code worked perfectly! Problem is solved!

Thanks for the tremendous help jstrahan.



[TOPIC: post.html]
#10

jstrahan

[GLOBAL: userInfoPane.html]
jstrahan
  • Pro
  • PipPipPipPipPipPip
  • 1,922 posts
  • Jedi


[TOPIC: post.html]
#11

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

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) 

 

Thanks for any help or suggestions!



[TOPIC: post.html]
#12

RagdogStudios

[GLOBAL: userInfoPane.html]
RagdogStudios
  • Starter
  • PipPipPipPipPipPip
  • 104 posts
  • Jedi

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 (;



[TOPIC: post.html]
#13

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

Thanks man, code worked like a charm!



[TOPIC: post.html]
#14

jstrahan

[GLOBAL: userInfoPane.html]
jstrahan
  • Pro
  • PipPipPipPipPipPip
  • 1,922 posts
  • Jedi

it more efficient to use
if radius*radius > dx*dx + dy*dy then
then to use math.sqrt

[TOPIC: post.html]
#15

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

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? 



[TOPIC: post.html]
#16

jstrahan

[GLOBAL: userInfoPane.html]
jstrahan
  • Pro
  • PipPipPipPipPipPip
  • 1,922 posts
  • Jedi

local circle = display.newCircle( 160, 240, 50 )
local radius = circle.contentWidth/2
local function move()
  circle.x = (circle.x + 0.5)%640
end

circle:addEventListener( "touch", function(e)
  if e.phase == "began" then
    myTimer = timer.performWithDelay( 100, function()
      local dX = e.x-circle.x;
      local dY = e.y-circle.y;
      if (radius*radius)<((dX*dX)+(dY*dY)) then
        print("Its out")
        timer.cancel( myTimer )
      else
        print("checking", e.x,e.y,circle.x,circle.y)
      end
    end,0)
  end
  if e.phase == "ended" or e.phase == "cancelled" then
    timer.cancel( myTimer )
  end
end)

Runtime:addEventListener("enterFrame", move)


[TOPIC: post.html]
#17

tilen.curin

[GLOBAL: userInfoPane.html]
tilen.curin
  • Starter
  • PipPipPipPipPipPip
  • 89 posts
  • Jedi

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



[TOPIC: post.html]
#18

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

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?



[TOPIC: post.html]
#19

RagdogStudios

[GLOBAL: userInfoPane.html]
RagdogStudios
  • Starter
  • PipPipPipPipPipPip
  • 104 posts
  • Jedi

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 (:



[TOPIC: post.html]
#20

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

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

 

Cheers to everyone who helped out!




[topic_controls]
[/topic_controls]



Also tagged with one or more of these keywords: touch, event, phase, moved, button