How are people implementing "pause" menus?

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Quall.

How are people implementing "pause" menus?

Post by Quall. »

Like the title says. I have been trying to create the logic behind it before I actually code it, and this is why I am stumped.

I would like to use multiple scenes...the game and the menus. I would not like to use the GUI manager for the menus as my game should not only be mouse free, but also have 3d menus. However, I don't see a way to pause the scenes (and alternate between the 2).

I could pause the driver, which would in turn pause every scene manager, but not single scenes. How are people alternating between scene managers?

I don't know if I am explaining the problem too well, so please tell me and I will try to explain it a little more.
Midnight
Posts: 1772
Joined: Fri Jul 02, 2004 2:37 pm
Location: Wonderland

Post by Midnight »

Good question I was curious myself.

I Implemented a restart function in Guice Click here to download

... I can think of one way to implement pause...using dusty engine or just creating an enumeration and only allowing certain things to operate when a certain mode is in place such as...

enum Mode { PAUSE, PLAY, REWIND, ECT };

if (Mode != PAUSE)
{
do whatever...
}
Quall
Posts: 154
Joined: Mon Mar 07, 2005 10:16 pm

Post by Quall »

I had a similar idea. I looked at the API doco and looked at the drawall() function. It says that it updates the scenenode and animators (<- my main concern).

So, I will have to see if not drawing a scene (and pausing all physics) would "pause" the scene and all movement calculations until it is called to "drawall" again.

Something like this:

Code: Select all

if(key pressed == "p")
{
  paused = !paused;
  if(paused) gui_mgr->create_square_to_hide_game_scene;
  else gui_mgr->remove_big_square;
}

while(run)
{
  if(!paused) 
  {
    physics->update();
    game_smgr->drawall(); //draw game
  }
  else 
  {
    gui_mgr->drawall(); //block old scene with black square
    pause_smgr->drawall(); //draw pause menu over gui scene
  }
}
But this would only work if not drawing a scene is like pausing it. However, rendering animators are based on the scenes timer, are they not? How would not drawing it pause a timer? This is confusing me. I wonder if Niko has pausing scenes in a driver, and not the entire driver, planned for future releases.
Dark Rain
Posts: 47
Joined: Thu Jul 07, 2005 1:31 am

Post by Dark Rain »

State Machine?
Quall
Posts: 154
Joined: Mon Mar 07, 2005 10:16 pm

Post by Quall »

....I hope you don't mean to save the state, modifier position, and all other data of every node in a scene_manager. Maybe for savegame positions, but there is no way I am going to do that JUST to make a temp menu. Loading times would be horrible.

If you mean states of the game, each having a different scene, then that wouldn't work.As seen in irrwizard, the scene manager is reset and reloaded everytime the states are changed. Wouldn't be good for a pause menu.
x4861
Posts: 24
Joined: Fri Feb 18, 2005 10:19 am

Post by x4861 »

You might want to check "os.h" header.
In particular:

Code: Select all

//! stops the virtual (game) timer
static void stopTimer();

//! starts the game timer
static void startTimer();
I would assume that all animations are using "os::getTime()" to calculate timing.

Then you can operate with your game states.
Guest

Post by Guest »

Just use irrlichts own ITimer calls to pause the timer and all anims will cease. Work in some suspended state checks and alternate code path to update what you need (render to stop black window etc).
TheRLG
Posts: 372
Joined: Thu Oct 07, 2004 11:20 pm

Post by TheRLG »

okay alternating between the two is easy, but as far as pausing goes, do you need the scene to actually freeze. if not, then its easy, but if you do, like most games do hehehe, then itll take a little thinking. which i am currently doing.
Guest

Post by Guest »

as I said - to freeze a scene you just pause the irrlicht timer and tick it as need ed. The same way you can go in slow motion by setting the timer etc using zero (or pause) will cease all rendering motion - you just need to draw all in another loop without motion updates and any background checks.

works great here anyway
dhenton9000
Posts: 395
Joined: Fri Apr 08, 2005 8:46 pm

Post by dhenton9000 »

what about using a physics engine like Newton? I have irrlicht timers and newton updates going. I'm thinking that you just don't call the physics update while paused.
sudi
Posts: 1686
Joined: Fri Aug 26, 2005 8:38 pm

Post by sudi »

I think i found a good solution on seperating the game from the menu. u could download my game from the sig to see the menu in action(source is included)
But i will post a edited version of my menu class to show how to use it.
then u will just need one instance of this class and call its run method during ur main loop.

Code: Select all

#include <irrlicht.h>
#include <vector>
struct Controls
{
       bool GameMenu;
       
       int MainMenu;
       int OptionMenu;
       int Game;
};
       
class CMenu
{
      protected:
                IVideoDriver* driver;
                ISceneManager* menusmgr;
                IGUIEnvironment* gui;
                
                Controls* Gamestates;
                
                std::vector<IGUIElement*> elements;
                
      public:
             CMenu();
             void run();
             void start(ISceneManager* mmenusmgr, Controls* mGamestates);
             void mainMenu();
             void optionMenu();
             void clearMenu();
             void DisplayText();
             std::vector<IGUIElement*> getElements()
             {
             return elements;
             }
             
};
CMenu::CMenu()
{
     
}
void CMenu::start(ISceneManager* mmenusmgr,Controls* mGamestates)
{
     Gamestates = mGamestates;
     
      //The Manager
      driver = device->getVideoDriver();
      menusmgr = mmenusmgr;
      gui = device->getGUIEnvironment();
}
void CMenu::run()
{
     if(Gamestates->GameMenu == false)
     {
                         //Load some stuff in the menu scenemanager
     }
     
     if(Gamestates->MainMenu == 1)
     {         
         mainMenu();
         device->getCursorControl()->setVisible(true);
         Gamestates->MainMenu = 2;
     }
     if(Gamestates->OptionMenu == 1)
     {         
         optionMenu();
         device->getCursorControl()->setVisible(true);
         Gamestates->OptionMenu = 2;
     }     
     if(Gamestates->Game == 0)
     {
                         menusmgr->drawAll();
                         DisplayText();
     }
     if(Gamestates->Game == 1)
     {
                         //clear menus
                         clearMenu();
                         device->getCursorControl()->setVisible(false);
                         Gamestates->Game = 2;
     }
     //Draw the GUI
     gui->drawAll();
}
void CMenu::mainMenu()
{
     //Clear GUI
     clearMenu();
     //Add elements
     elements.push_back(gui->addButton(rect<s32>(config.x/3,config.y/10+config.y/10+config.y/10,config.x/3+config.x/3,config.y/10+config.y/10+config.y/10+config.y/10), NULL, 102, L"Options"));
     elements.push_back(gui->addButton(rect<s32>(config.x/3,config.y/10+config.y/10+config.y/10+config.y/10,config.x/3+config.x/3,config.y/10+config.y/10+config.y/10+config.y/10+config.y/10), NULL, 103, L"Quit"));
}
void CMenu::optionMenu()
{
     //Clear GUI
     clearMenu();
     
     //Add an element to the gui manager
     IGUIEditBox* namebox = gui->addEditBox(L"This is an EditBox",core::rect<s32>(300,250,450,280),true, gui->getRootGUIElement(), 204);
     //than add this element to the elements vector to delete it later
     elements.push_back(namebox);
}

//Clear Function
void CMenu::clearMenu()
{
     if(!elements.empty())
     {
                         for (std::vector<IGUIElement*>::iterator it = elements.begin(); it != elements.end(); ++it) 
                         { 
                           (*it)->remove(); 
                         }
                         elements.clear();
     }
}
void CMenu::DisplayText()
{
     if(Gamestates->MainMenu ==2)
     {
                             font->draw(L"Main Menu",core::rect<s32>(config.x-(config.x/2)-50,80,config.x-(config.x/2)+100,100),video::SColor(255,255,255,255));
     }
     if(Gamestates->OptionMenu == 2)
     {
                             font->draw(L"Option Menu",core::rect<s32>(config.x-(config.x/2)-50,80,config.x-(config.x/2)+100,100),video::SColor(255,255,255,255));
     }
}
And then set the gamestate values with the eventreceiver. Thats it should work.
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
TheRLG
Posts: 372
Joined: Thu Oct 07, 2004 11:20 pm

Post by TheRLG »

I think the problem here is that he needs to be able to switch between drawing different scene managers (very easy already) but he needs to be able to pause the timer of only one scene manager while the other is in use, which is our stumping point.
Quall
Posts: 154
Joined: Mon Mar 07, 2005 10:16 pm

Post by Quall »

Indeed. By looking at your code Sudi, it seems that you clear the current scene and reload them each time they are called. If you look at the irrWizard project, it does it similarly to your code.

The method I am talking about uses multiple scene managers, one for each menu. This way, the main menu or pause menu will always be stored in memory for fast access while the game is running, and the only loading after that would be between stages/maps/levels.

I believe the problem has already been answered though. Pausing the engine timer would pause all animators (and hopefully partical effects). That way, while you draw the "pause" scene, you just pause the timer and stop drawing the game's scene (and it won't update while in the pause menu). Then switch back.

The only problem is that I would only be able to use animators in the game's scene (unless I create one based on a seperate timer). However, I could live with that.
area51
Posts: 338
Joined: Thu Mar 18, 2004 10:20 pm
Location: UK
Contact:

Post by area51 »

You can condition the clearing of the scene manager by using a 'pause' flag. Then will be able to change states without loosing the scene info.

That will get over the 'State Pattern' problem at least.
________
European Recipes
Last edited by area51 on Thu Feb 24, 2011 11:53 pm, edited 1 time in total.
Guest

Post by Guest »

see this shows the need for more scene control like smgr->pause() smgr->start(); etc..etc..
Post Reply