简体   繁体   中英

Field is never assigned and will always have default value null

So I just finished up doing a class for my wandering & pursuing enemies yet once I've gone through and declared the class and done the necessary coding when I run the game I get a NullReferenceException pop up which then tells me that the field Virtual_Alien is never assigned and will always have the default value of null.

What am I doing wrong here?

main game code:

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();
    }

Virtual alien code:

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;
        }

    }



}

You declare (twice actually) a variable called virtualAlien (of type Virtual_Aliens). However, you never assign it anything (while using it all over the place.

You declaration needs to look like:

Virtual_Alien virtualAlien = new Virtual_Alien();

This is assigns it to a new instance of the Virtual_Alien class, allowing you to use it later on. If you need parameters that aren't available until later, put the instantiation at the point when all needed information is available, and add null checks around any use of the variable that could happen before the instantiating code is called.

The romaingAlien member appears to have a similar problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM