britzl / defold-input

Simplify input related operations such as gesture detection, input mapping and clicking/dragging game objects
MIT License
111 stars 26 forks source link

Drag events after canceling drag #20

Closed Trevortni closed 2 years ago

Trevortni commented 2 years ago

Okay, it's hard to debug this because breakpoints interrupt the issue, but I think it looks like new drag events are getting generated on the same mousedown. I suppose there could be a use case for this, but for my purposes I'm having trouble thinking of a way to differentiate between the first drag and these later phantom drags. Is there any way to tell it to only allow one drag event per mousedown?

britzl commented 2 years ago

Oh, are you getting more than one drag event? That should not happen...

Trevortni commented 2 years ago

Yep, I definitely am, though it's a bit unpredictable. Sometimes it seems fine, but all too frequently it keeps spitting out dozens and dozens of events for about a second or so until it just mysteriously stops.

britzl commented 2 years ago

I'm unable to reproduce this. It would help a lot if you can set up and share a project where this happens.

Trevortni commented 2 years ago

Okay, I put together a minimal project that has the issue.

Desktop game.zip

I have the level script printing a bit of info every time it receives a drag message through the listener.

I also was able to pin down the requirements to make it happen a bit. If you go just to where it starts receiving drag messages (about half a tile width) and stop there, you will receive more messages forever. If you then go back, or a little farther forward (I assume side to side would work as well, but I didn't try it), the messages will stop and won't start again even if you move back into the window that does it.

Oh, and for reference, I have been dragging to the right, but I doubt that makes a difference.

Trevortni commented 2 years ago

Was that helpful for you at all?

britzl commented 2 years ago

Sorry, I've been busy. Thanks for providing a sample project. I'll take a look soon!

britzl commented 2 years ago

Was that helpful for you at all?

No :-) I'm afraid not. I'm not able to reproduce the problem with your sample project. When I run it I see a small green thing on a black background. If I drag from left to right outside I got a crash about not being able to concatenate message.group (which was nil). If I drag left to right on the green thing the log shows:

DEBUG:SCRIPT: Touch!
DEBUG:SCRIPT: [swap_tile] DRAG! dx = 6, dy = 0, time = 0.508239
DEBUG:SCRIPT: [swap_tile] DRAG! dx = 12, dy = 1, time = 0.510213
DEBUG:SCRIPT: [swap_tile] DRAG! dx = 8, dy = 0, time = 0.512309

I've tried dragging in all directions and different distances but I'm not able to reproduce any problems...

Trevortni commented 2 years ago

That looks like those drag events are from the same mousedown, which is what the issue is. There should only be one drag event per mousedown, because I'm canceling the drag on the drag start event. I'm not sure about the message.group issue, I didn't really test anything in this sample other than the issue I was aiming for.

Trevortni commented 2 years ago

Okay, the message.group thing looks like drag events happen even without a compatible collision object being involved. I didn't realize that would happen, but I guess it makes sense and I can obviously trap for it in my main project.

Trevortni commented 2 years ago

D'oh! I don't know why it didn't occur to me until now (I blame Caves & Cliffs), but I can handle the MouseDown event and set a once flag just as easily as you can. I can even grab the click origin while I'm in there and solve the other issue for myself as well.

britzl commented 2 years ago

That looks like those drag events are from the same mousedown, which is what the issue is. There should only be one drag event per mousedown, because I'm canceling the drag on the drag start event

Ah, now I understand! Doh! Let me check the code again.

britzl commented 2 years ago

Fixed in https://github.com/britzl/defold-input/commit/10ad8afd53ec6b4608b5786c0e5adb45640daf1b

Trevortni commented 2 years ago

self.state.dragging doesn't get set if the drag is canceled, so the drag state doesn't get cleared after releasing the button following a canceled drag. This means you never ever get another drag event after canceling one.

image

Trevortni commented 2 years ago

Okay, I guess I get to bother you some more. I'm still getting missed drag events after this update. It took me awhile to figure out that if I leave the clicked object before hitting my drag threshhold (which I have set to half a tile width because that's how Candy Crush appears to do it), this update clears the drag_state. I'm not entirely certain this covers all the new issues, as I haven't figured out yet why some of my drag events in my main game, but not the sample I made for you, seem to be coming in without an id set, but maybe getting this one out of the way will allow me to debug it further.

britzl commented 2 years ago

Ok, let me know if I can help you in any way!

Trevortni commented 2 years ago

Is it by design that it clears the drag_state if you leave the object before hitting the drag threshhold, or is that a bug?

britzl commented 2 years ago

Well, if it is by design then it's not a very good design. It doesn't really make sense and I think it should be changed.

Trevortni commented 2 years ago

The other issue seems to be something involving the collision not being detected after the first one. I initially thought it might have something to do with adding a highlight sprite on PRESSED, but neither taking out the enable of the sprite nor removing the PRESSED handler altogether seems to have any effect on it. I'm hoping getting the drag_state bug fixed will allow me test other bits further. I'd offer to share my code to get your opinion (in all probability it's something boneheaded I did in my code, though reverting to 4.1.0 eliminates this error in favor of the ones you just fixed), but I don't want to post it anywhere public at this point, if you have any other suggestions.

britzl commented 2 years ago

Ok, made a change so that a potential drag isn't immediately ignored if moving outside of the object you pressed on

Trevortni commented 2 years ago

Okay, I figured out the difference between my game code and the sample project I gave you: other tiles. In the actual game, in almost every instance that I leave one collision, I enter another, so the red circled collision_id is still populated, and the drag state never gets cleared. The sample project doesn't have other tiles, so this is never an issue.

If I put in the green circled check, however, everything seems to work properly even if all the other checks get bypassed for some reason or another.

image

britzl commented 2 years ago

Ah, yes, that makes sense. Although it should probably not generate a DRAG_END event since the drag start event was cancelled.

Trevortni commented 2 years ago

Just thought I'd check whether this got forgotten.

britzl commented 2 years ago

Sorry, yes, somewhat forgotten :-)

What is your thought on not generating a DRAG_END?

Trevortni commented 2 years ago

I think it's just as easy to move my edit to an elseif branch to only clear the drag state.

britzl commented 2 years ago

Yep. Would you like to try your hand on a pull request?

Trevortni commented 2 years ago

?

Trevortni commented 2 years ago

Okay, I had a little trouble with getting the name of the variable name right (and fixing the wrong variable), but it seems to be working now. Pull Request ready and waiting for you.