Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: rongel on Wed 15/01/2020 10:45:11

Title: Release pressed key / holding down key
Post by: rongel on Wed 15/01/2020 10:45:11
Hi!

This might be a very simple question, but I couldn't find an answer for it, and I want to do it right.

I have menu screen that comes up when I press "ESC" key. My code is simply something like this:

Code (ags) Select
if(keycode ==eKeyEscape) {
  if(!gControl.Visible) gControl.Visible = true;
  else gControl.Visible = false;
}


Everything works, unless player holds down the ESC key. Then the menu screen constantly switches on and off, and I dont want that. The menu screen should appear when the player releases the ESC key. The player needs to press it again to close it. Holding down the key shouldn't have any effect, pressing it should be like when pressing a gui button, the action happens when the button is released.

What would be the simplest way to achieve this?  Thanks!
Title: Re: Release pressed key / holding down key
Post by: Matti on Wed 15/01/2020 11:07:56
Ha. I never noticed that behavior, because I never tried  :-D. But now that you mentioned it I'm very much interested in an answer too.
Title: Re: Release pressed key / holding down key
Post by: eri0o on Wed 15/01/2020 11:47:27
On key press event triggers dependant on the OS configurations for your operating system, like when you hold a key in a input form and it inputs that key repeatedly. To avoid it, if undesired, you can instead detect the key press/release on a repeatedly_execute block (if you don't want to trigger during blocking events) or on a repeatedly_execute_always event.

you can use the following pattern:
Code (ags) Select
bool was_key_A_pressed;
void repeatedly_execute_always(){
  if(!was_key_A_pressed && IsKeyPressed(eKeyCodeA)){
    // do stuff
  }
  was_key_A_pressed = IsKeyPressed(eKeyCodeA);
}


I typed from memory so you may have to fix the above code. You can invert the ! on the if to switch to a release transition or use exclusive or to trigger on any transition.
Title: Re: Release pressed key / holding down key
Post by: Crimson Wizard on Wed 15/01/2020 12:00:00
Also, if you have several keys to track like this, there was a KeyListener module I once wrote: https://www.adventuregamestudio.co.uk/forums/index.php?topic=53226.0
Title: Re: Release pressed key / holding down key
Post by: rongel on Wed 15/01/2020 12:41:05
Thanks for the answers! The module sounds really good Crimson Wizard, I might use that. But I want to get this working first, I have trouble to closing the gui...

So I don't use anymore on_key_press, my script is now in GlobalScript under repeatedly_execute(). The code looks like this:


Code (ags) Select
if(!was_key_ESC_pressed && IsKeyPressed(eKeyEscape)) {
  gControl.Visible = true;
}
was_key_ESC_pressed = IsKeyPressed(eKeyEscape);


So this works fine, I tested it with another command, and it only gives one action like it should. But closing the gui is not working for me, I tried this under the previous script:

Code (ags) Select
if(was_key_ESC_pressed && IsKeyPressed(eKeyEscape)) {
  gControl.Visible = false;
}


That causes the gui flicker on and off. What am I doing wrong?
Title: Re: Release pressed key / holding down key
Post by: eri0o on Wed 15/01/2020 12:43:59
gControl.Visible = !gControl.Visible;

on the first bit of code you posted.
Title: Re: Release pressed key / holding down key
Post by: rongel on Wed 15/01/2020 13:54:50
Quote from: eri0o on Wed 15/01/2020 12:43:59
gControl.Visible = !gControl.Visible;

on the first bit of code you posted.

Sorry eri0o, still didn't get it, you need to spell it out for me... Did you mean that I add gControl.Visible = !gControl.Visible;  to this:

Code (ags) Select
if(!was_key_ESC_pressed && IsKeyPressed(eKeyEscape)) {
  gControl.Visible = true;
}
was_key_ESC_pressed = IsKeyPressed(eKeyEscape);


I tried it and also tried adding it to the script on the first post, but got the on/off flicker again.
Title: Re: Release pressed key / holding down key
Post by: eri0o on Wed 15/01/2020 14:04:48
Instead of setting to true, set to the inverse value it had before.

Boolean algebra 101:

! is the not operator
!0 == 1
!1 == 0

&& is the and operator
0&&0 == 0
0&&1 == 0
1&&0 == 0
1&&1 == 1

(1 is true, 0 is false)

__0__/””1”” -> we want to detect a up border transition

__was 0__/""" now 1

!was && now == true // condition we want to detect, a press

If it was a down border, then

was && !now == true // the release condition

Here is the code, the explanation is above.

Code (ags) Select
bool was_key_ESC_pressed;
void repeatedly_execute_always(){
  if(!was_key_ESC_pressed && IsKeyPressed(eKeyEscape)) {
    gControl.Visible = !gControl.Visible;
  }
  was_key_ESC_pressed = IsKeyPressed(eKeyEscape);
}
Title: Re: Release pressed key / holding down key
Post by: rongel on Wed 15/01/2020 14:26:22
Ok, got it:

Code (ags) Select
if(!was_key_ESC_pressed && IsKeyPressed(eKeyEscape)) {
  gControl.Visible = !gControl.Visible;
}
was_key_ESC_pressed = IsKeyPressed(eKeyEscape);


It works now just the way I want it to, thanks! Yeah, I need to brush up my boolean algebra some day...  :-D