How are people implementing "pause" menus?
-
Quall.
How are people implementing "pause" menus?
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.
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.
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...
}
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...
}
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:
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.
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
}
}
....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.
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.
You might want to check "os.h" header.
In particular: I would assume that all animations are using "os::getTime()" to calculate timing.
Then you can operate with your game states.
In particular:
Code: Select all
//! stops the virtual (game) timer
static void stopTimer();
//! starts the game timer
static void startTimer();
Then you can operate with your game states.
-
Guest
-
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
works great here anyway
-
dhenton9000
- Posts: 395
- Joined: Fri Apr 08, 2005 8:46 pm
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.
And then set the gamestate values with the eventreceiver. Thats it should work.
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));
}
}
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.
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.
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.
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
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