2016-02-12 18 views
0

我想學習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(); 
    } 
} 
+2

的可能的複製[什麼是一個NullReferenceException,如何解決呢?(http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i -fix-it) – Viru

+0

我知道NullReferenceException是什麼,但我的問題是我正在使用有問題的變量,但它仍然給我它。 – user4648142

+1

你是什麼意思我使用變量?如何使用變量保證你不會得到空引用異常?無論如何,如果你發佈堆棧跟蹤,那麼你會得到一些代碼的哪一部分可能失敗的指針....如果你可以調試,那麼你甚至可以確定代碼行失敗....但我沒有在你的問題中看到任何這樣的信息 – Viru

回答

0
你聲明 Scene爲抽象類

,所以你不能僅僅把它作爲你正在做的:Scene currentScene, newScene。 (有關抽象類的更多詳細信息,請參閱this參考)。

要麼使現場非抽象類類型或創建另一個類,從抽象類繼承,看你的代碼,這將是這樣的:

public class myScene : Scene 
    { 
     public override void Update() 
    { 
     //do something 
    } 

    // etc. 

    } 
+0

這是不正確的。你不能*實例化一個抽象類,但是你當然可以擁有一個該類型的變量(並且你應該*有這樣的變量,因爲這是OOP的全部重點)。 – Groo

0

你得到一個NullReferenceException因爲你是混合在你的代碼的靜態和實例字段:

有幾個問題:

  1. SceneManagerpublic構造函數,但其​​實例方法都訪問相同的靜態(單例)實例。

  2. 您的SceneManager.Draw方法確實是而不是訪問靜態實例。

  3. Game類實例化一個單獨ScreenManager情況下,這意味着單被初始化,但Game小號實例不是。這是允許的,因爲1.

有固定的這幾種方式:

的首選方式:從SceneManager刪除靜態的東西。無論如何,你的遊戲將在Game類中有一個實例,你可以簡單地將實例傳遞給任何場景。沒有道理。

但是,如果你想保持這個類是一個單例,你需要改變一些東西。人們通常需要這樣做,因爲他們懶得通過SceneManager到每個場景實例。所以,單身人士是不好的,你不能單元測試任何東西,但我相信大多數獨立遊戲開發人員不會太在意單元測試,如果一切都是靜態的,並且可以從任何地方訪問,那麼將是最快樂的。

  1. 使構造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(); 
    

    你的編譯器會告訴你,它不會工作方式。

  2. 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的引用。

相關問題