Search code examples
c#xna

XNA: ArgumentNullException when referencing value from a public class


I am still a novice at programming, and I'm currently trying to make a menu for a test game. However, I am having an issue where, when I reference a value from class, Language.cs in my Main.cs using spriteBatch.DrawString, it returns an ArgumentNullException. Any help would be greatly appreciated.

The debugger highlights the following segment under DrawMainMenu() in my Main.cs:

spriteBatch.DrawString(UIFont, Language.mainMenu[0], new Vector2(mainWidth / 2, mainHeight / 2 - 192), Color.White);

I'm not sure if it's an issue of what order I'm using my methods in, but here's what the whole page of Main.cs looks like. Please pardon some of the mess, as I have been experimenting with a variety of things in this program.

public class Main : Game
{
    GraphicsDeviceManager graphics;
    public static SpriteBatch spriteBatch;
    public static SpriteFont UIFont;
    public static Texture2D logo;
    public static Texture2D titleBack;
    public static Texture2D titleSelect;
    public static int menuType;
    public static Texture2D cursor1;
    public static MouseState mouseState;
    public static MouseState mouseStatePrevious;
    public static MouseState oldState;
    public static MouseState newState;
    public static int mouseX = mouseState.X;
    public static int mouseY = mouseState.Y;
    public static Vector2 cursorPos;
    public static int strength = 0;
    public static int mainWidth = 1920;
    public static int mainHeight = 1080;
    public static bool showSplash = true;
    public int splashCounter;
    public static int fadeCounter;
    public static bool gameTimeActive = false;

    private static int maxMenuItems = 12;
    public static int selectedMenu = -1;
    public static int selectedMenuType = -1;
    public static bool mainMenu = false;
    public static Vector2 screenPosition;

    Player player = new Player();

    public Main()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";

        graphics.PreferredBackBufferWidth = mainWidth;  // set this value to the desired width of your window
        graphics.PreferredBackBufferHeight = mainHeight;   // set this value to the desired height of your window
        //graphics.PreferredBackBufferWidth = GraphicsDevice.DisplayMode.Width;
        //graphics.PreferredBackBufferHeight = GraphicsDevice.DisplayMode.Height;
        graphics.ApplyChanges();
    }

    // Allows the game to perform any initialization it needs to before starting to run.
    // This is where it can query for any required services and load any non-graphic
    // related content.  Calling base.Initialize will enumerate through any components
    // and initialize them as well.

    protected override void Initialize()
    {
        // TODO: Add your initialization logic here

        player.Initialize();
        base.Initialize();
    }

    // LoadContent will be called once per game and is the place to load
    // all of your content.
    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        // Load initial content...

        spriteBatch = new SpriteBatch(GraphicsDevice);
        logo = Content.Load<Texture2D>(@"Textures\StudioLogoW");

        UIFont = Content.Load<SpriteFont>(@"Textures\Fonts\Font_FrontEnd");
        cursor1 = Content.Load<Texture2D>(@"Textures\CursorWhite");
        titleBack = Content.Load<Texture2D>(@"Textures\UI\TitleBackground");
        titleSelect = Content.Load<Texture2D>(@"Textures\UI\TitleSelect");


        player.LoadContent(Content);

        // TODO: use this.Content to load the rest of the game content...


    }


    // UnloadContent will be called once per game and is the place to unload
    // all content.
    protected override void UnloadContent()
    {
        // TODO: Unload any non ContentManager content here
    }

    // Allows the game to run logic such as updating the world,
    // checking for collisions, gathering input, and playing audio.
    // <param n
    protected override void Update(GameTime gameTime)
    {
        // Enable mouse funtion in game.
        //this.IsMouseVisible = true;

        cursorPos = new Vector2(mouseState.X, mouseState.Y);

        mouseState = Mouse.GetState();

        base.Update(gameTime);

        // Get Mouse State, in this case, we're checking to see if a button was clicked, and which one.
        // Depending on which button was pressed, it will either add or subract strength.
        if (gameTimeActive)
        {
            player.Update(gameTime);

            if (mouseState.LeftButton == ButtonState.Pressed && mouseStatePrevious.LeftButton == ButtonState.Released)
                strength++;
            if (mouseState.RightButton == ButtonState.Pressed && mouseStatePrevious.RightButton == ButtonState.Released)
                strength--;

            if (strength > 255)
                strength = 255;
            if (strength < 0)
                strength = 0;

            mouseStatePrevious = mouseState;
        }


        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        //Add your update logic here
    }

    protected void DrawSplash(GameTime gameTime) //Section for drawing our splash logo, and fading it in and out.
    {
        base.GraphicsDevice.Clear(Microsoft.Xna.Framework.Color.Black);
        base.Draw(gameTime);
        Main.spriteBatch.Begin();
        this.splashCounter++;
        Microsoft.Xna.Framework.Color white = Microsoft.Xna.Framework.Color.White;
        byte splashByte = 0;
        if (this.splashCounter <= 75)
        {
            float splashNum = (float)this.splashCounter / 75f * 255f;
            splashByte = (byte)splashNum;
        }
        else if (this.splashCounter <= 225)
        {
            splashByte = 255;
        }
        else if (this.splashCounter <= 300)
        {
            int splashNum2 = 225 - this.splashCounter;
            float splashNum3 = (float)splashNum2 / 75f * 255f;
            splashByte = (byte)splashNum3;
        }
        else
        {
            Main.showSplash = false;
            Main.mainMenu = true;
            Main.selectedMenu = 0;
            Main.fadeCounter = 75;
        }
        white = new Color((int)splashByte, (int)splashByte, (int)splashByte, (int)splashByte);
        Main.spriteBatch.Draw(Main.logo, new Rectangle(0, 0, Main.mainWidth, Main.mainHeight), white);
        Main.spriteBatch.End();
    }
    protected void DrawMainMenu() //Section for drawing our Main Menu and fading it in after the splash logo.
    {
        Language.lang = 1;
        graphics.GraphicsDevice.Clear(Color.Black);

        // Display some stuff. In this case, we're displaying the logo and some text.
        spriteBatch.Begin();

        splashCounter++;
        Microsoft.Xna.Framework.Color white = Microsoft.Xna.Framework.Color.White;

        spriteBatch.Draw(titleBack, new Rectangle(0, 0, mainWidth, mainHeight), Color.White);
        //spriteBatch.DrawString(UIFont, "Strength: " + strength, new Vector2(mainWidth / 2, 50), Color.White);
        //player.Draw(spriteBatch);

        if (selectedMenu == 0)
        {
            spriteBatch.DrawString(UIFont, Language.mainMenu[0], new Vector2(mainWidth / 2, mainHeight / 2 - 192), Color.White);
        }

        spriteBatch.Draw(cursor1, cursorPos, Color.White);
        spriteBatch.End();

        //base.Draw(gameTime);

    }
    // This is called when the game should draw itself.
    // <param name="gameTime">Provides a snapshot of timing values.</param>
    protected override void Draw(GameTime gameTime)
    {
        if (Main.showSplash)
        {
            DrawSplash(gameTime);
            return;
        }

        if (Main.mainMenu)
        {
            gameTimeActive = false;
            DrawMainMenu();
            return;
        }
    }
}

And here is my Language.cs:

public class Language
{
    public static int lang = 0;
    public static string[] mainMenu = new string[99];
    public static string[] debugMenu = new string[99];

    public static void MenuStrings()
    {
        if (lang == 1)
        {
            //For unavailable functions
            mainMenu[99] = "Currently unavailable";
            //Main Menu
            mainMenu[0] = "Single Player";
            mainMenu[1] = "Multiplayer";
            mainMenu[2] = "Options";
            mainMenu[3] = "Credits";
            mainMenu[4] = "Exit";
            //Single Player - Character
            mainMenu[5] = "New Character";
            mainMenu[6] = "Load Character";
            //Single Player - World
            mainMenu[7] = "New World";
            mainMenu[8] = "Load World";

            //Multiplayer - Front
            mainMenu[9] = "Host";
            mainMenu[10] = "Join";
            //Multiplayer - Host
            mainMenu[11] = "Game Mode";
        }
    }
}

Solution

  • You never called your Language.MenuStrings() method, so Language.mainMenu just contains 99 nulls.