所以我有一个HealthPickup类和一个Player类。每个类都有这行代码:
public static Rectangle Hitbox = new Rectangle(Pos.X, Pos.Y, Tex.Width, Tex.Height);
我的问题是,为什么Player类而不是HealthPickup类有错误?编辑:如果我跨过播放器命中框,HealthPickup会导致相同的错误。这是否与我的矩形有关?错误是TypeInitializationException,详细信息如下:
System.TypeInitializationException was unhandled
HResult=-2146233036
Message=The type initializer for 'TestGame.Player' threw an exception.
Source=TestGame
TypeName=TestGame.Player
StackTrace:
at TestGame.RPG.LoadContent() in C:\Users\Pyroglyph\Documents\Visual Studio 2010\Projects\TestGame\TestGame\TestGame\RPG.cs:line 41
at Microsoft.Xna.Framework.Game.Initialize()
at TestGame.RPG.Initialize() in C:\Users\Pyroglyph\Documents\Visual Studio 2010\Projects\TestGame\TestGame\TestGame\RPG.cs:line 33
at Microsoft.Xna.Framework.Game.RunGame(Boolean useBlockingRun)
at Microsoft.Xna.Framework.Game.Run()
at TestGame.Program.Main(String[] args) in C:\Users\Pyroglyph\Documents\Visual Studio 2010\Projects\TestGame\TestGame\TestGame\Program.cs:line 15
InnerException: System.NullReferenceException
HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=TestGame
StackTrace:
at TestGame.Player..cctor() in C:\Users\Pyroglyph\Documents\Visual Studio 2010\Projects\TestGame\TestGame\TestGame\Player.cs:line 20
InnerException:
编辑:我停止了错误,但我仍然需要碰撞检测,我正在使用Console.Beep()来确定代码是否运行。并且,根据要求,更多代码:)
public class HealthPickup : Microsoft.Xna.Framework.GameComponent
{
public static Texture2D Tex;
public static Point Pos = new Point(50, 50);
public static Rectangle Hitbox = new Rectangle(Pos.X, Pos.Y, 32, 32);
public HealthPickup(Game game) : base(game) { }
public override void Initialize() { base.Initialize(); }
public override void Update(GameTime gameTime)
{
//if (Tex.Bounds.Intersects(Player.Tex.Bounds)) //was testing other collision-detection methods
//{
// Console.Beep(); //the only way I can check if it's being run or not
//}
}
}
在Draw()中:
GraphicsDevice.Clear(Color.White);
spriteBatch.Begin();
// Create Useless Rectangles
Rectangle player = new Rectangle(Player.Pos.X, Player.Pos.Y, Player.Tex.Width, Player.Tex.Height);
Rectangle healthPickup = new Rectangle(HealthPickup.Pos.X, HealthPickup.Pos.Y, HealthPickup.Tex.Width, HealthPickup.Tex.Height);
// Draw Sprites
spriteBatch.Draw(Player.Tex, player, Color.White);
spriteBatch.Draw(HealthPickup.Tex, healthPickup, Color.White);
spriteBatch.End();
base.Draw(gameTime);
玩家类:
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 TestGame
{
public class Player : Microsoft.Xna.Framework.GameComponent
{
public static Texture2D Tex;
public static string Dir = "D";
public static Point Pos = new Point(GraphicsDeviceManager.DefaultBackBufferWidth / 2, GraphicsDeviceManager.DefaultBackBufferHeight / 2);
public static int speed = 4;
public static Rectangle Hitbox = new Rectangle(Pos.X, Pos.Y, Tex.Width, Tex.Height);
public Player(Game game): base(game) { }
public override void Initialize() { base.Initialize(); }
public override void Update(GameTime gameTime) { }
}
}
答案 0 :(得分:1)
每当静态构造函数抛出异常时抛出此异常,在这种情况下,您似乎在Player
类的静态构造函数中有NullReferenceException。
修改强>
这里的问题是Tex
静态字段,它在创建HitBox
之前未初始化,这解释了您获得的NullReferenceExcpetion的原因。所以为了解决问题,你必须初始化它,你可以在Player类中这样做:
public static Rectangle HitBox;
//other fields and methods
public override void LoadContent(){
ContentManager content = MyGame.ContentManager;
Tex = content.Load<Texture2D>("mytexture");
//...
base.LoadContent();
this.InitializeAfterLoadingContent();
}
private void InitializeAfterLoadingContent(){
Hitbox = new Rectangle(Pos.X, Pos.Y, Tex.Width, Tex.Height);
}
正如您所看到的,我创建了另一种方法,导致在初始化图形资源时出现问题。在XNA中,Initialize
方法在LoadContent
之前被调用,因此您需要克服此问题的方法是创建一个方法并在加载内容后调用它。您的Game类也可以完成:
public class MyGame : Microsoft.Xna.Framework.Game {
public static ContentManager ContentManager;
//...
public MyGame( ) {
//...
ContentManager = Content;
}
protected override void Initialize(){
// TODO: Add your initialization logic here
base.Initialize();
}
protected override void LoadContent() {
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
//...
this.InitializeAfterLoadingContent();
}
//you can call it however you want
private void InitializeAfterLoadingContent(){
//initialize your non-graphical resources by using the content info you need,
//like the width and height of a texture you loaded
}
//...
}