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:
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!
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.
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:
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.
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
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:
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:
if(was_key_ESC_pressed && IsKeyPressed(eKeyEscape)) {
gControl.Visible = false;
}
That causes the gui flicker on and off. What am I doing wrong?
gControl.Visible = !gControl.Visible;
on the first bit of code you posted.
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:
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.
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.
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);
}
Ok, got it:
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