所以我刚刚完成了为我的徘徊&追求敌人但是当我经历并宣布课程并在我运行游戏时完成必要的编码后,我会弹出一个NullReferenceException,然后告诉我,Virtual_Alien字段从未被分配,并且将始终具有默认值null。
我在这里做错了什么?
主要游戏代码:
private Roaming_Aliens roamingAlien;
private Virtual_Aliens virtualAlien;
public Vector2 playerPosition;
public Player mainPlayer = new Player();
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
mainPlayer.position = playerPostion;
// now assign that image to each of the characters we have
roamingAlien.LoadContent(Content);
virtualAlien.LoadContent(Content);
mainPlayer.LoadContent(Content);
score.LoadContent(Content);
// mainBackground.LoadContent(Content);
}
protected override void Update(GameTime gameTime)
{
currentKey = Keyboard.GetState();
if (currentKey.IsKeyDown(Keys.Escape))
{
this.Exit();
}
mainPlayer.Update(gameTime);
score.Update(gameTime);
virtualAlien.Update(gameTime);
roamingAlien.Wander();
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
//mainBackground.Draw(spriteBatch);
mainPlayer.Draw(spriteBatch);
virtualAlien.Draw(spriteBatch);
roamingAlien.Draw(spriteBatch);
spriteBatch.End();
}
虚拟外星人代码:
public class Virtual_Aliens
{
private enum TankAiState
{
Chasing,
Wander
}
private float maxSpeed;
private float maxRotation;
private float chaseDistance;
private float hysteresis;
private Texture2D texture;
private Vector2 drawingOrigin;
private Vector2 position;
private TankAiState tankState = TankAiState.Wander;
private float orientation;
private Random random = new Random();
private Rectangle viewportbounds;
public Rectangle boundingBox;
public Vector2 playerPosition;
private Vector2 heading;
public Virtual_Aliens(Rectangle pos, Rectangle b)
{
position = new Vector2 (100, 100);
boundingBox = new Rectangle(pos.X, pos.Y, pos.Width, pos.Height);
viewportbounds = new Rectangle(b.X, b.Y, b.Width, b.Height);
orientation = 0.0f;
heading = new Vector2(0, 0);
maxSpeed = 2.0f;
maxRotation = 0.20f;
random = new Random();
hysteresis = 15.0f;
chaseDistance = 250.0f;
}
public void LoadContent(ContentManager Content)
{
texture = Content.Load<Texture2D>("images/asteroid");
}
private Vector2 OrientationAsVector(float orien)
{
Vector2 orienAsVect;
orienAsVect.X = (float)Math.Cos(orien);
orienAsVect.Y = (float)Math.Sin(orien);
return orienAsVect;
}
Vector2 wanderPosition = new Vector2();
public void Wander()
{
// The wander effect is accomplished by having the character aim in a random
// direction. Every frame, this random direction is slightly modified.
// the max +/- the agent will wander from its current position
float wanderLimits = 0.5f;
// this defines what proportion of its maxRotation speed the agent will turn
float turnFactor = 0.15f;
// randomly define a new position
wanderPosition.X += MathHelper.Lerp(-wanderLimits, wanderLimits, (float)random.NextDouble());
wanderPosition.Y += MathHelper.Lerp(-wanderLimits, wanderLimits, (float)random.NextDouble());
// normalize the wander position, ...
if (wanderPosition != Vector2.Zero)
wanderPosition.Normalize();
// now find the new orientation based on the wanderPosition
orientation = TurnToFace(wanderPosition, orientation, turnFactor * maxRotation);
// determine the heading vector based on orientation
heading = OrientationAsVector(orientation);
// finally update the agents position based upon the new heading and its speed
// assume a wandering agent only moves at 0.5 of maxSpeed
position += heading * 0.5f * maxSpeed;
WrapForViewport();
}
private void WrapForViewport()
{
if (position.X < 0)
{
position.X = viewportbounds.Width;
}
else if (position.X > viewportbounds.Width)
{
position.X = 0;
}
if (position.Y < 0)
{
position.Y = viewportbounds.Height;
}
else if (position.Y > viewportbounds.Height)
{
position.Y = 0;
}
}
private float WrapAngle(float radian)
{
while (radian < -MathHelper.Pi)
{
radian += MathHelper.TwoPi;
}
while (radian > MathHelper.Pi)
{
radian -= MathHelper.TwoPi;
}
return radian;
}
private float TurnToFace(Vector2 steering, float currentOrientation, float turnSpeed)
{
float newOrientation;
float desiredOrientation;
float orientationDifference;
float x = steering.X;
float y = steering.Y;
// the desiredOrientation is given by the steering vector
desiredOrientation = (float)Math.Atan2(y, x);
// find the difference between the orientation we need to be
// and our current Orientation
orientationDifference = desiredOrientation - currentOrientation;
// now using WrapAngle to get result from -Pi to Pi
// ( -180 degrees to 180 degrees )
orientationDifference = WrapAngle(orientationDifference);
// clamp that between -turnSpeed and turnSpeed.
orientationDifference = MathHelper.Clamp(orientationDifference, -turnSpeed, turnSpeed);
// the closest we can get to our target is currentAngle + orientationDifference.
// return that, using WrapAngle again.
newOrientation = WrapAngle(currentOrientation + orientationDifference);
return newOrientation;
}
public void Update(GameTime gameTime)
{
if (tankState == TankAiState.Wander)
{
chaseDistance -= hysteresis / 2;
}
else if (tankState == TankAiState.Chasing)
{
chaseDistance += hysteresis / 2;
}
// Second, now that we know what the thresholds are, we compare the tank's
// distance from the cat against the thresholds to decide what the tank's
// current state is.
float distanceFromPlayer = Vector2.Distance(position, playerPosition);
if (distanceFromPlayer > chaseDistance)
{
// just like the mouse, if the tank is far away from the cat, it should
// idle.
tankState = TankAiState.Wander;
}
else
{
tankState = TankAiState.Chasing;
}
// Third, once we know what state we're in, act on that state.
float currentTankSpeed;
if (tankState == TankAiState.Chasing)
{
// the tank wants to chase the cat, so it will just use the TurnToFace
// function to turn towards the cat's position. Then, when the tank
// moves forward, he will chase the cat.
orientation = TurnToFace(playerPosition, orientation, maxRotation);
currentTankSpeed = maxSpeed;
}
else if (tankState == TankAiState.Wander)
{
Wander();
}
}
public void Draw(SpriteBatch spriteBatch)
{
drawingOrigin = new Vector2(texture.Width / 2, texture.Height / 2);
spriteBatch.Draw(texture, position, null, Color.White, orientation, drawingOrigin, 1.0f, SpriteEffects.None, 0.0f);
}
public Vector2 PlayerPosition
{
set
{
playerPosition = value;
}
get
{
return playerPosition;
}
}
}
答案 0 :(得分:2)
你声明(实际上是两次)一个名为virtualAlien的变量(类型为Virtual_Aliens)。但是,你永远不会给它任何东西(当它在整个地方使用它时。
您的声明需要如下:
Virtual_Alien virtualAlien = new Virtual_Alien();
这将它分配给Virtual_Alien类的新实例,允许您稍后使用它。如果需要以后才能使用的参数,请将实例化放在所有需要的信息可用的时刻,并在调用实例化代码之前对可能发生的变量的使用添加空检查。
romaingAlien成员似乎也有类似的问题。