• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM complex command-based UT3 style menu

S

Silicon Sorcery Studios

Guest
"Hello World!"

I am trying to learn how to do complex command-based menus.

My goal is to build a menu system that allows the player to change settings for each character the player uses. Like the one that is in Unreal Tournament III. Sorry I can't show a picture of it :(

As in many other modern games the player has rank over multiple sprites/models and can change among different sprites/models.

Dragon Age, GTA 5, and Secret of Mana, are just a few examples.


I have a semi working demo of what I am trying to achieve.

Link!


My progress thus far:
1. the menu sends and receives the correct info to the correct location (a separate array)

2. the player is able to move back and froth from each window within the menu.


However, If I select player 1, setting #1 for player gets, automatically, turned on.

Furthermore, once any of the settings get turned on, they will not turn off, when the corresponding number is pressed a second time.


Controls:
"Tab" opens the menu

Press the corresponding number for each item in the menu

"R" restartes the game

"Q" ends the game


Lastly, there has to be a better approach than my current method.
One of the biggest challenges I always find with menus is the auto flicker that occurs when a menu involves a boolean (on/off) setting.

The player presses the button and instead of turning 'on' or 'off' the setting flickers back and forth at the speed of light. It can be a real headache to solve. The "double if check system" is the only method I have found that overcomes the issue.

// Syntax:
status_check = false;
if keyboard_check_pressed(vk_button)
{
status_check = true;
if var_ai_com_open // boolean
{
do action...
status_check = false;
}
if status_check
{
if !var_ai_com_open // boolean
{
do action...
}
}
}

However, when dealing with complex menus, such as this, my current method is far too hairy and not-straight-forward enough for my tastes.

I would give anyone a ton of props if they showed me an elegant approach to the boolean flicker problem.

------------------------------------------------------------------------ CREATE ---------------------------------------------------------
/// Menu CTRL Init

var_screen_num = 0;

state_game_paused = 0;
var_pause_status_check = 1;


var_ai_com_open = 0;
var_ai_com_status_check = 1;

var_setting_status_check = 1;
var_show_all_players = 1;
var_show_player = 0;
var_single_player = 0;

var_not_single_player = 0;
var_not_settings = 0;

var_change_setting = 0;
var_settings = 9999;

var_show_ai_01 = "off";
var_show_ai_02 = "off";
var_show_ai_03 = "off";
var_show_ai_04 = "off";
var_show_ai_05 = "off";
var_show_ai_06 = "off";
var_show_ai_07 = "off";


------------------------------------------------------------------------ STEP -------------------------------------------------------------
/// AI Com Menu CTRL

if keyboard_check_pressed(vk_tab)
{
var_ai_com_status_check = true;
if var_ai_com_open
{
with (obj_menu_ai_com)
{
instance_destroy();
}
var_ai_com_open = false;
var_single_player = false;
var_show_all_players = false;
var_ai_com_status_check = false;
}
if var_ai_com_status_check
{
if !var_ai_com_open
{
instance_create(view_xview[0] + 0, view_yview[0] + 20, obj_menu_ai_com);
var_ai_com_open = true;
var_show_all_players = true;
var_single_player = false;
}
}
}

var_not_settings = 0;

if var_show_all_players
{
switch (keyboard_key)
{
case vk_numpad1:
case ord("1"):
var_show_player = 0;
var_single_player = 1;
var_show_all_players = 0;
var_not_single_player = 0;
var_settings = 0;
break;
case vk_numpad2:
case ord("2"):
var_show_player = 1;
var_single_player = 1;
var_show_all_players = 0;
var_not_single_player = 0;
var_settings = 0;
break;
case vk_numpad3:
case ord("3"):
var_show_player = 2;
var_single_player = 1;
var_show_all_players = 0;
var_not_single_player = 0;
var_settings = 0;
break;
case vk_numpad4:
case ord("4"):
var_show_player = 3;
var_single_player = 1;
var_show_all_players = 0;
var_not_single_player = 0;
var_settings = 0;
break;
case vk_numpad5:
case ord("5"):
var_show_player = 4;
var_single_player = 1;
var_show_all_players = 0;
var_not_single_player = 0;
var_settings = 0;
break;
case vk_numpad6:
case ord("6"):
var_show_player = 5;
var_single_player = 1;
var_show_all_players = 0;
var_not_single_player = 0;
var_settings = 0;
break;
case vk_numpad7:
case ord("7"):
var_show_player = 6;
var_single_player = 1;
var_show_all_players = 0;
var_not_single_player = 0;
var_settings = 0;
break;
case vk_numpad8:
case ord("8"):
var_show_player = 7;
var_single_player = 1;
var_show_all_players = 0;
var_not_single_player = 0;
var_settings = 0;
break;
case vk_numpad9:
case ord("9"):
var_show_player = 8;
var_single_player = 1;
var_show_all_players = 0;
var_not_single_player = 0;
var_settings = 0;
break;
}
}
if !var_not_single_player
{
if var_single_player
{
var_settings = 0;
var_not_settings = 1;
var_change_setting = 9999;
switch (keyboard_key)
{
case vk_numpad1:
case ord("1"):
var_change_setting = 1;
var_settings = 1;
var_not_settings = 0;
break;
case vk_numpad2:
case ord("2"):
var_change_setting = 2;
var_settings = 1;
var_not_settings = 0;
break;
case vk_numpad3:
case ord("3"):
var_change_setting = 3;
var_settings = 1;
var_not_settings = 0;
break;
case vk_numpad4:
case ord("4"):
var_change_setting = 4;
var_settings = 1;
var_not_settings = 0;
break;
case vk_numpad5:
case ord("5"):
var_change_setting = 5;
var_settings = 1;
var_not_settings = 0;
break;
case vk_numpad6:
case ord("6"):
var_change_setting = 6;
var_settings = 1;
var_not_settings = 0;
break;
case vk_numpad7:
case ord("7"):
var_change_setting = 7;
var_settings = 1;
var_not_settings = 0;
break;
case vk_numpad0:
case ord("0"):
var_change_setting = 9999;
var_settings = 0;
var_show_all_players = 1;
var_single_player = 0;
var_not_settings = 0;
break;
}
if !var_not_settings
{
if var_settings
{
if var_change_setting != 0
{
if obj_ai_master_settings.arr_player_object[var_show_player, 1] = 0 var_show_ai_01 = "off";
else var_show_ai_01 = "on";
if obj_ai_master_settings.arr_player_object[var_show_player, 2] = 0 var_show_ai_02 = "off";
else var_show_ai_02 = "on";
if obj_ai_master_settings.arr_player_object[var_show_player, 3] = 0 var_show_ai_03 = "off";
else var_show_ai_03 = "on";
if obj_ai_master_settings.arr_player_object[var_show_player, 4] = 0 var_show_ai_04 = "off";
else var_show_ai_04 = "on";
if obj_ai_master_settings.arr_player_object[var_show_player, 5] = 0 var_show_ai_05 = "off";
else var_show_ai_05 = "on";
if obj_ai_master_settings.arr_player_object[var_show_player, 6] = 0 var_show_ai_06 = "off";
else var_show_ai_06 = "on";
if obj_ai_master_settings.arr_player_object[var_show_player, 7] = 0 var_show_ai_07 = "off";
else var_show_ai_07 = "on";

var_setting_status_check = true;
if var_show_ai_05 = "on"
{
obj_ai_master_settings.arr_player_object[var_show_player, var_change_setting] = 0;
var_setting_status_check = false;
}
if var_setting_status_check
{
if var_show_ai_05 = "off"
{
obj_ai_master_settings.arr_player_object[var_show_player, var_change_setting] = 1;
}
}
}
if var_change_setting = 0
{
var_single_player = false;
var_show_all_players = true;
}
}
}
}
}
 
Last edited by a moderator:

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
Well, first things first, maybe it would be a good idea to make things that are exact replicas with one bit changed to be handled with a for-loop instead;
Having a numeric suffix in names of a number of variables is a pretty good symptom of it being possible to replace them with an array (and another for-loop).
That should reduce the line count a bit.

Flickering is due to fact that you are using keyboard_key (which indicates first of currently held buttons) instead of keyboard_check_pressed to test specific buttons.
 
Top