안녕 얘들 아 내 도움이 필요하다 여기 내 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;
}
이를 추가하여 기존의 문제를 해결하지만 상자가 전혀 작동하지 않습니다. .
무엇? 그러나 나는 내 벽돌 수업에서 그 두 가지를하고있다. (코드의 첫 번째 청크는 game1.cs이고 두 번째 청크는 wall.cs이고 내 세 번째 청크는 brick.cs 임) – Mettalknight
제 편집을 보니 제 첫 제안이 어떤 것이라고 생각하지 않습니다. 차. brick 클래스의 각 인스턴스에는 LoadContent()가 호출되어야합니다. Wall 클래스의 LoadContent 메서드에 1 줄의 코드를 추가하여 각 Brick 객체에서 spriteBatch를 초기화해야합니다. –
LoadContent가 보호되어 있습니다. 나는 그것을위한 방법을 만들려고 노력할 것이지만 나는 그것이 차이를 만들 것이라고 생각하지 않는다. 편집 : 이제 InvalidOperationException이 "spriteBatch = new SpriteBatch (GraphicsDevice);"행에서 처리됩니다. " brick.cs에서 – Mettalknight