top of page
Search
Writer's pictureSam RL

Design a Simple Universal Menu in Gamemaker 2

Updated: Feb 3, 2022

 

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!




3,872 views0 comments

Comments


bottom of page