How to check on every single frame if the mouse cursor is on the game screen? (DEF-1996)

Hi all!
I have a question according the position of the mouse cursor.

What I want to implement is a feature for changing the background music, if the mouse cursor is on the game screen. If the mouse cursor leaves the screen, the game music should change. When the mouse cursor enters the screen again, the background music should change again.

At the moment I use the mouse hovering input to detect if the mouse is hovered across the screen (then it’s sending messages with the action_id = nil).
Is there any possibility to check, if the mouse cursor leaves the screen about the paramaters of the action object of the hovered mouse?

Currently I use a naive implementation, to check if the mouse cursor reaches the screen borders. My code snippet looks like that:

-- check if cursor leaves the screen
if ( (action.x <= tonumber(sys.get_config("display.width")) and action.x >= tonumber(sys.get_config("display.width"))-40) or (action.x >=0 and action.x <= 40) ) or 
   ( (action.y <= tonumber(sys.get_config("display.height")) and action.y >= tonumber(sys.get_config("display.height"))-40) or (action.y >=0 and action.y <= 40) ) then
     self.mouse_on_screen = false
    
-- check if cursor is on screen
elseif (action.x < tonumber(sys.get_config("display.width")) and action.x > 0) and
       (action.y < tonumber(sys.get_config("display.height")) and action.y > 0) then
     self.mouse_on_screen = true

The problem with this Implementation is, that the mouse could be moved really fast to the outside of the game screen. In that case it will most likely happen that the mouse will pass the “border” which I defined in the first conditional statement without sending informations about leaving the screen, because it passes that border too quickly.

So the short form of the question is:
Is there any possibility to check if the mouse cursor is currently on screen, even if the mouse cursor does not move at that moment?

Greetings,
Alex

Test using action.screen_x action.screen_y and see if that helps. If it does then use it along with render.get_window_width() render.get_window_height() from your render script, make a helper module to pass the data to your game script.

There might need to be a rawer way to check mousex/mousey… there’s no way for us to check for window focus right now either. With extension system, probably possible to add support for both of these.

Thanks a lot for your answer, Pkeod!

I’m testing it with action.screen_x and action.screen_y and there are still some situations in which the mouse can be moved too fast to the outside of the game window. Maybe your second approach would fix this, but I do not have the methods get_window_width() and get_window_height() in my renderscript. How can I access these fields?

On OSX (and probably also windows, linux and html5) you still get mouse coordinates while the mouse pointer is offscreen as long as the Defold app window has focus. So, if you get negative screen_x or screen_y you can conclude that the mouse pointer is to the left of or below the window, and if you check for values greater than the screen width and height you can detect if the mouse pointer is to the right of or above the window.

PS render.get_window_width() and height can only be accessed from a render script. You can create a custom render script and store those values in a Lua module that you access from your .script and .gui_script files. An example can be seen here: https://github.com/britzl/publicexamples/blob/master/examples/fixed_aspect_ratio/fixed_aspect_ratio.render_script#L24

3 Likes

Thanks for your answer, britzl!

Actually it seems like you don’t get the mouse coordinates while the mouse pointer is offscreen on windows, even if the Defold app has the focus.

Basically this is my approach:

function on_input(self, action_id, action)
     if action_id == nil then
        print("action.screen_x: " .. action.screen_x)
        print("action.screen_y: " .. action.screen_y)
     end
end

This does print the coordinates only, if the mouse is on the Defold app window. Did I do something wrong to check the mouse coordinates?

PS Thanks for the example with the render script! That is indeed really helpful!

Oh, I see. I wasn’t aware that the windows and osx versions behaved differently when it came to sending mouse input on desktop. @Mathias_Westerdahl, worth creating a ticket?

Sure thing! I’ve added it as DEF-1996 !

1 Like