tags:

views:

134

answers:

2

I don't understand what I'm doing wrong here:

public void Draw(GameTime gameTime) // in ScreenManager
{
    SpriteBatch.Begin(SpriteBlendMode.AlphaBlend);
    for (int i = 0; i < Screens.Count; i++)
    {
        if (Screens[i].State == Screen.ScreenState.HIDDEN)
            continue;

        Screens[i].Draw(gameTime);
    }
    SpriteBatch.End(); // null ref exception
}

SpriteBatch itself is not null.

Some more context:

public class MasterEngine : Microsoft.Xna.Framework.Game
{

    public MasterEngine()
    {
        graphicsDeviceManager = new GraphicsDeviceManager(this);
        Components.Add(new GamerServicesComponent(this));

        // ...

        spriteBatch = new SpriteBatch(graphicsDeviceManager.GraphicsDevice);

        screenManager = new ScreenManager(assets, gameEngine, graphicsDeviceManager.GraphicsDevice, spriteBatch);
    }

//...

   protected override void Draw(GameTime gameTime)
    {
        screenManager.Draw(gameTime); // calls the problematic method
        base.Draw(gameTime);
    }
}

Am I failing to initialize something properly?

UPDATE:

As an experiment, I tried this to the constructor of MasterEngine:

spriteBatch = new SpriteBatch(graphicsDeviceManager.GraphicsDevice);

spriteBatch.Begin();
spriteBatch.DrawString(assets.GetAsset<SpriteFont>("calibri"), "ftw", new Vector2(), Color.White);
spriteBatch.End();

This does not cause a NRE. hmm....

UPDATE 2: This does cause an NRE:

protected override void Draw(GameTime gameTime)
{
    spriteBatch.Begin();
    spriteBatch.End(); // boned here
    //screenManager.Draw(gameTime);
    base.Draw(gameTime);
}
A: 

I've not used XNA for a long time, but shouldn't SpriteBatch be lowercase (or have another name), otherwise you'll be referencing the actual class SpriteBatch and not the instance?

chedabob
nah, that doesn't cause a problem. (I changed it to lowercase anyway, and the problem persists.)
Rosarch
+2  A: 

You shouldn't be creating you SpriteBatch in Constructors of your Game class or your DrawableGameComponent classes as it's not guaranteed the GraphicsDevice has been initialized properly at that point. (and in fact you may end up initializing them with null graphics devices :P)

Move your SpriteBatch creation into the overridden LoadContent method

Same with your ScreenManager, your passing in a GraphicsDevice at the wrong point. If your ScreenManager inherits from DrawableGameComponent then you should have access to a GraphicsDevice property from inside it anyway, which you can use in the LoadContent method of you screen manage to load any content that the ScreenManager requires.

Hope that helps.

Sekhat