HaxeFlixel/flixel-addons

FlxExtendedSprite: Cannot distinguish a mouse up from a mouse drag stop

KosnIre opened this issue · 2 comments

Summary

If I register for all callbacks from FlxExtendedSprite:

this.mousePressedCallback = _onMouseDown;
this.mouseReleasedCallback = _onMouseUp;
this.mouseStartDragCallback = _onMouseDragStart;
this.mouseStopDragCallback = _onMouseDragStop;
this.enableMouseClicks(true);
this.enableMouseDrag();

Then I can get down/up when the mouse is clicked without moving. And I can get a start/stop when the mouse is clicked and moved (pending #307).

However, there's some overlap during these steps:

  1. I press down, not moving yet. >>> _onMouseDown fires
  2. I move, still holding down. >>> _onMouseDragStart fires
  3. I stop moving.
  4. I release the mouse. >>> _onMouseUp fires && _onMouseDragStop fires.

The above seems reasonable to me, except that I can't tell if the mouse was moved at the point _onMouseUp fires. You might say "well just don't do anything until _onMouseDragStop". However, drag stop does not fire if the mouse did not move in step 2.

So, I cannot base any logic on a simple tap, unless I test FlxG.mouse.getWorldPosition(), which is identical logic to what is already happening in FlxExtendedSprite FlxMouseControl.

Proposal

I think the appropriate thing would be to add a parameter to the callback signature isDrag:Bool of mouseReleasedCallback. However, since this would change the callback signature, it would break any code that is currently assigning functions to the mouseReleasedCallback variable.

Another option would be to not fire mouseReleasedCallback if the mouse was dragged, but this also has the potential to break code already using the behavior.

I'm not keen on these suggestions. I would prefer the callbacks to have more information on the event such as start and end position, but I think this wouldn't be necessary. Do I understand correctly that you are trying to react specifically to a tap that is not a drag?

I'm not sure what devices you are targeting, but in both the case of mobile devices with a high resolution and with sensitive mice, it can sometimes be very hard to actually make a single tap/click with no movement whatsoever. It's a common issue I've seen in a lot of low budget mobile apps, especially with buttons in a scroll panel. You try to tap a button, but the panel scrolls a little, and the button input is ignored.

Typically this would be handled with a threshold which can be moved and still have the input count as a tap. This would require you to actually check the distance moved since the start of the tap. This will help make your game feel responsive.

Do I understand correctly that you are trying to react specifically to a tap that is not a drag?

Yes, that's accurate.

it can sometimes be very hard to actually make a single tap/click with no movement whatsoever.

Hmm, you are right about that. Something like a small rectangular area or distance check might work better. FlxExtendedSprite does not have a threshold area as such. I am beginning to think I should just write my own version of this class, using it as an example. Thanks for the input 😄