即使我使用变量获得null错误
我想学习MonoGame,我正在尝试做基本的东西,我已经想到了我自己的大部分,但我得到一个空指针,我不知道为什么。我试图让MainMenuScene只绘制纹理,但在SceneManager中currentScene不断给我空指针,我不知道为什么。我张贴我的SceneManager代码,但其余的将在github上。它没有太多的代码,所以它不应该花很长时间,如果你看看它。我感到非常困惑,我不知道该怎么去谷歌试图弄清楚自己。即使我使用变量获得null错误
https://github.com/eatmykhack/MonoGame.git
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tutorial.Scenes;
class SceneManager
{
private static SceneManager instance = new SceneManager();
Scene currentScene, newScene;
Dictionary<string, Scene> sceneDirectory =new Dictionary<string, Scene>();
public static SceneManager getInstance()
{
return instance;
}
public static Scene getCurrentScene()
{
return instance.currentScene;
}
public static void changeScene(Scene scene)
{
}
public static void addScene(string sceneName)
{
instance.newScene = instance.sceneDirectory[sceneName];
}
public void update() { currentScene.Update(); }
public void draw(SpriteBatch spriteBatch) { currentScene.Draw(spriteBatch); }
public void Initialize()
{
instance.sceneDirectory["MainMenuScene"] = new MainMenuScene();
instance.currentScene = instance.sceneDirectory["MainMenuScene"];
}
public void LoadContent(ContentManager content)
{
instance.currentScene.LoadContent(content);
}
public void UnloadContent()
{
instance.currentScene.UnloadContent();
}
}
你得到一个NullReferenceException
因为你是混合在你的代码的静态和实例字段:
有几个问题:
你
SceneManager
有public构造函数,但其实例方法都访问相同的静态(单例)实例。您的
SceneManager.Draw
方法确实是而不是访问静态实例。你
Game
类实例化一个单独ScreenManager
情况下,这意味着单被初始化,但Game
小号实例不是。这是允许的,因为1.
有固定的这几种方式:
的首选方式:从SceneManager
删除静态的东西。无论如何,你的游戏将在Game
类中有一个实例,你可以简单地将实例传递给任何场景。没有道理。
但是,如果你想保持这个类是一个单例,你需要改变一些东西。人们通常需要这样做,因为他们懒得通过SceneManager
到每个场景实例。所以,单身人士是不好的,你不能单元测试任何东西,但我相信大多数独立游戏开发人员不会太在意单元测试,如果一切都是静态的,并且可以从任何地方访问,那么将是最快乐的。
-
使构造
private
,所以没有其他类(如Game
)可以实例化。如果有人想访问实例,他们应该通过getInstance()
方法来完成。其中,顺便说一句,可能更是一个属性,而不是:public class SceneManager { // private constructor means other classes cannot instantiate this private SceneManager() { } private static readonly SceneManager _instance = new SceneManager(); public static SceneManager Instance { get { return _instance; } } }
如果你现在尝试在你的
Game
类退出这个功能:var sceneManager = new SceneManager();
你的编译器会告诉你,它不会工作方式。
-
你
SceneManager
应该只有一个单一静态方法/属性:getInstance()
或Instance
属性等上面显示。所有其他方法应该是该唯一实例的实例方法,并且根本不访问instance
字段。无论如何他们正在访问该实例。这是一个坏主意,有实例方法访问静态字段:这是错误:
public void Initialize() { var mainScene = = new MainMenuScene(); instance.sceneDirectory["MainMenuScene"] = mainScene; instance.currentScene = mainScene; }
但这是好的(和
this
关键字是多余的,当然):public void Initialize() { var mainScene = = new MainMenuScene(); this.sceneDirectory["MainMenuScene"] = mainScene; this.currentScene = mainScene; }
因为你要这样使用它反正:
// you're basically doing the same thing, but // it's immediately clear what's going on, and there // is no room for errors: var manager = SceneManager.Instance; manager.Initialize();
最简单的方法可以确保您正确地完成
SceneManager
类中的所有对instance
的引用。
的可能的复制[什么是一个NullReferenceException,如何解决呢?(http://*.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i -fix-it) – Viru
我知道NullReferenceException是什么,但我的问题是我正在使用有问题的变量,但它仍然给我它。 – user4648142
你是什么意思我使用变量?如何使用变量保证你不会得到空引用异常?无论如何,如果你发布堆栈跟踪,那么你会得到一些代码的哪一部分可能失败的指针....如果你可以调试,那么你甚至可以确定代码行失败....但我没有在你的问题中看到任何这样的信息 – Viru