Priority Keyboard Input

NeoShade

Member
GM Version: GMS2, but should work in any version of GameMaker
Target Platform: All
Download: N/A
Links: N/A

Summary:
Script that checks the pressed and released states of the direction keys and 'remembers' the order in which they were pressed and released. Great for creating an intuitive RPG-style movement so the player can be pressing multiple directions at once, but only the most recent is being used.

Tutorial:
I'm unsure if others will find this useful, but this a little script that I've been using for a few years. Somebody helped me come up with it in a private message conversation on the previous GameMaker Community, and unfortunately private messages are no longer accessible in the archives, so I'm unable to track down exactly who it was, so my apologies to that person.

The idea behind this script is to remember the order in which direction keys (or any keys, really) are pressed and released. It was initally designed to perfectly mimic the style of movement seen in Pokemon games.

Using 4-directional movement as an example, the player could start by holding the up key to have the character move up the screen. They could then also hold the left key without releasing the up key, and the character would start to move left, but when they release the left key the character would resume moving up.

This is achieved by assigning each key a priority value, and having an overall priority that is incremented with each additional key that is pressed. When a key is released, its priority is reset to zero, and the overall priority finds the key with the next highest priority.

Code:
/// INITIALISE VARIABLES SOMEWHERE FIRST

global.pri_key = 0;
global.pri_rt = 0;
global.pri_up = 0;
global.pri_lf = 0;
global.pri_dn = 0;
Code:
/// CALL THIS SCRIPT EACH STEP

// Check input: Right
if keyboard_check_pressed(vk_right) {global.pri_rt = ++global.pri_key}
if keyboard_check_released(vk_right) {global.pri_rt = 0}

// Check input: Up
if keyboard_check_pressed(vk_up) {global.pri_up = ++global.pri_key}
if keyboard_check_released(vk_up) {global.pri_up = 0}

// Check input: Left
if keyboard_check_pressed(vk_left) {global.pri_lf = ++global.pri_key}
if keyboard_check_released(vk_left) {global.pri_lf = 0}

// Check input: Down
if keyboard_check_pressed(vk_down) {global.pri_dn = ++global.pri_key}
if keyboard_check_released(vk_down) {global.pri_dn = 0}

// Calculate most recent input
pri_key = max(global.pri_rt, global.pri_up, global.pri_lf, global.pri_dn, 0);
Code:
/// COMPARE THE pri_key VARIABLE WITH OTHERS

if (pri_key > 0)
    {
    if global.pri_key == global.pri_rt {// Move right}
    if global.pri_key == global.pri_up {// Move up   }
    if global.pri_key == global.pri_lf {// Move left }
    if global.pri_key == global.pri_dn {// Move down }
    }
An advantage of this system over the common {x += key_right - key_left} is that there is no situation where holding multiple keys causes the character to stop moving - they will always move in the direction of the most recently pressed and still held key.

As I said, I don't know if anyone is going to find a use for this, but I think it's a neat little bit of code and I felt like I should share it.
 

chance

predictably random
Forum Staff
Moderator
Interesting idea. I haven't seen this approach used before. And I'm not sure I'd be comfortable with it for 4-directional movement, compared to the traditional approach. I suppose it depends on the game details, so I'd have to experiment with it to see.

But it's worth having a look and maybe discussing.
 
  • Like
Reactions: Yal

sylvain_l

Member
interesting system to enforce single direction move in a 4.direction system. Worth to have it in mind.
An advantage of this system over the common {x += key_right - key_left} is that there is no situation where holding multiple keys causes the character to stop moving - they will always move in the direction of the most recently pressed and still held key.
And the disadvange too^^

because you'll have to refactor the //COMPARE THE pri_key part to manage an anticipate a change of direction by moving "diagonally" with that system (be it a platformer or a top-down maze, even in a 4-direction system, there is some time where while moving up player can anticipate that at next junction he wants to go right ). But seams doable and offering alternate solution to get the job done.
 
Top