Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Last night I showed my game to my friends and they said it was a bit jumpy.

The example he gave was in the pokemon games when a battle starts music plays, the screen flashes then pixels out then the pokemon slide on from the side and the battle menu appears.

In my game you are walking along and the all of a sudden you are staring at the battle menu, I do see his point.

I am using a switch statement for my game loop, 1 is a fields and 2 is battle, in battle I run an if statement, if battle active do battle else display results screen/wait for user input.

I thought about making a state for the transition but them I would need a stater for field -> battle, battle -> field, town -> field and the list goes on an on seeming like lots of repeated code to me but I cant think of a way to pause the state while i play an animation like pokemon

With that sort or architecture how would transition between screens smoothly like my mate suggests?

C++ and directX

Edit: the problem I have is that once the state is changed the update routeen for that state is not called so all the sprites disappear as they are textures and only the background remains so I cannot just play a animation then change state or it will look even worse.

share|improve this question
    
If you have one state where you draw something, and one state where you draw another, you have to fade to a color between them, generally black. Old Scene -> Black -> New Scene. If you want a nice fade between the two scenes you can maybe render the previous scene into a RenderTarget, and fade that texture into the new scene. –  Jonathan Connell Jun 10 '11 at 15:28
    
@3nixios as I understand it direct x surfaces are blited to a buffer surface which is shown on screen where as a directx texture is drawn directly on the screen, i may be wrong but in my experience the player,npc and items disappear (texturex) and the background remains as it is copied from the back buffer and drawn outside the switch. this means i cannot maintain the current screen in order to do a fade –  Skeith Jun 10 '11 at 15:42
    
Can you not use a RenderTarget that is maintained between the two scenes? –  Jonathan Connell Jun 10 '11 at 15:49
    
@3nixion what do you mean render trigger I am unfamiliar with that term? –  Skeith Jun 10 '11 at 15:50
add comment

4 Answers 4

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:

enter image description here

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.

enter image description here

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:

enter image description here

My transition implementation:

TransitionMenuToBattle : public ITransition
{
    public:
        void enter()
        {
            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 )
                exit();
        }

        void exit()
        {
            getRoot()->removeChild( this );
            getNewState()->setActive( true );
        }
};

When enter method finishes, the scene graph is:

enter image description here

When exit method is called in update:

enter image description here

when exit method finishes:

enter image description here

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.

share|improve this answer
add comment

You could just make a single "transition" state, with which state you're going to and from indicated as a couple of variables in the object.

share|improve this answer
    
except that would require all the code from every possible state so it can maintain the screen while it changes. –  Skeith Jun 10 '11 at 15:16
    
@Skeith: Alternatively, you could just ask the originating state what to do when transitioning to the target state. Depending on how complex your requirements are, you could just get a 2D array of animations and index into it to find what to do. –  DeadMG Jun 10 '11 at 15:17
    
I don't see how passing every variable in my program to the transition state it at all a good idea? could you please explain you answer more. –  Skeith Jun 10 '11 at 15:21
    
Sorry, I'm off to bed, but expect an update from me in the morning –  DeadMG Jun 10 '11 at 21:13
add comment

If you're not willing to change your architecture from a switch statement to using the state design pattern (which is fine, as you know your code best) then it's gonna be pretty ugly.

Assuming you're using an architecture with a fairly standard Update loop, perhaps you could have a flag checking whether a transition is required and on the next Update check for the flag being set right at the beginning of your update loop and if it's on, then play a transition and wait until the transition has completed before turning the flag off.

Quick, dirty pseudocode would be:

bool bStateChangeRequested;

while( bUpdate )
{
    if( bStateChangeRequested )
    {
        PlayTransition();
        WaitForTransitionToComplete();
    }

    DoStateStuff();
}

Hope that helps, although I'd highly recommend the state design pattern for solving this. It'll make everything so much cleaner and better organised, so a definite thing to think about in future iterations.

share|improve this answer
add comment

In your switch statement call to a transition routine. For a ridiculously oversimplified pseudo answer:

void changeState ( int destinationState, int *currentState ) {
    // check that destination state is valid
    // check that current state can transition to destination state
    doTransition ( *currentState, destinationState);
    *currentState = destinationState
}

[Edit] To call this using a switch statement that already exists you would do something like this:

switch (destinationState): {
1: {changeState ( 1, &currentState); break; } // switch from some state to fields
2: {changeState ( 2, &currentState); break; } // switch from some state to battle
}

Then you do still need to write doTransition() that would actually do that transition animation. doTransition would do your fade in/fade out/whatever you wanted it to do.

share|improve this answer
    
you your self state this does not fit into my architecture so its not really an answer to the question that was asked. –  Skeith Jun 10 '11 at 15:18
    
@Skeith I don't believe I did, you can call this from your switch statement fairly straightforwardly, I'll edit my answer to show how. –  Stephen Jun 10 '11 at 19:35
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.