I'm getting a "moved" event without "began" or "ended"

I’ve ran into a problem where the “moved” event fires multiple times without the “began” event firing before it. This leave my game in an inconsistent state and pretty much renders it useless.

The problem happens when you tap and drag very fast (which my app requires). I’ve created a demo with the minimum code necessary to reproduce this behavior. The square should tilt when you tap or drag it. Note: in this demo the square’s position has been fixed to make the issue more obvious but this “bug” happens weter the square moves or not.

https://www.youtube.com/watch?v=e1aiIAkRzbg

It’s very hard reproduce do with the mouse but it’s quite easy to do in the actual device. I finally get it around second 14 in the video.

Any help will be greatly appreciated!

local button = display.newRect(display.contentCenterX, display.contentCenterY, 300, 300) local touchHandler = function(event) if event.phase == "began" then display.getCurrentStage():setFocus(button) button.rotation = 45 print(event.phase .. "------------------\\") end if event.phase == "ended" or event.phase == "cancelled" then display.getCurrentStage():setFocus(nil) button.rotation = 0 print(event.phase .. "------------------/") end if event.phase == "moved" then button.rotation = 45 print(event.phase) end return true end button:addEventListener("touch", touchHandler)

You could set a bit to flip that the moved phase recognizes, but only triggers on a began phase.

 local hasBeenTouched = false local touchCounter = 0 local function pressTest(event) if event.phase == "began" and hasBeenTouched == false then hasBeenTouched = true print("the new hasBeenTouched value is "..tostring(hasBeenTouched)) end if event.phase == "moved" and hasBeenTouched == true then touchCounter = touchCounter+1 print("the new hasBeenTouched value is "..tostring(hasBeenTouched).." and the touchCounter amount is "..touchCounter) end if event.phase == "ended" and hasBeenTouched == true then hasBeenTouched = false print("the new hasBeenTouched value is "..tostring(hasBeenTouched)) end end

Hi Panc, thanks for the prompt reply. That’s a very good idea and easy to implement. 

I would like to see what the Corona people think about this (is it a bug or is this intended?). 

I don’t want to put words in their mouths, but it’s more of a feature than a bug. Several different forum threads have detailed the “issue” and the solutions related to it.

The moved phase is a separate phase, independent of a began or ended phase, so it makes sense that it would be fired without input from either the began or ended phases. 

I’ve read those threads and others before posting, but they refer to a different problem. Most commonly, people were not getting the “ended” event but I couldn’t find an instance where people were getting the “moved” event by itself. 

Do you remember where you read that the “moved” phase is independent of the others? I find it very strange that this would be by design.

I mean, those examples were more to illustrate that folks wanted tighter control of their touch listener.

The docs talk about the three different event phases as “began”, “moved” and “ended”, meaning they are separate from each other. It would be a real " six in one, half dozen in the other" situation if the hardcoded the moved phase into the began and ended phases, as a lot of people need the independent moved phase for UI purposes. I myself have a few implementations that need an independent moved phase.

Also, just practically speaking, it might be more difficult to code around a phase-dependent moved phase.

It’s possible to get a moved without a began if the touch begins off object and then moves onto the object.

Rob

You could set a bit to flip that the moved phase recognizes, but only triggers on a began phase.

 local hasBeenTouched = false local touchCounter = 0 local function pressTest(event) if event.phase == "began" and hasBeenTouched == false then hasBeenTouched = true print("the new hasBeenTouched value is "..tostring(hasBeenTouched)) end if event.phase == "moved" and hasBeenTouched == true then touchCounter = touchCounter+1 print("the new hasBeenTouched value is "..tostring(hasBeenTouched).." and the touchCounter amount is "..touchCounter) end if event.phase == "ended" and hasBeenTouched == true then hasBeenTouched = false print("the new hasBeenTouched value is "..tostring(hasBeenTouched)) end end

Hi Panc, thanks for the prompt reply. That’s a very good idea and easy to implement. 

I would like to see what the Corona people think about this (is it a bug or is this intended?). 

I don’t want to put words in their mouths, but it’s more of a feature than a bug. Several different forum threads have detailed the “issue” and the solutions related to it.

The moved phase is a separate phase, independent of a began or ended phase, so it makes sense that it would be fired without input from either the began or ended phases. 

I’ve read those threads and others before posting, but they refer to a different problem. Most commonly, people were not getting the “ended” event but I couldn’t find an instance where people were getting the “moved” event by itself. 

Do you remember where you read that the “moved” phase is independent of the others? I find it very strange that this would be by design.

I mean, those examples were more to illustrate that folks wanted tighter control of their touch listener.

The docs talk about the three different event phases as “began”, “moved” and “ended”, meaning they are separate from each other. It would be a real " six in one, half dozen in the other" situation if the hardcoded the moved phase into the began and ended phases, as a lot of people need the independent moved phase for UI purposes. I myself have a few implementations that need an independent moved phase.

Also, just practically speaking, it might be more difficult to code around a phase-dependent moved phase.

It’s possible to get a moved without a began if the touch begins off object and then moves onto the object.

Rob