GUI blocking keys

Started by TDBFW1, Sun 15/10/2017 16:11:37

Previous topic - Next topic

TDBFW1

I'm doing this in a new game in a default game for testing:

Code: ags

function room_AfterFadeIn()
{
gTest.Visible=true;
mouse.Mode=eModePointer;
}


In the Globalscript:

Code: ags

   if (keycode == eKeyN) gTest.Visible = !gTest.Visible;


However, the GUI doesn't close when I push "N". BTW, the GUI visibility is on pause game when shown. Any help?

Crimson Wizard

#1
Quote from: TDBFW1 on Sun 15/10/2017 16:11:37
However, the GUI doesn't close when I push "N". BTW, the GUI visibility is on pause game when shown. Any help?

Actually I asked this in your previous forum thread, but you did not reply: http://www.adventuregamestudio.co.uk/forums/index.php?topic=55259.msg636571292#msg636571292

Check if you have something like this in on_key_press:

Code: ags

if (IsGamePaused())
    return;

TDBFW1

Yes I do, actually:
Code: ags

  if (IsGamePaused() || (IsInterfaceEnabled() == 0))
  {
    // If the game is paused with a modal GUI on the
    // screen, or the player interface is disabled in
    // a cut scene, ignore any keypresses.
    return;
  }

What should I do about it (It's in the default game)?

Crimson Wizard

#3
This condition is there to disable certain key shortcuts that are only allowed to work when no blocking GUI is shown (such as toggling cursor modes, for example).

I suggest splitting this function in parts, each for possible state of your game, for example:
- When your GUI dialog is shown;
- When no blocking GUI is shown;
- other...

Something like:
Code: ags

function on_key_press(eKeyCode keycode)
{
    if (gTest.Visible)
    {
        // Only check for keys that should work in gTest dialog
    }
    else if (IsGamePaused())
    {
        // Check for keys that should work when any other blocking GUI is shown
    }
    else
    {
        // Only check for keys that should work during regular gameplay (no blocking GUIs shown)
    }
}

TDBFW1

I tried something like this, in my original game with a GUI called gNotebook:

Code: ags

  if ((keycode == eKeyN) &&
(DifficultyEasy))
{
  if ((gNotebook.Visible) &&
  (IsGamePaused()))
  {
    gNotebook.Visible=false;
  }
  else if (!gNotebook.Visible) gNotebook.Visible=true;
  else
  {
    gNotebook.Visible=false;
  }
}

It still doesn't work and I don't know why.

TDBFW1

Difficulty Easy is just a variable that should be active in the new blank room.

Crimson Wizard

Could you show full contents of your on_key_press function?

TDBFW1

Code: ags

function on_key_press(eKeyCode keycode) {
  // The following is called before "if game is paused keycode=0", so
  // it'll happen even when the game is paused.
  
  if ((keycode == eKeyEscape) && gRestartYN.Visible) {
    //Use ESC to cancel restart.
    gRestartYN.Visible = false; 
    gIconbar.Visible = true;
    // If the panel's not ON, then the player must have gotten here by tapping F9,
    // therefore his cursor needs restoring. If the panel IS on, then it doesn't,
    // because it's already a pointer. Get used to thinking like this!!
    if (!gPanel.Visible) mouse.UseDefaultGraphic(); 
    return;
  }
  if ((keycode == eKeyEscape) && gPanel.Visible) {
    // Use ESC to turn the panel off.
    gPanel.Visible = false; 
    mouse.UseDefaultGraphic();
    gIconbar.Visible = true;
    return;
  }
  if ((keycode == eKeyEscape) && (gSaveGame.Visible))
  {
    // Use ESC to close the save game dialog
    close_save_game_dialog();
    return;
  }
  if ((keycode == eKeyEscape) && (gRestoreGame.Visible))
  {
    // Use ESC to close the restore game dialog
    close_restore_game_dialog();
    return;
  }
  
  if (keycode == eKeyReturn) { 
    // ENTER, in this case merely confirms restart
    if (gRestartYN.Visible) RestartGame();
  }

  if (IsGamePaused() || (IsInterfaceEnabled() == 0))
  {
    // If the game is paused with a modal GUI on the
    // screen, or the player interface is disabled in
    // a cut scene, ignore any keypresses.
    return;
  }

  // FUNCTION KEYS AND SYSTEM SHORTCUTS
  if (keycode == eKeyEscape) {
    // ESC
    gPanel.Visible = true; 
    gIconbar.Visible = false;
    mouse.UseModeGraphic(eModePointer);
  }
  if (keycode == eKeyCtrlQ)  QuitGame(1);   // Ctrl-Q
  if (keycode == eKeyF5) show_save_game_dialog();   // F5
  if (keycode == eKeyF7) show_restore_game_dialog();  // F7
  if (keycode == eKeyF9) {
    // F9, asks the player to confirm restarting (so much better to always confirm first)
    gRestartYN.Visible = true;  
    gIconbar.Visible = false;
    mouse.UseModeGraphic(eModePointer);
  }
  if (keycode == eKeyF12) SaveScreenShot("scrnshot.bmp");  // F12
  if (keycode == eKeyTab)   show_inventory_window();  // Tab, show inventory

  if ((keycode == eKeyN) &&
(DifficultyEasy))
{
  if ((gNotebook.Visible) &&
  (IsGamePaused()))
  {
    gNotebook.Visible=false;
  }
  else if (!gNotebook.Visible) gNotebook.Visible=true;
  else
  {
    gNotebook.Visible=false;
  }
}

  // GAME COMMAND SHORTCUTS
  if (keycode == 'W') mouse.Mode=eModeWalkto; //Notice this alternate way to indicate keycodes.
  if (keycode == 'L') mouse.Mode=eModeLookat; //Note that all we do here is set modes.
  if (keycode == 'U') mouse.Mode=eModeInteract; //If you want something else to happen, such as GUI buttons highlighting,
  if (keycode == 'T') mouse.Mode=eModeTalkto; //you'll need some more scripting done.
  if (keycode == 'I') mouse.Mode=eModeUseinv; //But this will, as-is, give you some standard keyboard shortcuts your players will very much appreciate.

  // For extra cursor modes, such as pick up, feel free to add as you will.
  // Uncomment the line below if you use the "Pick Up" mode.
  //if (keycode == 'P' || keycode == 'G') mouse.Mode=eModePickup; 

  // DEBUG FUNCTIONS
  if (keycode == eKeyCtrlS)  Debug(0,0);  // Ctrl-S, give all inventory
  if (keycode == eKeyCtrlV)  Debug(1,0);  // Ctrl-V, version
  if (keycode == eKeyCtrlA)  Debug(2,0);  // Ctrl-A, show walkable areas
  if (keycode == eKeyCtrlX)  Debug(3,0);  // Ctrl-X, teleport to room
  if (keycode == eKeyCtrlW && game.debug_mode) 
    player.PlaceOnWalkableArea(); //Ctrl-W, move to walkable area 

}


The code for the room is just this:
Code: ags

function room_AfterFadeIn()
{
gNotebook.Visible=true;
}

function room_Load()
{
DifficultyEasy=true;
}

Crimson Wizard

You still have IsGamePaused() check before checking for N key. This means that whenever game is paused it won't even get to 'N' key check (or anything else beyond IsGamePaused()).

I mean those lines:
Code: ags

  if (IsGamePaused() || (IsInterfaceEnabled() == 0))
  {
    // If the game is paused with a modal GUI on the
    // screen, or the player interface is disabled in
    // a cut scene, ignore any keypresses.
    return;
  }


You could remove it, but the problem is that if you do, then all other keys will also work while gNotebook is visible (such as eKeyCtrlQ, eKeyF5, and so on).

For that reason, I suggest to split the function into logical if/else blocks, where each will be executed only in particular game mode, similar to an example I showed in my previous post.

TDBFW1

This works:
Code: ags

function on_key_press(eKeyCode keycode)
{
    if (gNotebook.Visible)
    {
  if ((keycode == eKeyN) &&
  (DifficultyEasy))
  {
    gNotebook.Visible=false;
  }
  else
    {
  if ((keycode == eKeyEscape) && gRestartYN.Visible) {
    //Use ESC to cancel restart.
    gRestartYN.Visible = false; 
    gIconbar.Visible = true;
    // If the panel's not ON, then the player must have gotten here by tapping F9,
    // therefore his cursor needs restoring. If the panel IS on, then it doesn't,
    // because it's already a pointer. Get used to thinking like this!!
    if (!gPanel.Visible) mouse.UseDefaultGraphic(); 
    return;
  }
  if ((keycode == eKeyEscape) && gPanel.Visible) {
    // Use ESC to turn the panel off.
    gPanel.Visible = false; 
    mouse.UseDefaultGraphic();
    gIconbar.Visible = true;
    return;
  }
  if ((keycode == eKeyEscape) && (gSaveGame.Visible))
  {
    // Use ESC to close the save game dialog
    close_save_game_dialog();
    return;
  }
  if ((keycode == eKeyEscape) && (gRestoreGame.Visible))
  {
    // Use ESC to close the restore game dialog
    close_restore_game_dialog();
    return;
  }
  
  if (keycode == eKeyReturn) { 
    // ENTER, in this case merely confirms restart
    if (gRestartYN.Visible) RestartGame();
  }

  // FUNCTION KEYS AND SYSTEM SHORTCUTS
  if (keycode == eKeyEscape) {
    // ESC
    gPanel.Visible = true; 
    gIconbar.Visible = false;
    mouse.UseModeGraphic(eModePointer);
  }
  if (keycode == eKeyCtrlQ)  QuitGame(1);   // Ctrl-Q
  if (keycode == eKeyF5) show_save_game_dialog();   // F5
  if (keycode == eKeyF7) show_restore_game_dialog();  // F7
  if (keycode == eKeyF9) {
    // F9, asks the player to confirm restarting (so much better to always confirm first)
    gRestartYN.Visible = true;  
    gIconbar.Visible = false;
    mouse.UseModeGraphic(eModePointer);
  }
  if (keycode == eKeyF12) SaveScreenShot("scrnshot.bmp");  // F12
  if (keycode == eKeyTab)   show_inventory_window();  // Tab, show inventory
    }
  // GAME COMMAND SHORTCUTS
  if (keycode == 'W') mouse.Mode=eModeWalkto; //Notice this alternate way to indicate keycodes.
  if (keycode == 'L') mouse.Mode=eModeLookat; //Note that all we do here is set modes.
  if (keycode == 'U') mouse.Mode=eModeInteract; //If you want something else to happen, such as GUI buttons highlighting,
  if (keycode == 'T') mouse.Mode=eModeTalkto; //you'll need some more scripting done.
  if (keycode == 'I') mouse.Mode=eModeUseinv; //But this will, as-is, give you some standard keyboard shortcuts your players will very much appreciate.

  // For extra cursor modes, such as pick up, feel free to add as you will.
  // Uncomment the line below if you use the "Pick Up" mode.
  //if (keycode == 'P' || keycode == 'G') mouse.Mode=eModePickup; 

  // DEBUG FUNCTIONS
  if (keycode == eKeyCtrlS)  Debug(0,0);  // Ctrl-S, give all inventory
  if (keycode == eKeyCtrlV)  Debug(1,0);  // Ctrl-V, version
  if (keycode == eKeyCtrlA)  Debug(2,0);  // Ctrl-A, show walkable areas
  if (keycode == eKeyCtrlX)  Debug(3,0);  // Ctrl-X, teleport to room
  if (keycode == eKeyCtrlW && game.debug_mode) 
    player.PlaceOnWalkableArea(); //Ctrl-W, move to walkable area 

}
}

But if I add this:
Code: ags

if ((keycode == eKeyN) &&
(DifficultyEasy))
{
gNotebook.Visible=!gNotebook.Visible;
}

at the end of the initial "else" statement (I.e. where all the other keycodes live), it doesn't work.

Crimson Wizard

I think you have a mistake at the first "else", you did not close the very first condition "if (gNotebook.Visible)", and now all other keys are checked only if notebook is open.
You need to add one more closing bracket "}" before first else, and remove one unnecessary bracket after line "if (keycode == eKeyTab)   show_inventory_window();  // Tab, show inventory"

TDBFW1

Thanks so much! I had no idea why it wasn't working. Sorry for being a bit slow to realise what you were getting at, I'm a little late to coding.:-D

TDBFW1

Sorry, but a related question: Why doesn't this work?
Code: ags

function room_AfterFadeIn()
{
mouse.Mode=eModePointer;
gNotebook.Visible=true;
if (!gNotebook.Visible) player.Walk(180, 170, eBlock, eAnywhere);
}

Crimson Wizard

#13
Quote from: TDBFW1 on Tue 17/10/2017 21:15:11
Sorry, but a related question: Why doesn't this work?

If you mean why player is not walking, you are setting Notebook.Visible to true, and then immediately do player.Walk under condition if Notebook.Visible is false (which never happen at this point).
I cannot even guess what you were trying to do this way.

Khris

If the idea is to make the player Walk after the GUI was closed by the user, I don't think it'll work that way.
Even if gNotebook is a modal GUI, it won't stop execution mid-function.

Describe what you goal is, and we can provide solutions.

TDBFW1

Sorry, I do want the player to move once the GUI has closed. Is there a way I can do this?

Khris

Here's one way:
Code: ags
// above and outside the functions mentioned below
bool playerWalked;

  // in room_Load
  playerWalked = false; // upon entering the room, reset variable

  // in room_Rep_Exec
  if (!playerWalked && !gNotebook.Visible) {
    player.Walk(180, 170, eBlock, eAnywhere);
    playerWalked = true;
  }


The variable makes sure this happens a) every time the room is visited but b) only once

Cassiebsg

#17
Couldn't he just add the line to the close gNotebook function instead of using Rep_Exec?
And if it' only to happen once, then use Game.DoOnceOnly...

Code: ags

// whatever your function is called
{ 
    // ... eventually other code
    gNotebook.Visible=false;
    if (Game.DoOnceOnly("Walk only the 1st time the gNotes closes")) player.Walk(180, 170, eBlock, eAnywhere); 
}
There are those who believe that life here began out there...

Khris

#18
Sure, but I'm assuming this code is specific to a single room. That's why I chose to keep it inside the room script.
As for using Game.DoOnceOnly, I'm also assuming this code is supposed to run each time the room is entered, given that TDBFW1 put it in room_AfterFadeIn(). Therefore it needs to run more than once total.

Cassiebsg

Code: ags

    if (player.Room==1) player.Walk(180, 170, eBlock, eAnywhere); // or whatever room you which it to run


Better?
There are those who believe that life here began out there...

SMF spam blocked by CleanTalk