Erratic behavior in Mouse Events

  • #1, by tudor-stamateTuesday, 09. April 2019, 05:37 5 years ago
    Hi guys!

    I'm trying to create a Lua script for a jigsaw minigame and I need to rely on the mouse down/up events. Unfortunately I've noticed that the mouse up event doesn't always fire. The script is something like this:
    function start()
      registerEventHandler("mouseEvent", "onMouseClick", {eEvtMouseLeftButtonDown})
      registerEventHandler("mouseEvent", "onMouseRelease", {eEvtMouseLeftButtonUp})
    end
    
    function end()
      -- unregister the events above
    end
    
    function onMouseClick(eventType, mousePos)
      -- get puzzle piece
    end
    
    function onMouseRelease(eventType, mousePos)
      -- drop puzzle piece
    end

    The movement is done in a mainLoop event handler.

    Now, everything's fine and dandy IF I hold the piece for less than ~2s...
    If I hold the mouse button down for longer than that, the release event doesn't fire up anymore. I can consistently get this behavior each time I'm testing.

    Is this a bug or is there something I'm not doing right?

    As for more information:
    The puzzle pieces are Sprite Objects, with no polygon hotspots.
    I'm developing on Windows (I have access to a Mac machine but I wasn't able to test it yet there)
    I've tried with both the laptop trackpad and a mouse - same behavior.

    Thanks a lot!
    Tudor.

    Newbie

    27 Posts


  • #2, by afrlmeTuesday, 09. April 2019, 12:14 5 years ago
    There can only be one mouseEvent handler per project.

    To my knowledge you can't unregister mouseEvent handlers either, only mainLoop events, as it's possible to create multiple instances of mainLoop, but only 1 instance of each of the other event handlers/hooks.

    When you hold down the mouse for x time it will eventually change to mouse button hold (eEvtMouseLeftButtonHold or eEvtMouseLeftButtonHolding) - I forget which. Anyway, create a single mouse event handler, don't add any flags to it & query if x or y event with eventType... something along the lines of this...

    function mouseEvt(typ, pos)
    
    
    
     if typ == eEvtMouseLeftButtonDown or typ == eEvtMouseLeftButtonHold then
    
      -- do something (pressed/holding)
    
     elseif typ == eEvtMouseLeftButtonUp or typ == eEvtMouseLeftButtonHolding then
    
      -- do something (up/released)
    
     end
    
    
    
    end
    
    
    
    registerEventHandler("mouseEvent", "mouseEvt")

    Imperator

    7278 Posts

  • #3, by tudor-stamateTuesday, 09. April 2019, 12:42 5 years ago
    I see.  I'm guessing I can do a definition script that handles mouse button clicks and query that when needed in order to bypass the "one mouseEvent handler / project", no biggie.

    Thank you very much for the explanation, AFRLme. I'll try it out tonight!

    Newbie

    27 Posts

  • #4, by afrlmeTuesday, 09. April 2019, 12:55 5 years ago
    You can use conditions, values, Lua variables, & other queries in the mouse event handler to determine when the mouse event handler should work. You can even link to other functions via it as well. So to keep the mouse event handler tidy you could do something like this...

    function mouseEvt(typ, pos)
    
    
    
     if typ == eEvtMouseLeftButtonDown or typ == eEvtMouseLeftButtonHold then
    
      if game.CurrentScene:getName() == "example" then puzzlePressed(game.CurrentObject) end
    
     elseif typ == eEvtMouseLeftButtonUp or typ == eEvtMouseLeftButtonHolding then
    
      -- do something (up/released)
    
     end
    
    
    
    end
    
    
    
    function puzzlePressed(x)
    
     -- set puzzle piece x as held object
    
     -- do something
    
    end
    
    
    
    registerEventHandler("mouseEvent", "mouseEvt")

    I actually created a drag & drop puzzle last year (or the year before) for some freelance work. I used an interface, some animations, & the mouseEvent handler.


    There was one issue with it though because we can't change the object center (z-index) value during runtime without restarting the scene, so I wasn't able to get the pieces of paper to display on top of all the others when active.

    Imperator

    7278 Posts

  • #5, by tudor-stamateTuesday, 09. April 2019, 17:20 5 years ago
    So I just tried modifying the script, you're correct eEvtMouseLeftButtonHold fires when releasing the mouse button after holding it for a couple of seconds. eEvtMouseLeftButtonHolding fires when the hold timer runs out, even if the button is not released.

    I've also tested the unregistering of the events and they seem to unregister correctly when exiting the scene and calling the end() function. At least on v509 Build 1203

    For now, I'm going to let them here since they're for a prototype, but will move the event handling to a separate script when doing it "proper".

    That screenshot you've attached looks really cool! Yes, it is a pitty we can't change the sorting order but... we manage, haha!
    Also, did your minigame connect puzzle pieces "in the air"? For example even if they were not in the final, correct position?

    Cheers and thanks a lot, AFRLme!

    Newbie

    27 Posts

  • #6, by afrlmeTuesday, 09. April 2019, 23:01 5 years ago
    Yeah I implemented a sort of magnetic snap to them so they slid into the correct position if the mouse cursor was inside of the relevant object polygon or they stayed wherever they were dropped.

    If I remember correctly, what I did what was change the mouse hold time to something really low for that particular scene then reset it on scene end, so I just used the mouse hold & mouse hold (released) events instead of left button down/up.

    Imperator

    7278 Posts

  • #7, by esmeraldaThursday, 11. April 2019, 11:45 5 years ago
    @AFRLme (or tudor-stamate or everyone who knows how to do it) It would be really great if you could make some kind of tutorial how to do a jigsaw puzzle like that shown in the video/pictiure. 

    I can make a very crude version of a jigsaw with the action parts, but nothing where I can drop the pieces anywhere I like. 
    So I would really appreciate if you could find the time to do a tutorial.


    Key Killer

    513 Posts

  • #8, by tudor-stamateThursday, 11. April 2019, 11:53 5 years ago
    @AFRLme - hmmm didn't think of using the polygons, I'm just doing a basic AABB colision test ^_-' But now that you mention it... hmmm, might be faster that way since the calculations are done in engine and not in Lua. Will see.
    Also, didn't know you can change the mouse hold time. Is that in the options or in the Explorer?

    @Esmeralda. I was actually thinking of releasing the script after I finish it. It's not as "proffessional" as AFRLme's but it's a start! Haha.

    I'm off on holiday for the time being so it will be some time until then.

    Good luck!

    Newbie

    27 Posts

  • #9, by esmeraldaThursday, 11. April 2019, 12:00 5 years ago
    You can set the mouse hold time in the mouse properties and change it during the game via Lua.
    game.HoldTime =  time in ms     (learnt this just the other day ^^)

    The script would be great. Have a nice holiday!

    Key Killer

    513 Posts

  • #10, by afrlmeThursday, 11. April 2019, 12:57 5 years ago
    I don't know about writing/creating a tutorial for it. Maybe I can replace the asset files/edit the template I created for the freelance project - but I don't know when.

    The script itself was quite small. Less than 100 lines of code. I used a Lua table, a few functions, the isInsidePolygon function, & an interface. The template also includes a magnetic snap script & a none-magnetic snap script, but I don't remember if the latter works correctly - most likely an out of date version of the former.

    Imperator

    7278 Posts