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

GameMaker Gamepad slower than keyboard inputs? {SOLVED}

Chaser

Member
Quick question, i have my player with keyboard controls, and the i added the gamepad inputs. Simple variable, keyboard true use keyboard keys, if gamepad true, use controller inputs.
So,
hspeed is set to 1, press up on the arrow key, it moves up at a speed of 1. :)
however, move to gamepad input and the speed is a lot slower, i was curious as to what it might be? the hspeed set has not changed, only the 'key press'. So have i missed something that i haven't accounted for, like, a statement in the manual somewhere where this is normal behaviour from GMS.

Is there a difference between keyboard_check(vk_up) and gamepad_button_check(0,gp_padu), im going to assume more checks somewhere causing a slow down? I dunno, any suggestions would be cool.
Thanks. :)
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
A boolean value of true or false is a boolean value of true or false regardless of the function that generated it. So a button being pressed or a key being pressed both generate a true/false return... the issue must be elsewhere so it might be a good idea to show us the actual code. :)
 

kburkhart84

Firehammer Games
In theory, its possible that keyboard_check() is faster than gamepad_button_check(). I also know that there was supposedly an issue with checking gamepad input on a disconnected gamepad causing slowdowns, though that seems to not be your issue going by the idea that you say the thing still moves, just slower. However, I'd have to see the thing in action to know, or get more information. Is it just that one object that is suddenly slower, or does the whole game slow down? And yes, please supply the code that actually moves the thing too, as well as the code you are using to check the inputs.
 

Chaser

Member
OK, im running a script which the player object calls.

SCRIPT (player step event)
if global.keyboard = true
{
key_up = keyboard_check(vk_up);
key_up_p = keyboard_check_pressed(vk_up);
key_up_r = keyboard_check_released(vk_up);

key_down = keyboard_check(vk_down);
key_down_p = keyboard_check_pressed(vk_down);
key_down_r = keyboard_check_released(vk_down);

key_right = keyboard_check(vk_right);
key_right_p = keyboard_check_pressed(vk_right);
key_right_r = keyboard_check_released(vk_right);

key_left = keyboard_check(vk_left);
key_left_p = keyboard_check_pressed(vk_left);
key_left_r = keyboard_check_released(vk_right);

key_action_1 = keyboard_check(ord("Z"));
key_action_1_p = keyboard_check_pressed(ord("Z"));
key_action_1_r = keyboard_check_released(ord("Z"));

key_action_2 = keyboard_check(ord("X"));
key_action_2_p = keyboard_check_pressed(ord("X"));
key_action_2_r = keyboard_check_released(ord("X"));

key_enter = keyboard_check(vk_enter);
key_enter_p = keyboard_check_pressed(vk_enter);
key_enter_r = keyboard_check_released(vk_enter);

key_space = keyboard_check(vk_space);
key_space_p = keyboard_check_pressed(vk_space);
key_space_r = keyboard_check_released(vk_space);

key_back = keyboard_check(vk_escape);
key_back_p = keyboard_check_pressed(vk_escape);
key_back_r = keyboard_check_released(vk_escape);

key_nokey = keyboard_check(vk_nokey);

}

else

if global.gamepad = true
{

key_up = gamepad_button_check(0,gp_padu);
key_up_p = gamepad_button_check_pressed(0,gp_padu);
key_up_r = gamepad_button_check_released(0,gp_padu);

}

That OK? not sure how should of posted it, il be more than happy to give the actual project file, theres nothing in the game as yet, just trying to do the control stuff. :)
 

Chaser

Member
Idle 'State'
hspeed = 0;
vspeed = 0;


if key_up
{
image_index = 0;
vspeed = -1;
behaviour = behaviour.P1_walkup;
}

if key_down
{
image_index = 0;
vspeed = 1;
behaviour = behaviour.P1_walkdown;
}

if key_right
{
hspeed = 1;
image_index = 0;
behaviour = behaviour.P1_walkright;
}

if key_left
{
hspeed = -1;
image_index = 0;
behaviour = behaviour.P1_walkleft;
}

Walkup 'state'

vspeed = -1;

if key_right
{
hspeed = 0;
vspeed = 0;
image_index = 0;
behaviour = behaviour.P1_walkupright;
}
else
if key_left
{
hspeed = 0;
vspeed = 0;
image_index = 0;
behaviour = behaviour.P1_walkupleft;
}
else
if key_down
{
hspeed = 0;
vspeed = 0;
image_index = 0;
behaviour = behaviour.P1_walkdown;
}



if key_nokey
{
vspeed = 0;
hspeed = 0;
image_index = 0;
behaviour = behaviour.P1_idle;
}


Each 'state' is calling the control script, im sure you probably knew that. :) obviously there are another 7 'states' but im sure you don't want me to paste them all here.

Thank you for taking the time. :)
 

Chaser

Member
I think its something in the step event, you can see it changing states very quickly when using the gamepad, but doesn't do it when using keyboard.
 

kburkhart84

Firehammer Games
I only see the one button being checked for the gamepad section...if you are simply excluding that code for saving time, that's one thing...but if not, then I bet that is the problem. I don't see anything setting that "no key" variable you have, meaning there is something different going on. Also, I have never used the vk_nokey constant, I can't vouch for sure that it works as you would like at all, but I can't say it doesn't either as I've never used it either way.
 

Chaser

Member
Yes one button for up, that was as far as i got, because it wasn't working as i expected, so i wanted to get to the bottom of this issue before i moved on to the other button presses.
'key_nokey' sets the 'no_key' you mentioned. there isn't one for the gamepad from what i can see.(seems automatically checked) so thats not in the gamepad control script. i often find i have to use the 'vk_nokey' function, or my player wont stop moving when any button gets released. :)
 

Nidoking

Member
If you're not setting the nokey constant when you're using the gamepad, then checking it is going to cause all kinds of havoc. You need to complete all of the parts of the input that you're using if you want to get meaningful results.
 

Nidoking

Member
I'm not saying you need to find a function that does it. I'm saying that you're checking the value of a variable that you're not setting. You can't use a variable if you don't set the variable. You can either find a way to set your no_key variable based on the other inputs, or you can not use the variable that you're not setting. But you can't leave it at one default value and then check it as if it's going to tell you something meaningful, because it's not.
 

Chaser

Member
i haven’t set a variable for nokey in the control input, nor am I calling one. So I’m a little confused by what your saying buddy.when the controller input is being used it seems to automatically detect if a button is pushed or not, when I release a button the player automatically stops. When the players vspeed is set to 1 it moves slower then if the vk_up was pressed, same code just different function calls, perhaps it is the nokey part, but I’m not calling it during the control input.:)
 

Roldy

Member
So I’m a little confused by what your saying buddy.
In your walk state you check your no_key variable. However you don't set that variable when using a controller. So what is the value of no_key if you are not setting it?

If no_key == true then most likely you would move at half speed while using a controller because it would constantly be flipping between idle and walk_state.

Read your code. That is what you are asking it to do.

Try setting no_key to true if you have no controller input, else set it false.
 

Chaser

Member
Oh I see, it’s checking no key, even though it’s not being used when using the controller input, but it’s still checking for it. Gotcha. That makes sense, Thank you very much, il try it tomorrow. :)
 

kburkhart84

Firehammer Games
What I do instead of checking for "no key" like this, is in my movement code, I set a variable that assumes no movement is happening at the start. var didIMove = false; or similar. Then, I check the directions I could move in...in each one, if it is true, then I also set that variable to true. Finally, at the end, I simply check that variable and stop moving if needed. This comes in handy in situations, like if you want to only apply friction if you are not actually inputting anything. Its easier to calculate movement acceleration if friction isn't involved, so I simply turn off the friction if I'm not inputting movement, and turn it back on once input stops.

Another thing you might want to look into....a better input system. Right now, you are hard coding inputs, and simply flipping between keyboard and gamepad. What happens if the player wants to use a different key for movement, etc... or do different buttons for different things on the gamepad...or worse, what if the player wants to combine gamepad with keyboard? I've actually seen it where someone likes the axes of some gamepad but not the buttons, or the other way around, and so they want to configure controls to do that. So many games limit inputs for a player to single devices, and that's a shame. My input system has no limits like that...and it works all on its own, including the value of the input, and the "pressed" and "released" values that you currently are checking for. And it lets input be a complete separate system, which can then be accessed from whatever objects need it. This way, objects can be destroyed, changed, whatever, and as long as they access the input system, it just works, no dependencies on anything, and no hard-coded inputs either.
 

Chaser

Member
Thanks for the help. I will in the future consider what you mention about a more ‘universal’ control method, when I’m a bit less novice at coding.:) my focus is 8 bit and 16 bit games, so I’m happy with just the dpad and a couple of buttons at the moment, anything else right now is out of my scope of my experience and game ideas.
Appreciate your help and comments. Thank you.:)
 

Roleybob

Member
I tend to do something like this for controlling player movement input:

GML:
var h_dir = 0;
var v_dir = 0;

h_dir = (((keyboard_check(vk_right)) || (gamepad_button_check(0,gp_padr))) - ((keyboard_check(vk_left)) || (gamepad_button_check(0,gp_padl))));

v_dir = (((keyboard_check(vk_down)) || (gamepad_button_check(0,gp_padd))) - ((keyboard_check(vk_up)) || (gamepad_button_check(0,gp_padu))));
This will store -1, 0 or 1 in h_dir and similar for v_dir, and done in just a couple of lines of code instead of a whole page like you have above. The code is basically saying:

"If the player is pressing either the right arrow or right on the gamepad (or both), set h_dir to 1. If the player is pressing either the left arrow or left on the gamepad (or both), set h_dir to -1. If the player is not pressing any of those buttons, or is pressing left and right at the same time (on arrow keys, gamepad or a combination / both), set h_dir to 0"

And similar with v_dir.

You can easily add other checks so that the player has more ways to control the player character, just follow the form:

h_dir = (AAA or BBB or CCC or DDD) minus (WWW or XXX or YYY or ZZZ);

And it will only ever return a value of 1, 0 or -1

You can then use h_dir and v_dir to control which direction the player moves. For example, in a very simple movement code, you could just do:

GML:
x += h_dir * walk_speed;
y += v_dir * walk_speed;

//walk_speed variable is the number of pixels you want the player character to move in a single step//
 
Last edited:

TheouAegis

Member
First off: NEVER USE vk_nokey unless you are going to unmap the entire keyboard, and even then I'm not sure if it would still be good. It has about as much use as vk_anykey, and that is it's primarily only useful as the inverse of vk_anykey. If you use vk_nokey, your project will glitch out hard, I guarantee it.

Create Event:
Code:
enum keys {
    right = 1,
    up = 2,
    left = 4,
    down = 8,
    action_1 = 16,
    action_2 = 32,
    space = 64,
    enter = 128,
    back = 256,    //for 8-bit games, you wouldn't go past 128
}
input = 0;
input_prev = 0;
input_press = 0;
input_release = 0;
Begin Step Event:
Code:
input_prev = input;

//call your script that checks the keyboard or gamepad here (not in the Step Event)

input = ( ( ( ( ( ( ( key_back * 2 + key_enter ) * 2 + key_space ) * 2 + key_action_2 ) * 2 + key_action_1) * 2 + key_down) * 2 + key_left) * 2 + key_up ) * 2 + key_right;
//that's n-2 parentheses at the beginning, where n is how many keys you have
//by the way, you have 1 too many keys for an 8-bit game lol
input_press = input | input_prev ^ input_prev;
input_release = input | input_prev ^ input;
Now if you want to check if NONE OF THE KEYS are pressed, just check if input==0. If you want to check if none of the direction keys are pressed, check if input & 15 == 0.

If you want to check which keys were "pressed" this step, use input_press.
If you want to check which keys were "released" this step, use input_release.
To check if a specific key is held, pressed, or released, & the proper variable with the proper enum. E.g.:

if input & keys.action_1 {
 

Chaser

Member
Thanks everyone here for the comments and giving their approach to handling directional movement via keyboard and/or gamepad. I have got it working as intended, still using 'no_key'. :) I will look into the other ways you have mentioned in the future, when i'm more 'versed' in GML. At the moment i'm quite happy using 'no_key' for the time being for my little project, Shock horror to some i'm sure, but i'm just comfortable with it. :)
 
Top