字段从不被分配,并且将始终具有默认值null

本文关键字:null 默认值 分配 字段 | 更新日期: 2023-09-27 17:58:54

所以我刚刚完成了一节课,用于我的漫游&追求敌人,但一旦我通过并声明了类,并在运行游戏时进行了必要的编码,我会弹出一个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;
        }
    }

}

字段从不被分配,并且将始终具有默认值null

您声明(实际上两次)一个名为virtualAlien的变量(类型为Virtual_Aliens)。然而,你永远不会给它分配任何东西(同时到处使用它。

您的声明需要看起来像:

Virtual_Alien virtualAlien = new Virtual_Alien();

这是将它分配给Virtual_Alien类的一个新实例,允许您稍后使用它。如果您需要稍后才可用的参数,请将实例化放在所有所需信息都可用的位置,并在调用实例化代码之前对变量的任何使用添加空检查。

romaingAlien成员似乎也有类似的问题。