Xna NullReferenceException未处理(对象引用未设置为实例错误)

时间:2014-01-04 16:30:46

标签: c# object xna nullreferenceexception

我目前正在开发一个关于XNA的项目。我的问题是我正在尝试将精灵字体加载到屏幕上(通过将其加载到Game1类中),然后继续将其传递到绘图方法中的另一个类,以进一步将其绘制到屏幕上,除了我得到的进行中的错误。

我已经尝试查看整个代码,并意识到精灵字体确实已初始化,因为它已加载。我以前使用if语句来检查对象是否为空,据我所知,它不是,所以可能是什么问题?这是我课程的一小部分。任何帮助肯定会受到赞赏。也很遗憾长代码,我觉得它需要大部分才能真正理解问题。

Game1 Class的Tid位

protected override void LoadContent()
{
    #region loadTextures
    // Create a new SpriteBatch, which can be used to draw textures.
    spriteBatch = new SpriteBatch(GraphicsDevice);
    backGround = Content.Load<Texture2D>("MainMenu");
    graphics.PreferredBackBufferWidth = screenWidth; // width of screen..
    graphics.PreferredBackBufferHeight = screenHeight; //height of screen..

    IsMouseVisible = true;
    graphics.ApplyChanges(); // load images...

    HealthBar = Content.Load<Texture2D>("HealthBar");
    btnPlay = new cButton(Content.Load<Texture2D>("Button1"), graphics.GraphicsDevice);
    movement = new Movement(Content.Load<Texture2D>("SpritesRe"), new Vector2(rndXpos, rndYpos), 64, 57, HealthBar, cBar,Content.Load<Texture2D>("Grave"));
    npc_creation = new NPC_Creation(Content.Load<Texture2D>("MonsterSprite"), screenRectangle,HealthBar,Content.Load<Texture2D>("Grave"));
    btnPlay.setPosition(new Vector2(350, 300));
    spritefont = Content.Load<SpriteFont>("OnscreenLevel");

    StartGame();
    #endregion
}

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

protected override void Update(GameTime gameTime)
{
    MouseState mouse = Mouse.GetState();
    // Allows the game to exit
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
        this.Exit();

    switch (CurrentGameState)
    {
        case GameState.MainMenu: // if mouse is clicked... call method
            if (btnPlay.isClicked == true) CurrentGameState = GameState.Playing;
            btnPlay.Update(mouse);
            break;

        case GameState.Playing: // if true.. load new image...
            backGround = Content.Load<Texture2D>("Game Map");
            break;
    }


    //checks if character takes damage from being in range of enemy
    npc_creation.charWithinDamageRange(movement.getCharLocation());
    //checks if character is within sight range
    npc_creation.charWithinRange(movement.getCharLocation());
    //calls on monster update method, with the inputs:
    npc_creation.Update(gameTime, npc_creation.withinRangeOrNot(), movement.getCharLocation());

    //checks if monster is in range of character attack
    npc_creation.monsterTakeDamageRange(movement.getAttackRadius());

    npc_creation.charWithinDamageRange(movement.getCharLocation());

    if (npc_creation.withinDamageRangeOrNot() == true)
    {
        movement.decreaseCharHealth();
        npc_creation.charWithinDamageRange(movement.getCharLocation());
        npc_creation.withinDamageRangeOrNot();
    }

    while (npc_creation.inAttackRadius() == true)
    {
        npc_creation.decreaseMobHealth();
        movement.resetAttackRadius();
        npc_creation.monsterTakeDamageRange(movement.getAttackRadius());
        npc_creation.inAttackRadius();
    }
    movement.Update(gameTime);
    base.Update(gameTime);
}

/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);

    spriteBatch.Begin();
    //Draw Any Scene Stuff Here

    spriteBatch.Draw(backGround, Vector2.Zero, Color.White);

    switch (CurrentGameState)
    {
        case GameState.MainMenu: // if on main menu... draw button...
            btnPlay.Draw(spriteBatch);
           // chardev.Draw(spriteBatch,spritefont);
            break;

        case GameState.Playing: // otherwise.. draw the character sprites
            movement.Draw(spriteBatch);
        npc_creation.Draw(spriteBatch, Color.White);
        chardev.Draw(spriteBatch, spritefont);//THIS IS WHERE THE SPRITEFONT IS PASSED TO THE DRAW METHOD!!!
            break;  
    }

    spriteBatch.End();
    // TODO: Add your drawing code here
    base.Draw(gameTime);
}

角色发展课(绘制方法所在的位置)

class charDevelopment
{
    #region initalize


    int EXP = 50; // starting exp.. must be level 1...
    int LEVEL = 1;
    int SP = 10; // starting skill points
    int y;

    #endregion 

    public charDevelopment(int EXP)
    { // set value
        this.EXP = EXP;
        calcEXP(EXP);
    }

    public void calcEXP(int EXP)
    { // formula to calculate exp... arithmetic sequence... (150,300,600,1200,2400 etc..)
        y = 25 * EXP * (1 + EXP);
        checkLevel(y);
    }

    public int getEXP
    {
        get {return getEXP;}
        set {getEXP = EXP;}
    }
    #region levelCheck

    public void checkLevel(int y) 
    {
        // increment hp each level up (Can't spend skill points on it)
        if (y < 50)
        {
            LEVEL = 1;
            SP = 10;
        } // NEED A MORE EFFICIENT WAY TO DO THIS... possible for loop? ideas
        else if (y >= 50 && y < 150)
        {
            LEVEL = 1; SP += 10;
        }
        else if (y >= 150 && y < 300)
        {
            LEVEL = 2; SP += 10;
        }
        else if (y >= 300 && y < 600)
        {
            LEVEL = 3; SP += 10;
        }
        else if (y >= 600 && y < 1200)
        {
            LEVEL = 4; SP += 15;
        }
        else if (y >= 1200 && y < 2400)
        {
            LEVEL = 5; SP += 15;
        }
        else if (y >= 2400 && y < 4800)
        {
            LEVEL = 6; SP += 15;
        }
        else if (EXP >= 4800 && EXP < 9600)
        {
            LEVEL = 7; SP += 20;
        }
        else if (y >= 9600 && y < 19200)
        {
            LEVEL = 8; SP += 20;
        }
        else if (y >= 19200 && y < 38400)
        {
            LEVEL = 9; SP += 20;
        }
        else if (y >= 38400 && y < 76800)
        {
            LEVEL = 10; SP += 20;
        }
    }
    #endregion 

    public void checkSP ()
    {
        if(SP >0)
        {
            // display screen to chose skills which should be enhanced...
        }

    }

    public void Draw(SpriteBatch spritebatch, SpriteFont spritefont)
    {
        spritebatch.DrawString(spritefont, "Level: " , new Vector2(5, 0), Color.White);
    }

}

另一个类中的draw方法..检查敌人的怪物是否死了......用户获得exp ...将其传递给类

public void Draw(SpriteBatch spritebatch, Color color)
{ // draw the texture
    if (Alive == true)
    {
        spritebatch.Draw(texture, pos, color);
        spritebatch.Draw(HealthBar, new Rectangle((int)pos.X - 2, (int)pos.Y - 8, (int)(HealthBar.Width * ((double)CurrentHealth / 100)), 5), Color.Red);
    }

    else if (Alive == false) // if the monster is dead... i.e health is 0....
    {// draw the grave... need a timer here...
        spritebatch.Draw(Grave, pos, color);
        speedXnpc = 0;
        speedYnpc = 0;
        monsterSpeed = 0;
        tempEXP += 25;
        chardev = new charDevelopment(tempEXP);// this line PASSES THE EXP
    }
}

1 个答案:

答案 0 :(得分:0)

请在行上设置断点

“chardev.Draw(spriteBatch,spritefont);”

并验证spriteFont不是“null”?

如果您不知道断点是什么:右键单击代码行并单击“断点&gt;插入断点”。如果你然后开始游戏,它会停在这一行,并在一个名为“Locals”的窗口中显示变量。单击窗口中“this”附近的加号,然后选中“spriteFont”值。我希望很清楚。