2016-04-20 12 views
1

Ich bin eigentlich ein neuer Student in XNA, finde diese Bibliothek sehr interessant, aber mir fehlt noch etwas Wissen, um weiter zu gehen, da ich ein Problem fühlte, das ich nicht selbst beheben kann :(C# ArgumentNullException wurde nicht behandelt (SpriteBatch.Draw)

Die spriteBatch.Draw() -Methode sagt meine Textur ist null, aber ich habe es in einer Resources.cs-Klasse geladen und die Textur in MainMenu.cs übergeben, so dass ich nicht wirklich weiß, wo das Problem liegt wenn jemand mir darüber helfen könnte, würde ich sehr dankbar sein!

Resources.cs

class Resources 
{ 
    public static Texture2D pixel; 
    public static Texture2D startButton, loadButton, quitButton; 

    public static SpriteFont consoleFont; 

    public static void LoadContent(ContentManager Content) 
    { 
     pixel = Content.Load<Texture2D>("Pixel"); 
     consoleFont = Content.Load<SpriteFont>("Console"); 

     // UI Ressources : 
     startButton = Content.Load<Texture2D>("UI/StartButton"); 
     loadButton = Content.Load<Texture2D>("UI/LoadButton"); 
     quitButton = Content.Load<Texture2D>("UI/QuitButton"); 
    } 
} 

MainMenu.cs

class MainMenu 
{ 
    // Fields 
    List<Button> buttons = new List<Button>(); 

    // Constructors 
    public MainMenu() 
    { 
     this.buttons.Add(new Button(new Vector2(480, 132), 256, 48, Resources.startButton)); 
     this.buttons.Add(new Button(new Vector2(480, 212), 256, 48, Resources.loadButton)); 
     this.buttons.Add(new Button(new Vector2(480, 292), 256, 48, Resources.quitButton)); 
    } 

    // Methods 

    // Update 
    public void Update() 
    { 
    } 

    // Draw 
    public void Draw(SpriteBatch spriteBatch) 
    { 
     foreach (Button button in buttons) 
     { 
      button.Draw(spriteBatch); 
     } 
    } 
} 

Button.cs

class Button : UIElement 
{ 
    int width, height; 
    Texture2D texture; 

    public Button() 
    { 
    } 

    public Button(Vector2 b_position, int b_width, int b_height, Texture2D b_texture) 
    { 
     this.position = b_position; 
     this.width = b_width; 
     this.height = b_height; 
     this.texture = b_texture; 
    } 

    public void Update() 
    { 
    } 

    public void Draw(SpriteBatch spriteBatch) 
    { 
     spriteBatch.Draw(texture, position, Color.White); 
    } 
} 

Antwort

0

Einfach wirklich
Sie müssen nur die anrufende Reihenfolge der Funktionen von Game1 kennen. Zuerst wird der Konstruktor von Game1 aufgerufen. Dort hast du mainMenu = new MainMenu();. Danach gehen Initialize, Load und so weiter. Sie müssen mainMenu = new MainMenu(); von Game1-Konstruktor zu Load Funktion verschieben, nach Resources.LoadContent(Content);, so dass die Ressourcen geladen werden können, bevor sie in MainMenu verwendet werden. Ihr Game1.cs Code sollte so aussehen:

public class GameMain : Microsoft.Xna.Framework.Game 
{ 
    GraphicsDeviceManager graphics; 
    SpriteBatch spriteBatch; 

    MainMenu mainMenu; 

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

     this.IsMouseVisible = true; 
    } 

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

     base.Initialize(); 
    } 

    protected override void LoadContent() 
    { 
     // Create a new SpriteBatch, which can be used to draw textures. 
     spriteBatch = new SpriteBatch(GraphicsDevice); 

     // TODO: use this.Content to load your game content here 
     Resources.LoadContent(Content); 
     mainMenu = new MainMenu(); 
    } 

    protected override void UnloadContent() 
    { 
     // TODO: Unload any non ContentManager content here 
    } 

    protected override void Update(GameTime gameTime) 
    { 
     // Allows the game to exit 
     if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) 
      this.Exit(); 

     // TODO: Add your update logic here 
     base.Update(gameTime); 
    } 

    protected override void Draw(GameTime gameTime) 
    { 
     GraphicsDevice.Clear(Color.CornflowerBlue); 

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

Danke, dass es funktioniert! Ich wusste nicht, dass ich das so machen könnte, ich habe ein Video gesucht, in dem der Typ sein Menü im Spielkonstruktor erklärt, ich sehe es nicht immer so, es ist logisch wenn ich darüber nachdenke: D –

+0

@JeanMeier das Mann hatte wahrscheinlich keine Ressourcen Klasse: D btw, das ist ein gutes Konzept! Die Ressourcenklasse (Sie könnten es statisch machen). Mach weiter! – Monset

0

Während ich sehe deine Spielklasse nicht meine erste Annahme ist, dass Ihr nie der Öffentlichkeit static void Loadcontent (Contentmanager Inhalt) Aufruf der Methode in Ihrem Ressourcenklasse Da diese Funktion Ihre Texturen instanziiert, wird sie möglicherweise nicht aufgerufen.

+0

Ich dachte, es würde eine neue Nachricht nach diesem hinzufügen, sorry, ich habe die Spielklasse oben hinzugefügt :)! –

0

Vielen Dank für Ihre Antwort! In der Tat habe ich vergessen, die Game-Klasse aufzunehmen, ist das der richtige Weg, um die Ressourcen aufzurufen?

public class GameMain : Microsoft.Xna.Framework.Game 
{ 
    GraphicsDeviceManager graphics; 
    SpriteBatch spriteBatch; 

    MainMenu mainMenu; 

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

     this.IsMouseVisible = true; 

     mainMenu = new MainMenu(); 
    } 

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

     base.Initialize(); 
    } 

    protected override void LoadContent() 
    { 
     // Create a new SpriteBatch, which can be used to draw textures. 
     spriteBatch = new SpriteBatch(GraphicsDevice); 

     // TODO: use this.Content to load your game content here 
     Resources.LoadContent(Content); 
    } 

    protected override void UnloadContent() 
    { 
     // TODO: Unload any non ContentManager content here 
    } 

    protected override void Update(GameTime gameTime) 
    { 
     // Allows the game to exit 
     if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) 
      this.Exit(); 

     // TODO: Add your update logic here 
     base.Update(gameTime); 
    } 

    protected override void Draw(GameTime gameTime) 
    { 
     GraphicsDevice.Clear(Color.CornflowerBlue); 

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