Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Hello again. I've been trying to get mouse controls to work. I managed to get the mouse buttons working no problem, but I'm having a fair bit of trouble getting the menu to figure out which menuvalue_x and y the mouse should be on. I tried the code above, and it only seemed to partially work. On the main menu it only every selects New Game. On the player name select it goes to 'M' immediately, then if you click it selects all the letters from A-L.

I also tried a different system where I defined some variables and used them to figure out the menuvalue_x and menuvalue_y. The variables I used:

var mouse_y_gui = device_mouse_y_to_gui(0);
var mouse_x_gui = device_mouse_x_to_gui(0);
var array_l = array_length(ggui_frame_l) -1;
var array_w = array_length(ggui_frame_w) -1;
var array_t = array_length(ggui_frame_t) -1;
var array_h = array_length(ggui_frame_h) -1;
var menu_width = ggui_frame_l[array_l] + ggui_frame_w[array_w];
var menu_height = ggui_frame_t[array_t] + ggui_frame_h[array_h];
var menu_x = ggui_frame_l[0];
var menu_y = ggui_frame_t[0];


to try and get this code to work:

if((mouse_x_gui > menu_x && mouse_x_gui < menu_x + menu_width) && (mouse_y_gui > menu_y && mouse_y_gui < menu_y + menu_height))
{
menuvalue_x = floor(mouse_x_gui - menu_x/(menu_width/menu_w));
menuvalue_y = floor(mouse_x_gui - menu_x/(menu_width/menu_w));
}

I'm not quite sure what I missed, but it would be great to get mouse controls working, and any help would be greatly appreciated.

(1 edit) (+1)

First of all these give you the wrong sizes, just using the frame sizes should be enough (don't add the left/top position to the width/height)

var menu_width = ggui_frame_l[array_l] + ggui_frame_w[array_w];
var menu_height = ggui_frame_t[array_t] + ggui_frame_h[array_h];

I also don't see why you divide the pixel size with the number of elements along the axis, they represent the same ratio if evenly spaced and that means translating between them should "just work". Though you'll need to make sure the output stays in range:

clamp( round((mouse_x - menu_x)/menu_width), 0, menu_w - 1)

(And also note that "If evenly spaced" might cause issues with the more esoteric layouts since nothing forces a menu to actually be evenly spaced, you can place frames anywhere and fill them with whatever you want)


Did you check the code in ggui_draw that draws the rectangle over the currently selected item? It converts from grid coordinates to screen pixel coordinates so it might help a bit here. You could even skip having to do the reverse computation (grid coordinates from screen coordinates) if you loop over all menu options, compute their corresponding frame coordinates (using this code), and then use point_in_rectangle to check if the mouse cursor is over that frame. Slow, but 100% accurate.


(Note that drawmenux/drawmenuy, the scroll offset, are computed at the beginning of the function)

I got it to work! First, thank you so much for you help Yal! Your help has cleared up a bunch and made it so I could figure this out. It took a bit to try and understand how the menus work, and I still don't get it all, but for those interested in getting the mouse to work, here's what I did:

First, in the init_input script I added:

#macro input_MA 9
#macro input_MB 10
#macro INPUT_MAX 11
global.input_key[input_MA] = mb_left
global.input_key[input_MB] = mb_right

Then in the function get_keys script I added and changed a couple lines:

p_a = ((p_a + 1)*(k_a + k_ma))
p_b = ((p_b + 1)*(k_b + k_mb))
k_ma = mouse_check_button(global.input_key[input_MA])
k_mb = mouse_check_button(global.input_key[input_MB])

Then I found pretty much everywhere that k_a was and made it (k_a||k_ma). And the same thing with k_b,  I changed them to (k_b||k_mb).

This was to allow for the mouse button to work as the 'A' or the 'B' button, while still keeping the regular 'A' and 'B' button working. So you can use either the mouse or the keyboard.

The part that I had trouble with was figuring out which menu box the mouse was in. What I ended up doing was looping through the options to see if the mouse was hovering over an option. Than looping through the options and checking if the mouse was in each rectangle until it found the right one. It's on the more expensive end, it requires a few loops, but it does seem to work, and I haven't noticed any issues.

So, here's what I put, right near the end of ggui_menu_handler (just above the closing }):

for(c = 0; c < ggui_frames;c++){
     //check to see if the mouse is hovering over an option
     if(mouse_x > ggui_frame_l[c] && mouse_x < ggui_frame_l[c] + ggui_frame_w[c]){
     if(mouse_y > ggui_frame_t[c] && mouse_y < ggui_frame_t[c] + ggui_frame_h[c]){
          //the mouse is hovering over an option, so loop through the options to find out which one we are over
          for(var d = 0; d < menu_w; d++){
          for(var e = 0; e < menu_h; e++){
               frame = menu_frame[d, e];
               //here we are checking to see if the mouse overlaps with the rectangle created by the menu option
               if point_in_rectangle(
                 mouse_x, 
                 mouse_y,
                 lerp(ggui_frame_l[frame],ggui_frame_l[frame] + ggui_frame_w[frame],menu_reg_l[d, e]),
                 lerp(ggui_frame_t[frame],ggui_frame_t[frame] + ggui_frame_h[frame],menu_reg_t[d, e]),
                 lerp(ggui_frame_l[frame],ggui_frame_l[frame] + ggui_frame_w[frame],menu_reg_r[d, e]),
                 lerp(ggui_frame_t[frame],ggui_frame_t[frame] + ggui_frame_h[frame],menu_reg_b[d, e])
               )
               {
                    menuvalue_x = d;
                    menuvalue_y = e;
                    break;//End when we find the first option that matches
               }
          }
          }
     }
     }
}


If anyone has a way to refine this and make it less slow and costly, I'd love to hear it. If what I have put above is unclear, let me know. But, this is what I did, and the mouse seems to be working well.