I built a generic transition system for a 2d engine for iPhone. I'm going to try to explain it. This is only an approach, the implementation has more things that are not relevant.
Suppose that your engine is hierarchical, if it is not, there are a lot of of reasons why a game engine must be hierarchical. We can have two interfaces IState and ITransition inheriting from the SceneNode class. Like this:
Well, SceneNode can be updateable, this means that the parent calls the children method "update" and enabled, that receive or not input events ( so you can disable the user events when the transition is executing ).
Every state has a name, and every transition has the old and new state between the transition exists.
Ok. Now we can have two managers, Transition and StateManager, the purpose of these managers is to have a registry of all Transitions and States and offer features. These managers can be singleton to be accessible from everywhere.
With addTransition we attach a custom transition to a pair of menus, the order is important. When we call changeState, the manager is responsible of test if a transition has been added and execute it if exist.
With this simple architecture, we are to program a transition between the MainMenu to Battle.
The current scene graph is:
My transition implementation:
TransitionMenuToBattle : public ITransition
getOldState()->setActive( false );
getRoot()->addChild( this );
addChild( blackSprite );
void update( float delta )
// make fade of blackSprite
if ( blackSprite->getAlpha() == OPAQUE )
getRoot()->addChild( getNewState() );
getNewState()->setActive( false );
if ( blackSprite->getAlpha() == INVISIBLE )
getRoot()->removeChild( this );
getNewState()->setActive( true );
When enter method finishes, the scene graph is:
When exit method is called in update:
when exit method finishes:
when the game begins we need to add the transition:
TransitionFactory::get()->addTransition( "StateMainMenu", "StateBattle", new TransitionMenuToBattle( ) );
Then, for example in a button callback from MainMenu, we can put the call TransitionFactory::get()->changeMenu( "StateMainMenu", "StateBattle" ); or wrap this method into:
IState::changeMenu( std::string newMenu )
TransitionFactory::get()->changeMenu( getStateMenu(), newMenu );
You can complicate the transition much as you want. The transition has access to the two states and it can do things like overlap elements of two. The transition can receive the things that needs in his constructor. If TransitionManager detects that there is no transition added between two states can have a default behavior.