2013-03-19 2 views
0

안녕 얘들 아 내 도움이 필요하다 여기 내 spriteBatch는 NullReference 예외를 계속 반환하고 내가 뭘 잘못하고 있는지 몰라!? (나는 벽돌 깨기 게임을 만들고있다.) 그리고 내 벽돌이 Game1.cs 안에 만들어 질 때마다 잘 동작하지만 Wall.cs (벽돌 패턴을 표시하고자하는 곳)로 이동하면 게임이 멈추고 NullReference 예외입니다. Heres는 내 코드 :C# XNA SpriteBatch가 null입니까?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Audio; 
using Microsoft.Xna.Framework.Content; 
using Microsoft.Xna.Framework.GamerServices; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Input; 
using Microsoft.Xna.Framework.Media; 

namespace BrickBreaker 
{ 
    /// <summary> 
    /// This is the main type for your game 
    /// </summary> 
    public class Game1 : Microsoft.Xna.Framework.Game 
    { 
     GraphicsDeviceManager graphics; 
     SpriteBatch spriteBatch; 
     private Paddle paddle; 
     private Ball ball; 
     private Texture2D background; 
     private static int screenWidth = 750; 
     private static int screenHeight = 600; 
     private int leftBorder = 20; 
     private int rightBorder = 28; 
     private int topBorder = 20; 
     private readonly int normalBrickResist = 2; 
     private readonly int normalBrickPoints = 10; 
     private Wall wall; 

     //DELETE this shit 
     private Brick brick; 

     /// <summary> 
     /// Contructor for the Game1 class. 
     /// </summary> 
     public Game1() 
     { 
      graphics = new GraphicsDeviceManager(this); 
      Content.RootDirectory = "Content"; 
     } 


     /// <summary> 
     /// Read only property for the screen height. 
     /// </summary> 
     public static int ScreenHeight 
     { 
      get { return screenHeight; } 
     } 

     /// <summary> 
     /// Read only property for the screen width. 
     /// </summary> 
     public static int ScreenWidth 
     { 
      get { return screenWidth; } 
     } 

     /// <summary> 
     /// 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. 
     /// </summary> 
     protected override void Initialize() 
     { 
      graphics.PreferredBackBufferHeight = screenHeight; 
      graphics.PreferredBackBufferWidth = screenWidth; 
      graphics.ApplyChanges(); 

      paddle = new Paddle(this); 
      Components.Add(paddle); 

      wall = new Wall(this); 
      Components.Add(wall); 

      ball = new Ball(this, paddle, leftBorder, rightBorder, topBorder, brick); 
      Components.Add(ball); 

      base.Initialize(); 
     } 

     /// <summary> 
     /// LoadContent will be called once per game and is the place to load 
     /// all of your content. 
     /// </summary> 
     protected override void LoadContent() 
     { 
      spriteBatch = new SpriteBatch(GraphicsDevice); 

      background = Content.Load<Texture2D>("background"); 
     } 

     /// <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 
     } 

     /// <summary> 
     /// Allows the game to run logic such as updating the world, 
     /// checking for collisions, gathering input, and playing audio. 
     /// </summary> 
     /// <param name="gameTime">Provides a snapshot of timing values.</param> 
     protected override void Update(GameTime gameTime) 
     { 
      // Allows the game to exit 
      if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) 
       this.Exit(); 

      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(); 
      Vector2 position = new Vector2(0, 0); 
      spriteBatch.Draw(background, position, Color.White); 
      spriteBatch.End(); 

      base.Draw(gameTime); 
     } 

     public void RemoveComponent(IGameComponent obj) 
     { 
      this.Components.Remove(obj); 
     } 
    } 
} 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Audio; 
using Microsoft.Xna.Framework.Content; 
using Microsoft.Xna.Framework.GamerServices; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Input; 
using Microsoft.Xna.Framework.Media; 

namespace BrickBreaker 
{ 

    /// <summary> 
    /// This is a game component that implements IUpdateable. 
    /// </summary> 
    public class Wall : Microsoft.Xna.Framework.DrawableGameComponent 
    { 
     private Brick brick; 
     private Brick[,] brickLayout = new Brick[5, 8]; 
     private Game game; 
     SpriteBatch spriteBatch; 
     private Texture2D brickImg; 

     public Wall(Game game) 
      : base(game) 
     { 
      this.game = game; 
     } 

     /// <summary> 
     /// Allows the game component to update itself. 
     /// </summary> 
     /// <param name="gameTime">Provides a snapshot of timing values.</param> 
     public override void Draw(GameTime gameTime) 
     { 
      foreach (var item in brickLayout) 
      { 
       if (item != null) 
       { 
        item.Draw(gameTime); 
       } 

      } 

      base.Draw(gameTime); 
     } 

     /// <summary> 
     /// Allows the game component to update itself. 
     /// </summary> 
     /// <param name="gameTime">Provides a snapshot of timing values.</param> 
     public override void Update(GameTime gameTime) 
     { 
      foreach (Brick item in brickLayout) 
      { 
       item.Update(gameTime); 
      } 

      base.Update(gameTime); 
     } 

     /// <summary> 
     /// Allows the game component to perform any initialization it needs to before starting 
     /// to run. This is where it can query for any required services and load content. 
     /// </summary> 
     public override void Initialize() 
     { 
      // TODO: Add your initialization code here 
      foreach (var item in brickLayout) 
      { 
       if (item != null) 
       { 
        item.Initialize(); 
       } 
      } 
      base.Initialize(); 
     } 

     protected override void LoadContent() 
     { 

      int x = 0; 
      int y = 0; 
      Vector2 startPosition; 
      for (int i = 0; i < brickLayout.GetLength(0); i++) 
      { 
       for (int j = 0; j < brickLayout.GetLength(1); j++) 
       { 
        startPosition = new Vector2(x, y); 
        brickLayout[i, j] = new Brick(game, 20, 1, startPosition); 
        x += 20; 
       } 
       y += 20; 
      } 

      base.LoadContent(); 
     } 
    } 
} 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Audio; 
using Microsoft.Xna.Framework.Content; 
using Microsoft.Xna.Framework.GamerServices; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Input; 
using Microsoft.Xna.Framework.Media; 


namespace BrickBreaker 
{ 
    /// <summary> 
    /// This is a game component that implements IUpdateable. 
    /// </summary> 
    public class Brick : Microsoft.Xna.Framework.DrawableGameComponent 
    { 
     enum brickType 
     { 
      Regular1, 
      Regular2, 
      Regular3, 
      Regular4, 
      Regular5, 
      PowerUp, 
      Unbreakable 
     } 

     private Texture2D brick; 
     private SpriteBatch spriteBatch; 
     private Game game; 
     private int brickValue; 
     private Vector2 startPosition, position; 
     private Rectangle collisionBox; 
     private int brickWidth; 
     private bool isBroken = false; 
     private int resistance; 

     public Brick(Game game, int brickValue, int resistance, Vector2 startPosition) 
      : base(game) 
     { 
      this.brickValue = brickValue; 
      this.game = game; 
      this.resistance = resistance; 
      this.startPosition = startPosition; 
     } 

     public Boolean IsBroken 
     { 
      get 
      { 
       return this.isBroken; 
      } 
      set 
      { 
       this.isBroken = value; 
      } 
     } 

     /// <summary> 
     /// Property for the paddle collision box. 
     /// </summary> 
     public Rectangle CollisionBox 
     { 
      get { return collisionBox; } 
     } 


     /// <summary> 
     /// Read only property for the paddle width. 
     /// </summary> 
     public int BrickWidth 
     { 
      get { return brickWidth; } 
     } 

     /// <summary> 
     /// Allows the game component to perform any initialization it needs to before starting 
     /// to run. This is where it can query for any required services and load content. 
     /// </summary> 
     public override void Initialize() 
     { 
      // TODO: Add your initialization code here 

      base.Initialize(); 
     } 

     /// <summary> 
     /// Allows the game component to update itself. 
     /// </summary> 
     /// <param name="gameTime">Provides a snapshot of timing values.</param> 
     public override void Update(GameTime gameTime) 
     { 
      // TODO: Add your update code here 

      base.Update(gameTime); 
     } 

     /// <summary> 
     /// Allows the game component to update itself. 
     /// </summary> 
     /// <param name="gameTime">Provides a snapshot of timing values.</param> 
     public override void Draw(GameTime gameTime) 
     { 

      if (isBroken == false) 
      { 
       spriteBatch.Begin(); 
       spriteBatch.Draw(brick, this.position, Color.White); 
       spriteBatch.End(); 
      } 


      base.Draw(gameTime); 
     } 

     /// <summary> 
     /// Comment 
     /// </summary> 
     protected override void LoadContent() 
     { 
      spriteBatch = new SpriteBatch(GraphicsDevice); 
      brick = game.Content.Load<Texture2D>("brick"); 

      collisionBox = new Rectangle(0, 0, brick.Width, brick.Height); 

      position = startPosition; 
      collisionBox.X = (int)position.X; 
      collisionBox.Y = (int)position.Y; 

      base.LoadContent(); 
     } 

     public void TakeHit() 
     { 
      resistance--; 

      if (resistance == 0) 
       IsBroken = true; 

     } 

    } 
} 

편집 : 이제 충돌을 wall.cs

for (int i = 0; i < brickLayout.GetLength(0); i++) 
    { 
     for (int j = 0; j < brickLayout.GetLength(1); j++) 
     { 
      startPosition = new Vector2(x, y); 
      brickLayout[i, j] = new Brick(game, 20, 1, startPosition); 
      //Added this line: 
      brickLayout[i, j].Initialize(); 
      x += 45; 
     } 
     x = 150; 
     y += 25; 
    } 

이를 추가하여 기존의 문제를 해결하지만 상자가 전혀 작동하지 않습니다. .

답변

0

그리기 메서드의 SpriteBatch.Begin() 줄에서 Brick 클래스의 NullReferenceException이 발생합니다.

1

Brick 클래스를 자세히 살펴보십시오.

spriteBatch = new SpriteBatch(GraphicsDevice); 

그리고 당신이 당신의 Draw 방법으로 호출해야합니다 : 귀하의 벽 클래스에서 당신은 spriteBatch를 초기화하지 않는, 당신은 BeginEnd

귀하의 LoadContent 메소드를 호출하지 않는 것은이 필요 :

spriteBatch.Begin(); 

spriteBatch.End(); 

편집 : 벽돌 클래스에서 LoadContent를 호출하지 않으므로 spriteBatch가 초기화되지 않습니다. 시도해보십시오 :

protected override void LoadContent() 
    { 

     int x = 0; 
     int y = 0; 
     Vector2 startPosition; 
     for (int i = 0; i < brickLayout.GetLength(0); i++) 
     { 
      for (int j = 0; j < brickLayout.GetLength(1); j++) 
      { 
       startPosition = new Vector2(x, y); 
       brickLayout[i, j] = new Brick(game, 20, 1, startPosition); 
       // This new line... 
       brickLayout[i, j].LoadContent(); 
       x += 20; 
      } 
      y += 20; 
     } 

     base.LoadContent(); 
    } 
+0

무엇? 그러나 나는 내 벽돌 수업에서 그 두 가지를하고있다. (코드의 첫 번째 청크는 game1.cs이고 두 번째 청크는 wall.cs이고 내 세 번째 청크는 brick.cs 임) – Mettalknight

+0

제 편집을 보니 제 첫 제안이 어떤 것이라고 생각하지 않습니다. 차. brick 클래스의 각 인스턴스에는 LoadContent()가 호출되어야합니다. Wall 클래스의 LoadContent 메서드에 1 줄의 코드를 추가하여 각 Brick 객체에서 spriteBatch를 초기화해야합니다. –

+0

LoadContent가 보호되어 있습니다. 나는 그것을위한 방법을 만들려고 노력할 것이지만 나는 그것이 차이를 만들 것이라고 생각하지 않는다. 편집 : 이제 InvalidOperationException이 "spriteBatch = new SpriteBatch (GraphicsDevice);"행에서 처리됩니다. " brick.cs에서 – Mettalknight