Pausing a scene?
Pausing a scene?
Anyone has an idea how to pause a scene?
It's not the game logic that troubles me but the animators. If you have a GUI window e.g. option screen you would normaly like to freez the scene, dispaly the GUI return back and unfreez. So far so good, but only if you dont have any animators since those are updating their state on every device.Run(). The same is with animated meshes. The later one can be solved by setting the AnimationSpeed to 0.
My first thought was removing all animators prior pausing the scene. If there was a way one could iterrate through all the attached animators of a node they could be removed thus preventing nodes to move. Unfortunately I couldnt find a way to iterrate animators unless keeping track of them by my own.
The second problem is that even if an animator is Remove()d it is still updating during Run() but not affecting the detached node. Once attached again it instantly applies to the node its internal state (at least if talk about movements or collisions).
I whish there was a Freez like function
Another one...is there a way to isolate the Scenes and having the Device.Run() act only upon one "active" scene?
If not this would be indeed a nice engine feature!!!
I'll have another beer now, any one interested?
It's not the game logic that troubles me but the animators. If you have a GUI window e.g. option screen you would normaly like to freez the scene, dispaly the GUI return back and unfreez. So far so good, but only if you dont have any animators since those are updating their state on every device.Run(). The same is with animated meshes. The later one can be solved by setting the AnimationSpeed to 0.
My first thought was removing all animators prior pausing the scene. If there was a way one could iterrate through all the attached animators of a node they could be removed thus preventing nodes to move. Unfortunately I couldnt find a way to iterrate animators unless keeping track of them by my own.
The second problem is that even if an animator is Remove()d it is still updating during Run() but not affecting the detached node. Once attached again it instantly applies to the node its internal state (at least if talk about movements or collisions).
I whish there was a Freez like function
Another one...is there a way to isolate the Scenes and having the Device.Run() act only upon one "active" scene?
If not this would be indeed a nice engine feature!!!
I'll have another beer now, any one interested?
You must add some parts for your game eg:
Code: Select all
void render()
{
while(Device->isActive)
{
if(MODE==Menu)
{
// Objects not walk
// Rendering munu withs all components
if(goto_play)
MODE=Game;
}
if(MODE==Game)
{
// Objects walk
// play anim eg. walks
if(goto_menu)
MODE=Menu;
}
}
}
I'm pretty sure there's a function for nodes called something like removeAnimators() which removes all the animators. But if you remove them then you can't re-add them, if you did re-add them they'd start from the start position anyway which wouldn't work well.
What you could do is make your own animator which somehow allows you to control when it's updated. Or maybe you could just not call device->run() when you're in the menu..? I'm not sure if that would cause problems or not but as i remember it device->run() does little more than tick the timer so probably wouldn't hurt to not call it during the menu time.
What you could do is make your own animator which somehow allows you to control when it's updated. Or maybe you could just not call device->run() when you're in the menu..? I'm not sure if that would cause problems or not but as i remember it device->run() does little more than tick the timer so probably wouldn't hurt to not call it during the menu time.
You obviously didnt read my question if it was that easy I would post it to the beginners section rofl...but thanks for the good will buddyNadro wrote:You must add some parts for your game eg:
Code: Select all
void render() { while(Device->isActive) { if(MODE==Menu) { // Objects not walk // Rendering munu withs all components if(goto_play) MODE=Game; } if(MODE==Game) { // Objects walk // play anim eg. walks if(goto_menu) MODE=Menu; } } }
@ JP
1. I tried to avoid keeping track of the animators. But even if I did it removing them and adding them would not work since
a) if just removed and after pause added, the scene would start from the paused position but the animators would start as if they where running the whole pause time (you can not pause them).
b) if removed and recreated they would start from the initial position
Now imagine you have an movement animator attached to your player character... you pause and after you are back supprise, supprise
2. Creating custom animators wouldn't work either - at least not without changing the engine. BTW I am using a .NET wrapper for this project anyway.
3. There is no way you can get away with not calling device.run()...well you could try but it indeed hurts a lot. No device.Run() == no menu, actually you wouldnt get anything!
But thanks for giving a hand
1. I tried to avoid keeping track of the animators. But even if I did it removing them and adding them would not work since
a) if just removed and after pause added, the scene would start from the paused position but the animators would start as if they where running the whole pause time (you can not pause them).
b) if removed and recreated they would start from the initial position
Now imagine you have an movement animator attached to your player character... you pause and after you are back supprise, supprise
2. Creating custom animators wouldn't work either - at least not without changing the engine. BTW I am using a .NET wrapper for this project anyway.
3. There is no way you can get away with not calling device.run()...well you could try but it indeed hurts a lot. No device.Run() == no menu, actually you wouldnt get anything!
But thanks for giving a hand
Re: Pausing a scene?
ITimer has start() and stop() methods. can be used like:Riki wrote:Anyone has an idea how to pause a scene?
Code: Select all
Device->getTimer()->stop();
... here we can execute Device->run() ...
Device->getTimer()->start();
--------
after little tests i found that this pauses OK FlyCircleAnimator and GUI works OK but for example RotationAnimator continue animates -- possible it is Irrlicht's bug.
You can try this:
while(device->run())
{
if(!paused)
{
driver->beginScene(...);
smgr->drawAll();
gui->drawAll();
driver->endScene();
}
else if(paused)
{
driver->beginScene(...);
gui->drawAll();
driver->endScene();
}
}
maybe still have to play with timer because animators are using it.
But i think its a good start.
while(device->run())
{
if(!paused)
{
driver->beginScene(...);
smgr->drawAll();
gui->drawAll();
driver->endScene();
}
else if(paused)
{
driver->beginScene(...);
gui->drawAll();
driver->endScene();
}
}
maybe still have to play with timer because animators are using it.
But i think its a good start.
indeed this is good idea. alot of games uses this kind of pause -- it take a screenshot of the scene , then applies some nice effect , and then uses this image as background for gui menus ( -- this done in ExMachina and many other games ).BlindSide wrote: PS: Maybe you dont have to see the models when it paused? Add some pretty background effects to the menu or something..
p.s.: you can simple get screenshot and directly use it as background for pausing -- that what you just need i guess.
Guys none of the approaches would work,
@belfegor:
What would you accomplish with:
if(!paused)
{
driver->beginScene(...);
smgr->drawAll();
gui->drawAll();
driver->endScene();
}
else if(paused)
{
driver->beginScene(...);
gui->drawAll();
driver->endScene();
}
This way you are drwaing only the GUI elements when in pause mode and everything if its not paused. One could have a menu screen without a singel one GUIEleMent on it you know. I am mostly combinig GUI and scenemanager elements (SceneNodes) for both menus and the main game. So not drawing one part wouldnt help.
THE MAIN PROBLEM IS THAT device.Run() UPDATES THE ANIMATORS!
But again if you wannt to pause the game for whatever reason, it must not be only the menu - why not allowing the user to ust pause the game, you would like to have everything stopped. The only way is not to invoke device.Run() or not to use animators. The first approach has a catch 22 since it stops dispatching the window messages.
@everyone:
What I need is defenitively a way to isolate scenes (or scenemanagers) from each other.
So you could have a scene with guielements and scenenodes on it but the scene would not be automaticaly updated, drawn nor presented with device.Run(), Begin/EndScene(). Instead you would have an active scene or active scenemanager and only stuff from the active scenemanager would be drawn!!! Of course there should be a way of defining more than one scenemanager and defining the active one. Invoking device.Run() would process all the common window stuff plus only update object states of the active scenemanager.
Such approach would mean that one could have its Menu's and other "screens" implemented in no time and with much less trouble. Unfortunately this has to be implemented in the engine.
@belfegor:
What would you accomplish with:
if(!paused)
{
driver->beginScene(...);
smgr->drawAll();
gui->drawAll();
driver->endScene();
}
else if(paused)
{
driver->beginScene(...);
gui->drawAll();
driver->endScene();
}
This way you are drwaing only the GUI elements when in pause mode and everything if its not paused. One could have a menu screen without a singel one GUIEleMent on it you know. I am mostly combinig GUI and scenemanager elements (SceneNodes) for both menus and the main game. So not drawing one part wouldnt help.
THE MAIN PROBLEM IS THAT device.Run() UPDATES THE ANIMATORS!
But again if you wannt to pause the game for whatever reason, it must not be only the menu - why not allowing the user to ust pause the game, you would like to have everything stopped. The only way is not to invoke device.Run() or not to use animators. The first approach has a catch 22 since it stops dispatching the window messages.
@everyone:
What I need is defenitively a way to isolate scenes (or scenemanagers) from each other.
So you could have a scene with guielements and scenenodes on it but the scene would not be automaticaly updated, drawn nor presented with device.Run(), Begin/EndScene(). Instead you would have an active scene or active scenemanager and only stuff from the active scenemanager would be drawn!!! Of course there should be a way of defining more than one scenemanager and defining the active one. Invoking device.Run() would process all the common window stuff plus only update object states of the active scenemanager.
Such approach would mean that one could have its Menu's and other "screens" implemented in no time and with much less trouble. Unfortunately this has to be implemented in the engine.
Then don't use device.Run()Riki wrote: THE MAIN PROBLEM IS THAT device.Run() UPDATES THE ANIMATORS!
In the Tutorial #14 Win32Window there is a comment that shows how to run the engine without using device.Run()
Software documentation is like sex. If it's good you want more. If it's bad it's better than nothing.
Device::run() does not update the animators. It just updates the timer that you get with getTimer(). The animators keep track of the time that they started, so given the current time they know how far along their animation sequence they should go. If you stop the timer, you stop the animators. Simple as that.
Technically the drawAll() method of the scene manager updates all of the animators...
Travis
Technically the drawAll() method of the scene manager updates all of the animators...
Travis
Hi Vitek (or is it Travis),
Thanks for the reply. This makes stuff much more clear, but greenya noted that Timer.Stop() does not stop all animators - I didnt check this but since he tested it I droped the idea.
This makes it even easier to implement my finall idea about isolated scenemanagers. If the device is doing only win messages dispatching and all the scene drawing stuff is inside the scenemanager, you could easy allow creating more than one scenemanager. That way we could setup multiple scenes but run just the desired one by simply invoking the DrawAll() on only one object.
Of course there should be something like a GUImanager but this is not that important.
What do you say about this idea?
Thanks for the reply. This makes stuff much more clear, but greenya noted that Timer.Stop() does not stop all animators - I didnt check this but since he tested it I droped the idea.
This makes it even easier to implement my finall idea about isolated scenemanagers. If the device is doing only win messages dispatching and all the scene drawing stuff is inside the scenemanager, you could easy allow creating more than one scenemanager. That way we could setup multiple scenes but run just the desired one by simply invoking the DrawAll() on only one object.
Of course there should be something like a GUImanager but this is not that important.
What do you say about this idea?