Legacy GM [SOLVED] 2D Array skill tree menu

I

Ian

Guest
Trying to create a skill tree and thought 2D arrays would be my best bet and so far everything works fine except i want a part of the menu controller code to be more efficient.

Heres how the menu functions:

And heres the code:

///Create event:
Code:
menu[0,0] = spr_gui_opt;
menu[0,1] = spr_gui_opt;
menu[0,2] = spr_gui_opt;
menu[0,3] = spr_gui_opt;
menu[0,4] = spr_gui_opt;
menu[0,5] = spr_gui_opt;
menu[0,6] = spr_gui_opt;

menu[1,0] = spr_gui_opt1;
menu[1,1] = spr_gui_opt1;
menu[1,2] = spr_gui_opt1;


menu[2,0] = spr_gui_opt1;
menu[2,1] = spr_gui_opt1;
menu[2,2] = spr_gui_opt1;
menu[2,3] = spr_gui_opt1;
menu[2,4] = spr_gui_opt1;

menu[3,0] = spr_gui_opt1;
menu[3,1] = spr_gui_opt1;
menu[3,2] = spr_gui_opt1;
menu[3,3] = spr_gui_opt1;
menu[3,4] = spr_gui_opt1;
menu[3,5] = spr_gui_opt1;
menu[3,6] = spr_gui_opt1;

menu[4,0] = spr_gui_opt1;
menu[4,1] = spr_gui_opt1;
menu[4,2] = spr_gui_opt1;
menu[4,3] = spr_gui_opt1;
menu[4,4] = spr_gui_opt1;

menu[5,0] = spr_gui_opt1;
menu[5,1] = spr_gui_opt1;
menu[5,2] = spr_gui_opt1;
menu[5,3] = spr_gui_opt1;
menu[5,4] = spr_gui_opt1;

menu[6,0] = spr_gui_opt1;
menu[6,1] = spr_gui_opt1;
menu[6,2] = spr_gui_opt1;
menu[6,3] = spr_gui_opt1;
menu[6,4] = spr_gui_opt1;

mpos = 0;
array_index = 0;
space = 48;
///Step event
Code:
//Menu controller
if(alarm[0] <= 0)
{
    if(down_key)
    {
        if(mpos < array_length_2d(menu,array_index) - 1)
        {
            mpos++;
        }
        alarm[0] = room_speed/6;
    }
    if(up_key)
    {
        if(mpos > 0)
        {
            mpos--;
        }
        alarm[0] = room_speed/6;
    }
   
    if(right_key)
    {  
                if(mpos <= array_length_2d(menu,array_index+1)-1)
                {
                    array_index += 1;
                }
                else if(mpos <= array_length_2d(menu,array_index+2)-1)
                {
                    array_index += 2;
                }
                else if(mpos <= array_length_2d(menu,array_index+3)-1)
                {
                    array_index += 3;
                }
    }
   
    if(left_key)
    {
           //Havent coded this yet, only testing but will be the opposite of right_key
    }
}
///GUI Event
Code:
draw_set_font(-1);
var xx, yy;
draw_set_halign(fa_left);
draw_set_valign(fa_middle);

draw_text(0,20,"mpos:"+string(mpos));
draw_text(0,40,"array_index:"+string(array_index));

for(i = 0; i < array_height_2d(menu); i++;)
{
    for(m = 0; m < array_length_2d(menu,i); m++;)
    {
        draw_sprite(menu[i,m],0,x+(i*space),y+(m*space));
        if(m == mpos) draw_sprite(spr_gui_opt_active,0,x+(array_index*space),y + (m * space));
    }
}

Var info:
mpos (stands for menu pos): holds which row we are in
array_index: basically holds which column we are in
space: used in the draw event to space each menu item out.


Problem:
Everything works but i do not like how i coded the menu controller for the right_key input.
Tried to come up with a loop:
Code:
if(right_key)
    {  
            for (i = 0; i < array_height_2d(menu); i++)
            {
                if(mpos <= array_length_2d(menu,array_index+i)-1)
                {
                    array_index += i;
                }
             
            }
        alarm[0] = room_speed/6;
    }
Didnt work and i cant seem to come up with new logic, see i want it to where if u go to the next column over and that column doesnt reach far enough to where u are it checks if the next column is long enough and if so changes the array_index to that column (shown in gif). Pretty odd and small problem but cant seem to come with efficient logic for it.
 

jo-thijs

Member
How about this?
Code:
if right_key
    { 
            for (var i = array_index; i < array_height_2d(menu); i++)
            {
                if mpos < array_length_2d(menu, i)
                {
                    array_index = i;
                    break;
                }
            }
        alarm[0] = room_speed / 6;
    }
 

Simon Gust

Member
Hi,
There sure are some things that could be tried.
In the create event you can also use loops to initialize arrays.
For your right key problem, instead of doing it manually, do it automatically so that the array_index knows if there should be an array positions.
You need to prematurely fill all non-accessable array spots with "noone" for example.
Then when you try to move array_index +1, check if the one where it's going to is noone or not, if it is then jump once more, check again and again until there is no noone anymore
Code:
if right_key
   {
      var index_on_right = menu[@ mpos, array_index+1];
      while (index_on_right == noone && mpos <= array_length_2d(menu,array_index))
      {
         array_index++;
         index_on_right = menu[@ mpos, array_index+1];
      }          
   alarm[0] = room_speed / 6;
}
I gotta say I am a bit confused about how you went on and named your array-positions though. This might not work as intended.
 
I

Ian

Guest
Hi,
There sure are some things that could be tried.
In the create event you can also use loops to initialize arrays.
For your right key problem, instead of doing it manually, do it automatically so that the array_index knows if there should be an array positions.
You need to prematurely fill all non-accessable array spots with "noone" for example.
Then when you try to move array_index +1, check if the one where it's going to is noone or not, if it is then jump once more, check again and again until there is no noone anymore
Code:
if right_key
   {
      var index_on_right = menu[@ mpos, array_index+1];
      while (index_on_right == noone && mpos <= array_length_2d(menu,array_index))
      {
         array_index++;
         index_on_right = menu[@ mpos, array_index+1];
      }        
   alarm[0] = room_speed / 6;
}
I gotta say I am a bit confused about how you went on and named your array-positions though. This might not work as intended.
thanks for the reply and Sorry forgot to put the solved flag on the post, came up with a solution and just had to subtract a value to make it work for the whole menu (previously only worked for half of it with the loop)

As for your optimization point in create event, this was prototyped in 5-10 min so functionality is there just not my optimized touch ups (the code u see is not final).

It works just fine, although im in the middle of scrapping 2D Array for a different DS so i can get more in depth with each option.
How about this?
Code:
if right_key
    {
            for (var i = array_index; i < array_height_2d(menu); i++)
            {
                if mpos < array_length_2d(menu, i)
                {
                    array_index = i;
                    break;
                }
            }
        alarm[0] = room_speed / 6;
    }
Thanks for the reply, subtracting the "array_length_2d(menu, i)-1" and doing array_index += i; is basically it.
 

JeanSwamp

Member
thanks for the reply and Sorry forgot to put the solved flag on the post, came up with a solution and just had to subtract a value to make it work for the whole menu (previously only worked for half of it with the loop)

As for your optimization point in create event, this was prototyped in 5-10 min so functionality is there just not my optimized touch ups (the code u see is not final).

It works just fine, although im in the middle of scrapping 2D Array for a different DS so i can get more in depth with each option.


Thanks for the reply, subtracting the "array_length_2d(menu, i)-1" and doing array_index += i; is basically it.
Hello, I just stumble upon this post through the forum search trying to find ways to navigate a 2d array with keyboard. May I ask how did you manage to solve this? The last reply fix seems not to be working for me!

Thanks :D
 
Top