SOLVED: Basic help needed on room_repexec and pausegame

Started by johanvepa, Wed 26/03/2014 22:43:31

Previous topic - Next topic

johanvepa

Could someone point me in the right direction here?

In one room I'm doing a blocking animation every 2000 cycles.

I've found out that if I open the inventory window, the buttons of inventory will grey out (rendering it impossible to leave inventory) when the animation starts. And since the animation is followed by a DisplayMessage(0), and I can't click away the message when in the onventory window, the game halts.

I tried going to the
function show_inventory_window ()
and putting in PauseGame(); there. I thought this would mean everything stops and waits for the game to unpause, but it didn't.

Another matter that confuses me is, I have an animation running in the background consisting of small drops of rain travelling across the screen.
I use oRain.Y++; in room_repexec for this feature.
Now, the rain keeps falling in the background, even though I have the inventory window opened, and even though the game is paused when in inventory.

I don't understand, I thougt PauseGame(); would stop any effects going on in the room's repexec?




Khris

This stuff is kinda tricky to work with. What I would do is fix the original problem: in the code that does the blocking animation, don't do it if (IsInterfaceEnabled() == false).

PauseGame() does not stop the entire game in its tracks, for instance the default global script manually skips processing mouse clicks if the game is paused.

johanvepa

If I hear you correctly, the inventory screen (at least the one that comes with the demo game template) does NOT stop any actions going on in the room that's bound to repexec?

That means also that game time will pass (I have a day/night cycle) and any wandering monsters will chase Ego while he fumbles for the magic sword in his rucksack? Have I understood correctly?

Oh.

Well, I see why you call this tricky. But thank you for the solution, I'll have to work on it.

monkey0506

#3
Khris, I'm afraid you're a bit mistaken.

IsInterfaceEnabled would return true if the Inventory ANY GUI is/isn't shown, regardless of whether or not the game is paused. The only time that IsInterfaceEnabled would ever return false is during a blocking event or upon manually calling DisableInterface. GUI visibility will never affect the user interface. "Pause game when shown" will cause IsGamePaused to return true, not IsInterfaceEnabled to return false.

The basic premise of what Khris said is still generally correct though, you just need to check IsGamePaused.




Rant about Pausing the game vs. Disabling the interface

Spoiler
To help make the distinction, pausing the game (e.g., via a GUI or PauseGame) will tell AGS to stop the background processing. This means that animations (e.g., Character.Animate, Object.Animate, etc., not any user-defined manual animations), movement (e.g., cEgo.Walk, oBall.Move, etc., not any user-defined movements like oBall.X++), and so-forth will temporarily stop being processed by the engine, and resumed when the GUI is closed or UnPauseGame is called (note that PauseGame calls can stack, so you may have to call UnPauseGame more than once if you're pausing it from multiple locations). All calls such as repeatedly_execute, on_event, on_mouse_click, on_key_press, interaction events, and GUI events will still be called normally! GUIs and their controls will not be disabled by pausing the game.

Disabling "the interface" (e.g., during any blocking event or by calling DisableInterface) is essentially the opposite of pausing the game. That is, it tells the engine to stop processing user input, rather than to stop doing its own work. The interface will remain disabled until the blocking event ends or EnableInterface is called (similarly to PauseGame, calls to DisableInterface also stack, so you may have to call EnableInterface more than once if disabling from multiple locations). Calls such as repeatedly_execute, on_event, on_mouse_click, on_key_press, interaction events, and GUI events will not be called while the interface is disabled. GUIs and their controls will be greyed out or disabled while the interface is enabled. The engine will automatically set the mouse cursor to eModeWait (regardless of name, this is hardcoded behavior for cursor mode 7) while the interface is disabled).

I'll also note that the wording in the manual can sometimes be a bit misleading or counter-intuitive given these descriptions. For example, the entries for Wait, WaitKey, and WaitMouseKey all begin with the phrase, "Pauses the script" by which it actually means the interface is disabled. The game is not paused by calling Wait.

And not that you were probably about to, but you should generally avoid calling PauseGame and DisableInterface at the same time because then the only thing the engine would do is call repeatedly_execute_always and draw the screen. It wouldn't process any input, animations, or anything until you released it to do so... (roll)
[close]




In short, all you have to do is check that the game isn't paused:

Code: ags
function room_RepExec()
{
  if (!IsGamePaused()) // equivalent to IsGamePaused() == false
  {
    // update and check loop count
    // do animation, if needed
    oRain.Y++;
    // sanity/bound checking on oRain.Y, I presume?
  }
}

johanvepa

#4
Let me see if I can get this straight...

PauseGame() does not pause the game in the respect that I would expect (with my intuitive understanding, that is). Any repeatedly executing effects still execute, like time passing (since I have that set up for repeatedly execute in almost every room), rains created using for example the
oRain.Y++;oRain.X++;
thingamagig,  and any other effects relating to the local room's room_RepExec.

So, in order to have the inventory screen truly pause not only the "game" but also any effects that would occur repeatedly, like timers, I have to add PauseGame() to my show inventory function:

Code: ags
function show_inventory_window () 
{
  gInventory.Visible = true;
  mouse.Mode = eModeInteract;
  mouse.UseModeGraphic(eModePointer);
  PauseGame();
}


and in every room where I don't want RepExec to execute whenever inventory is visible, I must add a further
Code: ags

if (!IsGamePaused())
{
//everything here
}

to the RepExec code.

Could you tell me if I'm on the right track here?

monkey0506

You've got the general idea of it. Instead of manually calling PauseGame/UnPauseGame you could simply set the GUI's visibility type to "Pause game when shown" (in the editor). That will automatically handle pausing the game, but again, this still allows events to be run (otherwise you couldn't interact with GUIs and so forth while the game is paused).

So, to deal with that you can do one of the following:

Code: ags
function room_RepExec()
{
  if (!IsGamePaused())
  {
    oRain.X++;
    oRain.Y++;
    // etc., etc., etc.
  }
}


Or, a bit more simply:

Code: ags
function room_RepExec()
{
  if (IsGamePaused()) return; // if game is paused, we don't need to do anything
  oRain.X++;
  oRain.Y++;
  // etc.
}


These both accomplish the same thing, so it's up to you which one you choose. The second one prevents you having the entire function inside a huge if-statement though, so it makes it a bit clearer what's going on. Also note that you could have some things still run in your rep ex functions while the game is paused by simply calling them before you check if the game is paused.

Does that make it clearer?

johanvepa

Thank you both very much!

This makes sense to me, and it is manageable to work with, for someone with my limited skills (even though there will be a bit of fixing up to do now, but thats life).

I still don't quite get what DisableInterface does, but I'll work on it and see to it that I don't use code I don't understand.

monkey0506

It's not strictly relevant to what you're doing here, but you can think of DisableInterface as being like a call to Wait. It forces the game into the blocking thread (read the manual about blocking vs non-blocking) so that animations and movement are still drawn/updated, but user-input like clicking the mouse is ignored (effectively disabling the opposite side of things from what PauseGame does).

SMF spam blocked by CleanTalk