Detecting in touch event if button is being held at same place

Hi I found an article that show how to determine in touch phase if touch event is being hold down, but I want to determine if it is being held at the same place, so not being moved but still being hold down. What can I add to this code to see that its not moved and determine the position while its hold down and not moving.

local holding = false
local function enterFrameListener()
if holding then
– Holding button
– Code here
– Code here
– Code here
else
– Not holding
– Code here
– Code here
– Code here
end
end

local function touchHandler( event )
if event.phase == “began” then
display.getCurrentStage():setFocus( event.target )
event.target.isFocus = true
Runtime:addEventListener( “enterFrame”, enterFrameListener )
holding = true
elseif event.target.isFocus then
if event.phase == “moved” then
elseif event.phase == “ended” then
holding = false
Runtime:removeEventListener( “enterFrame”, enterFrameListener )
display.getCurrentStage():setFocus( nil )
event.target.isFocus = false
end
end
return true
end

Hi I see the forum is flooded with some weird stuff. Do not want my Post to be lost in the see of unwanted posts.

We had a spammer get loose.  That’s been taken care of.

You would have to do basically the same thing with a different flag.  You have a flag that you set and clear on the began and ended phases.  You could set another flag:  isMoving = false in the began phase, and then if you get a “move” phase, set isMoving to true then in your Runtime enterFrame listener, you can test to see if isMoving is false and holding.

Rob

Hi Rob

Thanks for the advice. I did add the flags. But the problem is that in the move event remains true because the move event was triggered but as soon as as still have your finger holding and you do not move your finger the move event remains true. I would like to know how I can determine if in the move event the event.x and event.y remains in one position and  if I try to use event.x - event.x it always returns zero. I do not care if for the xStart event but need to know in the move event if it remains in the same position and that value where the user keeps his finger I need retuned to the event listener.

Hope that is a bit more clear. 

You are only going to get a move event if the finger moves.  You should never get an event if current event.x, event.y and previous event.x and event.y are the same.  Maybe you need a move counter and throw away the first move it make your handler less sensitive to people moving their finger about.  But you can easily save the last move by doing something like this:

     event.target.lastMoveX = event.x

     event.target.lastMoveY = event.y

You can also do this in the began phase to initialize the lastMoveX and lastMoveY values.  Then in your move phase (before you set the values above), you can do a comparison and maybe say they have to move 5px for it to count as a move or something like that.

Rob

Hi Rob

Thanks for the reply. Ok if I understand it correct you say that when you will get the move event only if it moves, but the ended phase is not initiated so how can I determine if the user has in the move phase stopped moving because with the isMove state meant is still true, because I only change to isMove false in the end phase. Maybe I am missing some thing. I added the code for reference.

local function enterFrameListener()

    if isMoving then

        – isMoving button

        print (“is”Moving)  –  this returns even if I keep my finger still

    elseif holding then

        print(“holding”)

   

    else

        – Not holding

        print (“ended”)

    end

end

l

local function onSceneTouch( self, event )

    

    touchedID = self

    localX, localY = touchedID:localToContent( 0, 0 )

    local t = event.target

 

if event.phase == “began” then

    Runtime:addEventListener( “enterFrame”, enterFrameListener )

     holding = true

      isMoving = false

    display.getCurrentStage():setFocus( t )

        t.isFocus = true

 

elseif t.isFocus then

    

        if (event.phase == “moved”) then

         isMoving = true

 

    — I need some thing here that show me the user is still holding the object and not moving the object and need to determine the position he has his finger at, at that stage.

     elseif (event.phase == “ended”) then

              holding = false

              isMoving = false

         Runtime:removeEventListener( “enterFrame”, enterFrameListener )

 

         display.getCurrentStage():setFocus( nil )

                t.isFocus = false

      end

 end             

 return true

end

You will only get an “ended” phase when they pick up their finger (or let go of the mouse button).  If you touch and move and stop you will likely only get a began and moved phase.  Depending on the movement, you could get multiple move’s but it could be as few as one. 

Hi Rob

So is there an solution on how to determine if the user in one move event stopped moving his finger? Not going to the end phase?

There must be some event listener to determine your finger position on the screen and when its not moving?

Or is there an arithmetic you can do to determine this?

I have tired a few options and read a few posts, but could not find an answer?

Rob

I think you must think I am confused. I took the code and created a new Test.lua file. Indeed if I stop my finger in the move event it does change the event listener. I think I will have to go through my code in the other file to see why my moving event keeps on returning a move event, maybe I have a “return true” or “return self” at the wrong place in my move event.

Regards

Rob 

Sorry man, this is still driving me nuts, I check the test file again. I posted this as a question on Brent Tap/Touch Anatomy as well.

The thing is I checked the print statement in the move phase and not the one on the isMoving true event runtime.

This is what I replied to at Brent Tutorial:

“I would like to know in the event.phase == “moved” when you have a print statement, it will print the whole time you move the object. But as soon as you stop the move, but not go to the ended phase (so you have in essence kept your finger in one place) the print statement will stop printing, what event or handler is checked to see if in the move phase that it has stopped moving causing the print statement to stop. I would like to know because if you put an boolen to the move phase it will remain true even if you you keep your finger in the move phase in one place, how does lua check this? I would like to know what I can set or change to get the same result as when you only move your finger and when you stop moving your finger to change a boolen or variable to notice the finger is being kept in one place?”

Rob

I appreciate the help so-far, but I can not get this out of my head - please if you can let me know.

Thanks

Regards

I think the only way to go around this would be to have an enterFrame checking on it.
In the move event, log in a variable the event.time value.
In the enterFrame event, check if that event.time value hasn’t changed for a certain amount of time. In that case, you will know that the user has stopped moving, even though their finger is still touching the screen.

Just tried this out, it seems to work fine. 200 is the time it waits before declaring the movement stopped. 1000 = 1s.

 

local bg = display.newRect(display.contentCenterX, display.contentCenterY, display.contentWidth-(display.screenOriginX\*2), display.contentHeight-(display.screenOriginY\*2)); function bg:touch(event) if event.phase == "began" then self.currTime = event.time; print("touch began"); elseif event.phase == "moved" then self.currTime = event.time; print("touch moved"); if not self.musicIsPlaying then self.musicIsPlaying = audio.play(music, {channel = 1}); end elseif event.phase == "ended" then self.currTime = nil; print("touch ended"); end end bg:addEventListener("touch", bg); function bg:enterFrame(event) if self.currTime then if (event.time-self.currTime) \> 200 then print("touch movement has stopped"); if self.musicIsPlaying then audio.stop({channel = 1}); self.musicIsPlaying = nil; end end end end Runtime:addEventListener("enterFrame", bg);

Hi Hachisoft

Thanks for this, it could be an option but the problem is it is dependant on the began phase. If you have to move an object through a maze or even if you have to play a sound while the object is moving and stop playing the sound when he pauses his movement and then continue playing the sound as soon as he start moving again, then you can not depend on the began phase time. It would really be help full if it was only dependent on the move phase because the user can start the move hold it down to figure out where he want o move it and one can not guess the time he will take to do this. So my question still remains how does corona keep track of the move event to keep printing the statement while moving and when you stop moving it stops the print statement. Because if I could get that event handler then you could only depend on the move phase.

Hi Sadsack,
have you tried the code out?
It doesn’t depend on the began phase at all.

If you look at the code, both the began and the moved phases contain the exact same code.
Therefore, you can do everything you’ve said with it. Wether it’s the began phase, or the move phase, they’ll behave exactly the same.

I’ve edited the code above to show you how to loop a sound only when the player is moving, and stop it if it’s not moving.

What you’re asking (an event that tells you that the movement has stopped) is not handled by Corona. This is because the device only tells you 3 things. If a touch has started (began), if it has updated (moved) and if it has ended. It can’t tell you that it has started, moved, but then it stopped. That’s something you have to figure out by yourself, for example with the code I’ve written above.

If you try it, you’ll see that it will tell you when the touch began, when the touch moves, when the touch has stopped movements, and when the touch ends. You can use these (in the same places as the print statements) to alter your booleans or do anything else.

Hi Hachisoft

Sorry I did not notice the you use the began phase to make the timer true and then just update it in the move event. This is a working solution.

Hachisoft

Thanks for this you are a star, been bugging me for some time now and that is truly a nice way of doing it.

Really appreciate it.

SadSack

Glad it works (;

Good luck with your project!

Just to clarify our event handling on touch events.:

Finger/Mouse Down = event.phase == “began” once

Finger/Mouse Up = event.phase == “ended” once

Finger/Mouse move = event.phase == “moved” but only once per move.

Finger/Mouse moves off object being touched = event.phase == “cancelled”.

I’m glad you have a solution that works for you.

Hi I see the forum is flooded with some weird stuff. Do not want my Post to be lost in the see of unwanted posts.

We had a spammer get loose.  That’s been taken care of.

You would have to do basically the same thing with a different flag.  You have a flag that you set and clear on the began and ended phases.  You could set another flag:  isMoving = false in the began phase, and then if you get a “move” phase, set isMoving to true then in your Runtime enterFrame listener, you can test to see if isMoving is false and holding.

Rob