display keys

Tales

Member
Hello!

I cant see "vk_shift" when I try draw keys txt.

I declare on Hero obj
KEYESQU = 'vk_shift';

I draw on MENU obj
draw_text(x+350,y+58+110,string(Hero.KEYESQU))

this works, no problem, the problem comes when I change the KEYESQU :

In the menu object I have:
if keyboard_check_pressed(vk_anykey) and touche17=3 {Hero.KEYESQU=chr(keyboard_lastkey);touche17=1}

I know one time I have a string and the other I have a chr, but the key still works in the game it a draw problem. I get confused with the passage from string to char. I already try different combinaison but I fail. What I forgot to see again "vk_shift" plz?
 

Nidoking

Member
KEYESQU = 'vk_shift';
The string "vk_shift" has nothing to do with the constant vk_shift. I'm going to go out on a limb and say you should be using the constant, especially since you already have it wrapped in string() when you pass it to draw_text. How that will interact with chr, I have no idea, but I'm certain you'll need to start there and figure out the rest from that point.
 

Tales

Member
if I put ' ' for 'vk_shift' its to see it in the draw, and it works.. the key and display. But if I change, I dont see it anymore. Its blank.
The "Hero.KEYESQU=chr(keyboard_lastkey) " works (the game is ok) but the "draw_text(x+350,y+58+110,string(Hero.KEYESQU)) " gone blank.


EDIT if I put KEYESQU = vk_shift
"draw_text(x+350,y+58+110,string(Hero.KEYESQU)) " writte the number 16 (the key number) and the game dont works anymore.

I should add I use this after keyboard_check_released(KEYESQU) in the Hero obj
 

Nidoking

Member
Like I said, there are other things you'll need to fix once you're properly using the numeric constant for the key. Have you considered not using chr?
 

Tales

Member
OK correction I can have number everywhere and keys works, but I have number everywhere in the draw
 
Last edited:
Look, 16 is what vk_shift is. vk_shift is literally just a constant that stands in for the number 16. It doesn't stand for "shift" or "vk_shift" or any other string. If you want to print the name of the key being pressed for a key bindings section or something, then you can't just print vk_shift, you actually have to do a lot of work:
Code:
var str = "";
switch (Hero.KEYESQU) {
   case vk_shift:
      str = "Shift";
   break;
}
draw_text(x,y,str);
That will print "Shift" if Hero.KEYESQU is set to vk_shift. If you want it to show the name of all the other keys, you have to add a new case and then set a variable to the typed name of that key (such as str = "A" for the case ord("A"): or str = "Delete" for case vk_delete: ).

If your player controls actually controlled the player with Hero.KEYESQU being set to an actual string, then you'll need to rewrite the way you have coded your input, because that is very wrong and is not compatible with key bindings.
 
Last edited:

Tales

Member
Yep thanks, I thought about it but I dont gonna do ALL keyboard keys like this .. GML can tell vk_shift is 16 but there is no function that do the invert?

they keybinding works good till the begining, its only the display that show numbers now (still better than nothing at the begining )
 
No, because vk_shift doesn't have any relationship to the string "Shift". It would be nice if there were a function, but there isn't, so it has to be done manually.
 

Tales

Member
I guess I need to keep the 'chr' part for all "A B C D" and make exception for shift, alt, ctrl, and space. "Classic keys".. I guess nobody gonna use DELETE or ENTER to jump.. its heretic.. ^^

Thanks NIDOKING and REFRESHERTOWEL!! :)
 

kburkhart84

Firehammer Games
Your issue here is that any key on the keyboard that doesn't directly correspond to a printed ASCII text character will not work with chr(), at least not the way you would want it to. If you are going to let the player customize the input(which I promise is a good thing), you need to account for all those possible keys, which include the whole top row, ctrl, alt, shift, arrows, and some others as well. My solution is simply to not use the chr() function at all. Instead I have code that returns a nice description of the key simply based on the keyboard key constant. This is the solution I'm using in my input system. The only catch right now is that I still have to verify and add systems to handle different regions of keyboards that aren't American English, but besides that glitch, it should get you started. Just change _fhinputKeys to whatever you prefer, and make it not global if you want. Note that I also put "Unknown" all over the array in case someone has an esoteric keyboard with multimedia buttons or something, so you can still support those as inputs if you want to without knowing what they are called. Then, just access the array with index of whatever the keyboard constant is to get a nice string, and this should technically be faster even then calling the chr() function.

Code:
for(var i = 0; i < 256; i++)
{
    global._fhinputKeys[i] = "Unknown";
}
global._fhinputKeys[vk_escape] = "Escape";
global._fhinputKeys[vk_f1] = "F1";
global._fhinputKeys[vk_f2] = "F2";
global._fhinputKeys[vk_f3] = "F3";
global._fhinputKeys[vk_f4] = "F4";
global._fhinputKeys[vk_f5] = "F5";
global._fhinputKeys[vk_f6] = "F6";
global._fhinputKeys[vk_f7] = "F7";
global._fhinputKeys[vk_f8] = "F8";
global._fhinputKeys[vk_f9] = "F9";
global._fhinputKeys[vk_f10] = "F10";
global._fhinputKeys[vk_f11] = "F11";
global._fhinputKeys[vk_f12] = "F12";
global._fhinputKeys[145] = "Scroll Lock";
global._fhinputKeys[vk_pause] = "Pause";
global._fhinputKeys[192] = "Tilde(~)";
global._fhinputKeys[49] = "1";
global._fhinputKeys[50] = "2";
global._fhinputKeys[51] = "3";
global._fhinputKeys[52] = "4";
global._fhinputKeys[53] = "5";
global._fhinputKeys[54] = "6";
global._fhinputKeys[55] = "7";
global._fhinputKeys[56] = "8";
global._fhinputKeys[57] = "9";
global._fhinputKeys[48] = "0";
global._fhinputKeys[189] = "Dash(-)";
global._fhinputKeys[187] = "Equals(=)";
global._fhinputKeys[vk_backspace] = "Backspace";
global._fhinputKeys[65] = "A";
global._fhinputKeys[66] = "B";
global._fhinputKeys[67] = "C";
global._fhinputKeys[68] = "D";
global._fhinputKeys[69] = "E";
global._fhinputKeys[70] = "F";
global._fhinputKeys[71] = "G";
global._fhinputKeys[72] = "H";
global._fhinputKeys[73] = "I";
global._fhinputKeys[74] = "J";
global._fhinputKeys[75] = "K";
global._fhinputKeys[76] = "L";
global._fhinputKeys[77] = "M";
global._fhinputKeys[78] = "N";
global._fhinputKeys[79] = "O";
global._fhinputKeys[80] = "P";
global._fhinputKeys[81] = "Q";
global._fhinputKeys[82] = "R";
global._fhinputKeys[83] = "S";
global._fhinputKeys[84] = "T";
global._fhinputKeys[85] = "U";
global._fhinputKeys[86] = "V";
global._fhinputKeys[87] = "W";
global._fhinputKeys[88] = "X";
global._fhinputKeys[89] = "Y";
global._fhinputKeys[90] = "Z";
global._fhinputKeys[219] = "L Bracket([)";
global._fhinputKeys[221] = "R Bracket(])";
global._fhinputKeys[220] = "Backslash(\\)";
global._fhinputKeys[20] = "Capslock";
global._fhinputKeys[186] = "Semi-Colon(;)";
global._fhinputKeys[222] = "Apostrophe(')";
global._fhinputKeys[13] = "Enter";
global._fhinputKeys[160] = "L Shift";
global._fhinputKeys[161] = "R Shift";
global._fhinputKeys[162] = "L Control";
global._fhinputKeys[163] = "R Control";
global._fhinputKeys[164] = "L Alt";
global._fhinputKeys[165] = "R Alt";
global._fhinputKeys[188] = "Comma(,)";
global._fhinputKeys[190] = "Period(.)";
global._fhinputKeys[191] = "Slash(/)";
global._fhinputKeys[vk_space] = "Spacebar";
global._fhinputKeys[93] = "Apps";
global._fhinputKeys[vk_insert] = "Insert";
global._fhinputKeys[vk_home] = "Home";
global._fhinputKeys[vk_pageup] = "Page Up";
global._fhinputKeys[vk_delete] = "Delete";
global._fhinputKeys[vk_end] = "End";
global._fhinputKeys[vk_pagedown] = "Page Down";
global._fhinputKeys[144] = "Numlock";
global._fhinputKeys[111] = "Numpad Slash(/)";
global._fhinputKeys[106] = "Numpad Asterisk(*)";
global._fhinputKeys[109] = "Numpad Dash(-)";
global._fhinputKeys[vk_numpad0] = "Numpad 0";
global._fhinputKeys[vk_numpad1] = "Numpad 1";
global._fhinputKeys[vk_numpad2] = "Numpad 2";
global._fhinputKeys[vk_numpad3] = "Numpad 3";
global._fhinputKeys[vk_numpad4] = "Numpad 4";
global._fhinputKeys[vk_numpad5] = "Numpad 5";
global._fhinputKeys[vk_numpad6] = "Numpad 6";
global._fhinputKeys[vk_numpad7] = "Numpad 7";
global._fhinputKeys[vk_numpad8] = "Numpad 8";
global._fhinputKeys[vk_numpad9] = "Numpad 9";
global._fhinputKeys[110] = "Numpad Period(.)";
global._fhinputKeys[107] = "Numpad Plus(+)";
global._fhinputKeys[vk_left] = "Left Arrow";
global._fhinputKeys[vk_right] = "Right Arrow";
global._fhinputKeys[vk_up] = "Up Arrow";
global._fhinputKeys[vk_down] = "Down Arrow";
I guess nobody gonna use DELETE or ENTER to jump.. its heretic.. ^^
FYI, the best thing you can do is to NOT assume somebody isn't going to use any given key for something. It may not be likely in the case of jumping, but if its me, I put the input code in a separate system, object, whatever, and then re-use it in all my games(hence my input system). And you may make a game in the future that needs more keys, where some of those options aren't as likely. Simply put, even for now, if you are going to support players choosing input, you should go all the way and support the whole keyboard(unless you reserve a couple keys for your game stuff, like escape to pause and go to the menu).

Another thought, are you handling gamepads? If you make a good system, it can handle gamepads behind the scenes. The idea is to totally separate the input from the game. You have objects that handle input, including knowing what key, or gamepad button/axis, is assigned to the game's actions(jump, run, move left, whatever). Then, your game object, like the player, only checks that system for the status of the jump action to know whether to jump or not, and doesn't care about what input is actually driving the jump action status. In my input system, besides handling all gamepads and mouse buttons along with the keyboard, I support multiple players with the same actions. I also constantly store the status of the raw value of the input(in case its an axis and you want to modify the movement based on such). Then it stores the "just pressed" and "just released" values, so that you don't have to handle that in the code for the player(to avoid repeated inputs where not wanted). It even stores a timer for how long the input is being held down(in steps and in seconds) for if you want to do a charging animation(like Megaman's weaponry). And the best part is that the game's objects don't know or care where this input is coming from. I can make the player objects all separate from the input. This allows me to do something as robust as turning off input device polling and letting the code directly direct the status of the inputs(for example to have an AI do it). Then the AI version of the objects can be the same as the player version, just checking a different player's actions, which are driven by code instead of physical devices.
 

Tales

Member
wow its a lot of words.. and keys... Thanks I gonna check the code, its perfectly what I search to know which key which number etc

No I dont think to put some gamepad because the game not thinking for this, too much thing to "click". You dont control only a char who jump. There is his startship and "lot" of controler to puch. Switching it to gamepad would take far too long and it would be uncomfortable, I think.

thank you
 

kburkhart84

Firehammer Games
If you had an input system that handled it, and made your objects separate from that, it wouldn't be an issue at all. My input system uses basically a list of "actions" that can be done, and then behind the scenes it knows what inputs to check based on the custom mapping(which can easily be changed). So if the "attack" action is set to spacebar, that gets checked, if its the R button on some gamepad, that gets checked. Then, your games objects don't have to know anything about what is actually driving the "attack" action, they only call up the input system and ask what is going on with the action, if it is down or not(in my input engine I also store status for just this step pressed and released, as well as time held down in steps and in seconds, in case you wanted to use that info to charge up a weapon or something).

The point I make is to completely decouple the input system from the objects that use it. Its a good concept to understand. Then, later on, you could easily sub in AI instead of the input system(my system supports this), and the objects don't have to know the difference, as they only check whether they should attack or not and don't care what is driving that attack, whether it is a button or some AI. And the same applies for multiple players, as they can use the same objects and you only point the players' object instances to the correct input system(in my input system I have a concept of players and each player has its own action list).

Note that this concept applies everywhere else as well. Quite often, you want to separate things in code, and have any specific object do just one and only one thing. For example, the player shouldn't really control its stats(or inputs), rather it should simply draw itself, and access other systems to know what it should do, like how high it can jump(if that's a stat). It shouldn't know how many lives are left, how many points it has, or anything like that. You would want a separate controller object for those things. This lets you have things in proper places, so its easier to create, and easier to change/maintain later. Keeping things separate also makes it easier to re-use code/objects both in the same project and in other future projects. My input system is designed to be useful basically in any project, except possibly something that is literally completely mouse dependent, point and click, things like that.
 
Top