• 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 (Solved) How to stop object movement caused by holding the key from overlapping room_restart()?

R

Raya

Guest
I am trying to make a simple game where the player, represented by a character object called o_tommy, moves left and right with the keyboard arrows. That works but the problem is that I show a message when my timer runs out that aims to inform the player of their score and tell them to try again. Clicking ok on the message restarts the room and works fine as long as the player has clicked the keyboard buttons left and right in a single clicks manner. If the player has held down the left or right keyboard button then when the room restarts the object o_tommy (though newly generated) keeps moving in the direction of the lastly held down key (e.g. right) until it gets out of the room and never comes back.

How can I check if the keyboard key is pressed down continuously and somehow cancel it after clicking ok on the popped up message?

My code for making the object move is located in the o_tommy object Step event:

if (keyboard_check(vk_right)) {
x = x + 14;
}

if (keyboard_check(vk_left)) {
x = x - 14;
}

I restart the room in another object called o_dropper which is an invisible object placed in the room (dragged there in the room editor window) in order to drop objects simultaneously and also in the o_dropper's Create event an o_tommy object gets created so that it gets restarted with room_restart(). In o_dropper's Step event I check the timer and restart the room like this:

if (timer == 0)
{
show_message("bla bla try again");
timer = room_speed * 30;
score = 0;
room_restart();
}

It all works as I want except when the player holds down the left or right key while playing (which is the most natural thing to do). Then o_tommy object, though restarted (shown in initial position) keeps moving in the direction of the lastly held button and nothing can stop it! Holding down the opposite direction key only makes it pause but releasing it the object still keeps moving in that predefined direction (from a key held down prior to the message showing).

I am new to Game Maker, I tried a bunch of alternatives like for example having e.g. an global_pause variable to encompass the moving code in o_tommy' Step but changing the value in o_dropper when timer ran out doesn't stop this left-over movement...

Any advice on how to cancel this movement (of my object leaving the room by himself and running endlessly in the nothingness) will be greatly appreciated :)
 
L

Linkdeous

Guest
use
if check_keyboard_pressed(vk_key(left))
instead of
if check_keyboard(vk_key(left))

should do the trick
 
R

Raya

Guest
Thank you! That does indeed disable the hold down key function. Now if I hold down the right key it just doesn't move as I need to just click it again to move a step firther.

While this works, now the character is moving in a very discrete way, abrupt step by step. I liked the smooth way it moved with holding the key down. I just don't want it to overlap room_restart(), i.e. I don't want holding the right key when the message appears to result in my character running right out of the screen after room_restart() has happened.

Is there a way to keep the hold down key functionality for movement but just reset it together with the room_restart()?
 
Show_message is for debug use only and shouldn't really be used in game, as it completely blocks GMs from running.

You could use show_mesage_async instead.

Or, instead of restarting the room immediately after the player clicks ok, set an alarm and in the alarm do the room restart. That way GMs can clear the keyboard input Normally.

Finally, if you just want to use the check_keyboard_pressed functions to get smooth movement, you'll need to manage some booleans to indicate the key state.

When the player presses the left key, set a variable key_left to true.

Then use keyboard_check_released to check if the key has been released and if so, set key_left to false.

Then in the same event, after those checks, if key_left is true, move the player.
 
L

Linkdeous

Guest
mh.. then you could maybe make a move variable and then set every movement under this variable so :

if move {if (keyboard_check(vk_right)) {
x = x + 14;
}

if (keyboard_check(vk_left)) {
x = x - 14;
} }

then eveytime there is a cutscene, a stuff hapenning or what you can make move variable be 0 so it will make the player unable to move or press the key that's the easiest way to do it
so in your game end screen, restart, game over etc etc you just add a obj_player.move =0 then when it's over(or if you just restart the game ) put in the "i clicked on OK to restart the game" event/if code just put the obj_player.move=1 so it can move when you want, then get his movement disabled when you want to cutscene or so
 
Pretty sure you can just call keyboad_clear(vk_right) and keyboard_clear(vk_left) before you restart your room. The function -should- force the named keys state to return to unpressed without triggering a keyboard_check_release() event. Though sometimes it does funny things when I use it, so I'm not entirely sure if it will work for you.
 
R

Raya

Guest
Thank you all! So I tried all your suggestions. It was only IndianaBones' ones that worked in the end (except using alarms - that didn't make any difference).

Using check_keyboard_pressed function combined with boolean variable to get smooth movements did the trick but there was still a small glitch.
So I decided to stop using show_message as it was indeed it that caused that bug of key press going over room_restart. Now I use surfaces to show messages instead and there is no issue any more with room_restart and left over movements.

Thanks again! :)
 

Adikey

Member
I think you need to check your conditional checking for pressing key_left or key_right might as well key_up, key_down
It worked for me. Try this code in the step page:
//Movements
if (keyboard_check(vk_right))
{
x = x + 4;
}

if (keyboard_check(vk_left))
{
x = x - 4;
}

if (keyboard_check(vk_up))
{
y = y - 4;
}

if (keyboard_check(vk_down))
{
y = y + 4;
}
 
Top