Get ALL of the menus you will ever need for Gamemaker 2 with the link below. Just drop all of the assets right into your game to get started!
Sign up and receive Simple Essential Menus, as well as many other GML source code for FREE
All menus + much more source files: https://www.darklabgames.com/freestuff
Design a Simple Universal Menu in Gamemaker 2
Menu code can be simple or they can be complicated, they can be effective or they can be confusing. I have figured out an effective way to create a simple menu for your game. You can of course customize it however you like, but it is very effective base code to use for all of your menus. It is a universal input menu that works with mouse (touch), keyboard, and gamepad. Lets get started!
Editors Note: I included the bulk of the code in the DrawGUI event for simplicity and you can of course structure it how you like. In my expereince there is no performance increase from structuring your menus in this way, the menus is all of my games are structured similarily.
IMPORTANT: Additional font and sounds you may need to create before starting
fnt_menu
snd_switch
snd_select
FIRST, create a new object (name it whatever you like) You will need 3 events and I will go over what each of these require:
1) Create Event
2) Draw GUI Event
3) Alarm[0] Event
1) In the Create Event
we will declare some variables to make things easier
add as many menu options as you want, name them as you like.
we will need to determine when the mouse is being used, so not to confuse the input during the Draw GUI Event
Create Event:
color1 = c_gray; //unselected items
color2 = c_white; //selected items
vS = 70; //vertical space
menu[0] = "OPTION 0";
menu[1] = "OPTION 1";
menu[2] = "OPTION 2";
menu[3] = "OPTION 3";
menu[4] = "OPTION 4";
menuitems = array_length(menu);
cursor = 0;
//detect if mousec is plugged in
mousec = true;
var gp_num = gamepad_get_device_count();
var i;
for (var i = 0; i < gp_num; i++;) {
if gamepad_is_connected(i) mousec = false;
}
lastmx = device_mouse_x_to_gui(0);
lastmy = device_mouse_y_to_gui(0);
2) In the DrawGUI Event First we will check the player input by:
checking what buttons are being pressed: (mouse/touch, keyboard, gamepad)
we will use the alarm[0] to lockout the thumstick so there is no unlimited scroll
then we will check if the mouse is being used and if not we will disable its effects
DrawGui Event:
// GAMEPAD, KEYBOARD CONTROLS
// Press Direction (thumbstick, dpad, keyboard arrows, keyboard WASD)
pright = gamepad_button_check_pressed(0,gp_padr) || keyboard_check_pressed(vk_right)
|| keyboard_check_pressed(ord("D"))
|| ((gamepad_axis_value(0,gp_axislh) > 0.5) && !alarm[0]);
pleft = gamepad_button_check_pressed(0,gp_padl)
|| keyboard_check_pressed(vk_left)
|| keyboard_check_pressed(ord("A"))
|| ((gamepad_axis_value(0,gp_axislh) < -0.5) && !alarm[0]);
pup = gamepad_button_check_pressed(0,gp_padu) || keyboard_check_pressed(vk_up)
|| keyboard_check_pressed(ord("W"))
|| ((gamepad_axis_value(0,gp_axislv) < -0.5) && !alarm[0]);
pdown = gamepad_button_check_pressed(0,gp_padd) || keyboard_check_pressed(vk_down)
|| keyboard_check_pressed(ord("S"))
|| ((gamepad_axis_value(0,gp_axislv) > 0.5) && !alarm[0]);
// Lockout for Thumbstick Press
if ( (gamepad_axis_value(0,gp_axislh) > 0.5)
|| (gamepad_axis_value(0,gp_axislh) < -0.5)
|| (gamepad_axis_value(0,gp_axislv) < -0.5)
|| (gamepad_axis_value(0,gp_axislv) > 0.5) ) {alarm[0] = 5;}
//Action:
action = gamepad_button_check_pressed(0,gp_face3) || keyboard_check_pressed(vk_enter)
|| gamepad_button_check_pressed(0,gp_face1)
|| keyboard_check_pressed(vk_space)
|| mouse_check_button_released(mb_left)
|| gamepad_button_check_pressed(0,gp_start);
//Cancel:
cancel = gamepad_button_check_pressed(0,gp_face2)
|| keyboard_check_pressed(vk_backspace)
|| keyboard_check_pressed(vk_escape);
//check if the user is using the mouse
var mx = device_mouse_x_to_gui(0);
var my = device_mouse_y_to_gui(0);
if (mx != lastmx || my != lastmy) mousec = true;
lastmx = mx;
lastmy = my;
//if using keyboard then disable the mouse, so there is no confusion
if keyboard_check_pressed(vk_anykey) mousec = false;
//if using gamepad then disable the mouse, so there is no confusion
for (i=gp_face1; i<gp_axisrv; i++){
if gamepad_button_check(0, i) {
mousec = false;
}
}
Next we will:
declare some local variables
draw the menu
check if the mouse is hovering or clicking
DrawGui Event:
var ax = 350; //x loc on the GUI to anchor the menu from top left
var ay = 300; //y loc on the GUI to anchor the menu from top left
var txt;
var col;
var i;
draw_set_font(fnt_menu); //add your own custom font
draw_set_valign(fa_middle);
draw_set_halign(fa_left);
draw_set_alpha(1);
var xx = ax;
var yy = ay;
//find the widest menu item so we know where to create boundaries
var wide = 0;
for (var i = 0; i < menuitems; i++) {
var w = string_width(menu[i]); //find the widest string
if w > wide wide = w;
}
var ls = (xx - 30);
var rs = (xx + wide);
/// DRAW MENU
for (var i = 0; i < menuitems; i++) {
//highlight on mouse over
if point_in_rectangle(mx,my,ls,yy-vS/3,rs,yy+vS/3) && mousec {
if cursor != i audio_play_sound(snd_switch,1,false);
cursor = i;
}
col = color1;
txt = menu[i];
if cursor == i col = color2;
draw_text_transformed_color(xx,yy,menu[i],1,1,0,col,col,col,col,1);
yy += vS;
}
Lastly:
check if the user is moving up or down on gamepad or keyboard
activate when the user presses action (you will have to determine what happens when you choose a menu option)
add some sound effects
DrawGui Event:
//highlight with mousec/ keyboard
if pup {
cursor -= 1;
if cursor < 0 cursor = menuitems-1;
}
if pdown {
cursor += 1;
if cursor > menuitems-1 cursor = 0;
}
//activate
if action {
switch cursor {
case 0:
//menu actions go here
break;
case 1:
//menu actions go here
break;
case 2:
//menu actions go here
break;
case 3:
//menu actions go here
break;
case 4:
//menu actions go here
break;
case 5:
//menu actions go here
break;
}
}
//sound effects - Add your own custom Sound Effects Here
if action audio_play_sound(snd_select,1,false);
if pup || pdown audio_play_sound(snd_switch,1,false);
3) In the Alarm[0] Event
Nothing goes here, we just leave it blank to be accessed as the lockout =)
Alarm[0] Event:
//@description lockout timer
If you got anything of use out of this tutorial or have question please let me know in the comments, and happy programming!
Comments