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.

It's my first time working with actual scenes/states, aka DrawableGameComponents, which work separate from one another. I'm now wondering what's the best way to make transitions between them, and how to affect them from other scenes.

Lets say I wanted to "push" one screen to the right, with another one coming in at the same time. Naturally I'd have to keep drawing both, until the transition is complete. And I'd have to adjust the coordinates I'm drawing at while doing it. Is there a way around specifically handling this special case in every single scene?

Or of I wanted to fade one into the other. Basically the question stays the same, how would you do that without having to handle it in every single scene?

While writing this I'm realizing it will be the same thing for all kinds of transitions. Maybe a central Draw method in the manager could be a solution, where parameters and effects are applied when necessary. But this wouldn't work if objects that are drawn have their own method, and aren't drawn within the scene, or if an effect has to be applied to the whole scene. That means, maybe scenes have to be drawn to their own rendertarget? That way one call to the base class after the normal drawing could be enough, to apply the effects, while drawing it to the main render target. But I once heard there are problems when switching from target to target, back and forth. So is that even a viable option?

As you can see, I have some basic ideas how it might work... but nothing specific. I'd like to learn what's the common way to achieve such things, a general way to apply all kinds of transitions.

share|improve this question
add comment

3 Answers

The Game State Management sample that deals with screen transitions can be found here. (The MSDN site recently updated their App Hub url's so I'm guessing a lot of links will be broken for a while)

Personally I find some of the code to be too complex for beginners, with the constant use of events to be fired when menu items are clicked, and layering of state machines, etc. However I can explain the idea behind all of this.

Each scene has a transition delta time variable, which doesn't change when it's not transitioning. During transitions you increment it each frame. When the delta time reaches a threshold (like 1 or 0) the screen should update itself from "exiting" to "exited". You should pass this variable to functions responsible for drawing the screens.

Maybe you don't want the actual transition behavior coded in the screen object, but it should have some set of parameters to tell the Draw method how it should transition. That way Draw can still take care of the visuals, from position to alpha and anything else you want to add. I am in the process of making "menu skins" for my menu system, adapted from the XNA sample. As you would expect, the skin determines the menu's appearance but also where it should be placed, and how it should transition in/out. This works as a struct of parameters passed on to the Draw method.

Next time the main Update loop runs, the Screen Manager will check through the screens to see which ones have exited and it will remove those from the list.

This way you can have two or more screens at once, so one function can tell Screen A to leave and the other one to enter. Both of them will be "passing through" and don't need to know about each other to know when to finish their transitions.

share|improve this answer
add comment

I don't know if there's a general way of applying transitions but this is how I do it:

In my Game1 class i have this piece of code which basically shows a new scene and hides the active one:

    protected void ShowScene(GameScene scene)
    {
        activeScene.Hide();
        activeScene = scene;
        scene.Show();
    }

Then I have some scenes which inherit from SceneManager.

I made a Fade transition between my scenes in SceneManager:

    public virtual void Show()
    {
        Visible = true;
        Enabled = true;
        alpha = 0;        // Invisible
        fade = Fade.In;   // An enum Fade with values In, Out, Idle
    }

    public virtual void Hide()
    {
        Enabled = true;   // Has to be enabled to run the update method below.
        alpha = 1;        // Fully visible
        fade = Fade.Out;
    }

    public override void Update(GameTime gameTime)
    {
        if (fade != Fade.Out) // This is to avoid having two scenes active at the same
        {                     // time during the transition; this can lead to
                              // unexpected behavior.

            // -- all other code --

            foreach (GameComponent component in components)
            {
                component.Update(gameTime);
            }
        }

        // the enum 'fade' increases or reduces the float 'alpha'

        switch (fade)
        {
            case Fade.In:
                alpha += 0.01f;
                break;
            case Fade.Out:
                alpha -= 0.01f;
                break;
        }

        if (fade != Fade.Idle)
        {
            if (alpha < 0)        // end of Fade.Out
            {
                alpha = 0;
                fade = Fade.Idle;
                Visible = false;  // stop the draw of the scene
                Enabled = false;  // stop the update
            }
            else if (alpha > 1)   // end of Fade.In
            {
                alpha = 1;
                fade = Fade.Idle;
            }
        }

        base.Update(gameTime);
    }

Now that we got the alpha value we can pass it down to all the components in the scene. Those components can then use that alpha value to add transparency on its textures:

    public override void Draw(GameTime gameTime)
    {
        SpriteBatch sBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));

        sBatch.Draw(texture, position, Color.White * alpha);

        base.Draw(gameTime);
    }

If you want a 'slide to a side' transition you can do the same thing but then use the position as variable.

share|improve this answer
    
Thanks for this example. But what I'm after is a way to do that, and much more, without putting transition specific code inside the scenes. –  Mars Jul 10 '12 at 23:46
add comment

There used to be a great state management sample for XNA that was available, called "Game State Management Sample". I can't seem to find it anymore (the first hit on Google is it, but Microsoft moved the page...) You can find the WP7 version which should be nearly identical right here. It has transitions built into it (a fade-in effect, at least) and you should definitely check it out.

share|improve this answer
    
It's still on the app hub. The URL may have been mangled in the latest "split", but it's still there if you search for it. –  Justin Skiles Aug 9 '12 at 23:30
    
I see someone above managed to find it, I'm glad... Microsoft needs to stop this restructuring crap. –  Vaughan Hilts Aug 9 '12 at 23:32
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.