How to fade to black in XNA 4

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Lexus Langg
    New Member
    • Nov 2011
    • 1

    How to fade to black in XNA 4

    I'm relatively new to XNA and C#, so please try to use small words. I'm making a Breakout clone for my first real project (simplest thing I could think of), and have gotten fairly far. How would I implement a fade to black after the level ends or the ball flies past the paddle. I also want it to pause the game loop until the fade is complete. Any suggestions?

    My whole game-state management, minus a couple if-elses:
    Code:
        static class GlobalVars
        {
            public static int Lives;
            public static int Points;
            public static bool IsGameRunning;
            public static int Level;
            public static bool Sound;
    
            public static void Reset()
            {
                Lives = 3;
                Points = 0;
                Level = 1;
            }
        }

    Main Loop:
    Code:
            protected override void Update(GameTime gameTime)
            {
                iHelper.Update();
                OtherKeyStuff();
                if (GlobalVars.IsGameRunning)
                {
                    paddle.Update();
                    ball.Update();
    
                    ball.PaddleCollision(paddle.GetLeftBounds(),paddle.GetRightBounds(),paddle.GetCenterBounds());
    
                    if (ball.OffBottom())
                    {
                        DoLives(true);
                        if (GlobalVars.Sound)
                        {
                            Kaboom.Play();
                        }
                        StartGame();
                    }
                    
                    base.Update(gameTime);
                }
            }
    
            protected override void Draw(GameTime gameTime)
            {
                if (GlobalVars.IsGameRunning)
                {
                    GraphicsDevice.Clear(Color.Black);
                    spriteBatch.Begin();
                    DrawBackground();
    
                    foreach (Brick brick in bricks)
                        brick.Draw(spriteBatch);
                    paddle.Draw(spriteBatch);
                    ball.Draw(spriteBatch);
                    DrawInGameText(gameTime);
                    spriteBatch.End();
                    base.Draw(gameTime);
                }
                else
                {
                    //TODO
                }
    
            }
    
            private void DoLives(bool detract) //Add pause at end/ use gamestate
            {
                if (detract)
                {
                    GlobalVars.Lives--;
                }
    
                if (GlobalVars.Lives < 0)
                {
                    string tempPoints;
                    tempPoints = GlobalVars.Points.ToString();
                    this.Exit();
                }
            }
    And the Reset Level code:
    Code:
            private void StartGame() //add IsGameRunning stuff
            {
                if (MediaPlayer.State == MediaState.Stopped)
                {
                    StartGameSoundtrack();
                }
                
                paddle.SetInStartPosition();
                ball.SetInStartPosition(paddle.GetBounds());
    
                bricks = new Brick[bricksWide, bricksHigh];
    
                for (int y = 0; y < bricksHigh; y++)
                {
                    Color tint = Color.White;
    
                    for (int x = 0; x < bricksWide; x++)
                    {
                        bricks[x, y] = new Brick(
                            brickImage,
                            new Rectangle(
                                x * brickImage.Width,
                                y * brickImage.Height,
                                brickImage.Width,
                                brickImage.Height),
                                tint, true);
                    }
                }
            }
    I'm really sorry if this is to much code, I don't know what you guys want to see...
  • GaryTexmo
    Recognized Expert Top Contributor
    • Jul 2009
    • 1501

    #2
    Honestly, the easiest way would be to just draw a black rectangle at an increasing opacity over your entire screen. Control this with some kind of state and update the opacity according to some timing formula. So like, if you want it to fade out over 5 seconds, that's 51 RBG value per second.

    Code:
    private Texture2D m_pixel = null;
    private GraphicsDebice m_graphicsDevice = ...;
    private SpriteBatch m_spritebatch = ...;
    private int m_screenWidth = ...;
    private int m_screenHeight = ...;
    private bool m_fading = false;
    private int m_fadeOpacity = 0;
    private int m_opacityPerSecond;
    private GameTime m_fadeTimeStart;
    ...
    public YourClassConstructor()
    {
      m_pixel = new Texture2D(m_graphicsDevice, 1, 1);
      m_pixel.SetData<Color>(new Color[] { Color.White });
    }
    ...
    public void Update(GameTime gameTime)
    {
      ...
      if (someCondition == true)
      {
        m_fadeTimeStart = gameTime;
        m_opacityPerSecond = 255 / 5;
        m_fading = true;
      }
      ...
      if (m_fading)
      {
        double elapsedSeconds = gameTime.TotalSeconds - m_startTime.TotalSeconds; // a little unsure on this... may not be correct code, but you'll figure it out :D
        m_fadeOpacity += elapsedSeconds * m_opacityPerSecond;
        
        if (m_fadeOpacity >= 255)
        {
          m_fading = false;
          // transition to the next state
        }
      }
      ...
    }
    ...
    public void Draw(GameTime gameTime)
    {
      ...
      m_spriteBatch.Begin();
      ...
      if (m_fading)
      {
        m_spriteBatch.Draw(m_pixel, new Vector2(0, 0), null, new Color(0, 0, 0, m_fadeOpacity), 0f, Vector2.Zero, new Vector2(m_screenWidth, m_screenHeight), SpriteEffects.None, 0);
      }
      ...
      m_spriteBatch.End();
      ...
    }
    ...
    Something to that effect... as long as the fade rectangle is the last thing you draw, it should block out everything behind it. Your alternative would be to have a global opacity and have each object in your game draw with it's own opacity value, then drop that from 255 to 0 over a period of time.

    Comment

    Working...