我正在构建一个icosphere,我已经得到了代码的绘制部分,但我一直得到一个NullReferenceException是未处理的错误。我知道它指的是哪些代码,但我不知道实际上是什么错误或如何解决它。
这是类代码:
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 Icosahedron_Test
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Camera camera;
VertexPositionColor[] verts;
VertexBuffer vertexBuffer;
BasicEffect effect;
Matrix worldTranslation = Matrix.Identity;
Matrix worldRotation = Matrix.Identity;
int radius = 1; //planet radius
int refinement = 2; // number of times to refine surface
TriXYZ[] vertices; // array containin vertex locations
Icosahedron planet;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
/// <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()
{
camera = new Camera(this, new Vector3(0, 0, 5),
Vector3.Zero, Vector3.Up);
Components.Add(camera);
planet = new Icosahedron(radius, refinement, vertices); // create the planet object ( the icosphere )
vertices = planet.InitializeArray(); // fill the initial verticies list (TriXYZ[])
//Here is where you will get the world radius and number of time to refine. For now, use constants
vertices = planet.Refine(vertices, refinement); // subdivide the triangles as many times as is specified by refinement variable
// at this point, I should be able to move on to draw and create the list for drawing the triangles of the icosphere
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()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
//Initialize Verticies
VertexPositionColor[] verts;
verts = planet.BuildList(vertices);
//set vertex data in vertexBuffer
vertexBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionColor),
verts.Length, BufferUsage.None);
vertexBuffer.SetData(verts);
//Initialize BAsic effect
effect = new BasicEffect(GraphicsDevice);
}
/// <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();
//Translation
KeyboardState keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyDown(Keys.Left))
worldTranslation *= Matrix.CreateTranslation(-.01f, 0, 0);
if (keyboardState.IsKeyDown(Keys.Right))
worldTranslation *= Matrix.CreateTranslation(.01f, 0, 0);
if (keyboardState.IsKeyDown(Keys.Up))
worldTranslation *= Matrix.CreateTranslation(0, .01f, 0);
if (keyboardState.IsKeyDown(Keys.Down))
worldTranslation *= Matrix.CreateTranslation(0, -.01f, 0);
//Rotation
worldRotation *= Matrix.CreateFromYawPitchRoll(
MathHelper.PiOver4 / 60,
0,
0);
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);
GraphicsDevice.SetVertexBuffer(vertexBuffer);
//Set object and camera info
effect.World = worldRotation * worldTranslation * worldRotation;
effect.View = camera.view;
effect.Projection = camera.projection;
effect.VertexColorEnabled = true;
//Begin effect and draw for pass
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
GraphicsDevice.DrawUserPrimitives<VertexPositionColor>
(PrimitiveType.TriangleList, verts, 0, (verts.Length/3));
}
base.Draw(gameTime);
}
}
}
它指向的代码部分是:
GraphicsDevice.DrawUserPrimitives<VertexPositionColor>
(PrimitiveType.TriangleList, verts, 0, (verts.Length/3));
有没有人看到导致此问题的原因?
答案 0 :(得分:7)
verts
为null,因为永远不会分配变量。您的LoadContent()
方法会在其范围内创建verts
,忽略作为您班级成员的那个。
答案 1 :(得分:1)
这是这类问题的一般答案。
在调试器中运行您的代码。当它由于未处理的空引用而停止时,将鼠标悬停在它停止的代码行中的每个项目上。应该说,“null”表示null。如果您的工具提示不起作用,请单击每个项目并使用QuickWatch(Shift + F9)显示该值。
答案 2 :(得分:0)
verts可能为null?通过在那里设置断点并检查自己来检查调试器。
答案 3 :(得分:0)
我可以假设访问verts.Length
verts
时为空。但是为什么你不能添加Debug.WriteLine()
输出来查看究竟发生了什么,或者只是设置一个断点或Debugger.Break()
来电?
答案 4 :(得分:0)
我冒昧地猜测顶点为空,这是基于初始化。
答案 5 :(得分:0)
除了此处的所有帖子,请确保在VS中启用异常处理:
选中“公共语言运行时例外”复选框,很可能VS会引导您出现问题的确切行。
编辑
您可以在VS菜单中找到它:Debug-&gt;例外。
希望这有帮助。
问候。