• 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!

Gamepad Up/Down

I have a menu that I want to move up and down with my gamepad left stick. I'm not sure how to code for it though. Here is how I am doing it successfully with either the keyboard or D-pad on the controller.

I'm guessing I need to do something with gp_axislv, but I can't seem to get it to work.

GML:
//get input
var _up = keyboard_check_pressed(vk_up) || (gamepad_button_check_pressed(0, gp_padu));
var _down = keyboard_check_pressed(vk_down) || (gamepad_button_check_pressed(0, gp_padd));
var _select = keyboard_check_pressed(vk_enter) || (gamepad_button_check_pressed(0, gp_face1));



//move selection
var _move = _down - _up;
if _move != 0 {
    //move the index
    index += _move;

    //clamp values
    var _size = array_length_1d(menu);
    if index < 0 index = _size - 1;        //at start, so loop to menu end
    else if index >= _size index = 0;    //at end, so loop to menu start
}

if _select {
    switch(index) {
        case 0:
            //New Game
            room_goto(Level1);
        break;
        case 1:
            //Continue
            LoadGame(global.gameSaveSlot);
        break;
        case 2:
            //Exit
            game_end();
        break;
    }
}
 

Slyddar

Member
The main problem you face is converting analogue stick movement into single key_press_up and down like values, that are true only the first time the stick is moved in that direction. Once you have that, you can use it with an OR to set your _move variable correctly.

So essentially you need to capture ls_up_pressed and ls_down_pressed. You can do that by also capturing ls_up_held and ls_down_held, as the step you set the held variables to true, where they were set to false previously, is the step that the pressed variables are also true for that step.
 
This is how I've done it in my menu system...
GML:
var menuVStick = gamepad_axis_value(global.gamepad, gp_axislv);
if menuVStick !=0 and !alarm[0]{
    if menuVStick < 0 menuVStick = -1 else menuVStick = 1;
    menuIndex += menuVStick;
    alarm[0] = 15;
}
The alarm doesn't have any code in it but it just stops the menu from being over sensitive to input.
global.gamepad is just my variable for keeping track of the gamepad in use.
Hope that helps in some way.

[edit] removed a redundant line.
 
Last edited:
This is how I've done it in my menu system...
GML:
var menuVStick = gamepad_axis_value(global.gamepad, gp_axislv);
if menuVStick !=0 and !alarm[0]{
    if menuVStick < 0 menuVStick = -1 else menuVStick = 1;
    menuIndex += menuVStick;
    alarm[0] = 15;
}
The alarm doesn't have any code in it but it just stops the menu from being over sensitive to input.
global.gamepad is just my variable for keeping track of the gamepad in use.
Hope that helps in some way.

[edit] removed a redundant line.
Thanks for the code snippet. It's only letting me move up or down one time though. Not sure what I'm missing.
 
Hmm... That should work as it is. Could you post your code again with the new bit added.
Sure no problem. Sorry about that I should have thought to before.

GML:
//get input
var _up = keyboard_check_pressed(vk_up) || (gamepad_button_check_pressed(0, gp_padu));
var _down = keyboard_check_pressed(vk_down) || (gamepad_button_check_pressed(0, gp_padd));
var _select = keyboard_check_pressed(vk_enter) || (gamepad_button_check_pressed(0, gp_face1));
var menuVStick = gamepad_axis_value(0, gp_axislv);

if menuVStick !=0 and !alarm[0]{
    if menuVStick < 0 menuVStick = -1 else menuVStick = 1;
    index += menuVStick;
    alarm[0] = 15;
}

//move selection
var _move = _down - _up;
if _move != 0 {
    //move the index
    index += _move;

    //clamp values
    var _size = array_length_1d(menu);
    if index < 0 index = _size - 1;        //at start, so loop to menu end
    else if index >= _size index = 0;    //at end, so loop to menu start
}

if _select {
    switch(index) {
        case 0:
            //New Game
            room_goto(Level1);
        break;
        case 1:
            //Continue
            LoadGame(global.gameSaveSlot);
        break;
        case 2:
            //Options
            //room_goto(r_game);
        break;
        case 3:
            //Exit
            game_end();
        break;
    }
}
 
OK, looking at my whole code I realise I have other stuff happening.
In the create event of your menu object add the following canMenuMove = true;
Then in the step event change the code to:
GML:
//get input
var _up = keyboard_check_pressed(vk_up) || (gamepad_button_check_pressed(0, gp_padu));
var _down = keyboard_check_pressed(vk_down) || (gamepad_button_check_pressed(0, gp_padd));
var _select = keyboard_check_pressed(vk_enter) || (gamepad_button_check_pressed(0, gp_face1));
var menuVStick = gamepad_axis_value(0, gp_axislv);

//move selection
var _move = _down - _up;
if _move != 0 or (menuVStick !=0 and canMenuMove) {
     if menuVStick < 0 {
         _move = -1 ;
     } else if menuVStick > 0 {
        _move = 1;
     };
     canMove = false;
     alarm[0]=15;
    //move the index
    index += _move;
Then add the following code to the alarm event:
GML:
canMenuMove = true;
That should work :)
 
Top