对象引用未设置为对象

时间:2013-12-10 11:59:19

标签: c# object reference xna null

我试图在我的子弹和敌人之间制造碰撞。我为每个创建了边框,并将它们放入自己的类中。但是,我在HandleCollision函数中得到Null引用错误,特别是在带有边界框的if语句中。我还会发布我的其余代码。

我和两位讲师和一些同伴讨论过这个问题,因为子弹和敌人等于零。这是因为敌人需要几秒钟的时间才能产生,子弹只有在被射击后才会产生。为了解决这个问题,我添加了一个if语句来检查子弹或敌人是否为空但它仍然会引发相同的错误。

HandleCollision功能

private void HandleCollision()//collision
{   
    Sprite toRemove = null;

    if (bullet != null || enemyTexture != null)
    {
       foreach (EnemySprite e in enemyList) //checks each enemy sprite
       {
          if (bullet.BoundingBox.Intersects(enemy.BoundingBox))
          {
             enemyList.Remove(enemy); //removes enemy
             //toRemove = enemy;
             break;
          }
       }
    }
}

Game1.cs

public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    Rectangle spriteRectangle;
    Rectangle bulletBounds;
    Rectangle enemyBounds;

    Sprite player;
    Bullets bullet;
    EnemySprite enemy;

    Texture2D  enemyTexture;

    List<EnemySprite> enemyList = new List<EnemySprite>();
    List<Bullets> bulletsList = new List<Bullets>();

    //Pause
    bool paused = false;
    Texture2D pauseTexture;
    Rectangle pauseRectangle;

    KeyboardState pastKey;

    Vector2 enemyPos = new Vector2(100, 400);
    Vector2 Position;
    Vector2 Distance;
    Vector2 spriteOrigin;
    Vector2 spriteVelocity;

    const float tangentialVelocity = 5f;
    float friction = 0.1f;       
    float rotation;     
    float timer = 0f;
    float dropInterval = 2f;
    float speed = 4f;
    float angle;
    Random random;

    enum GameState
    { 
        MainMenu,
        Options,
        Help,
        Playing,
        Exit,
    }
    GameState CurrentGameState = GameState.MainMenu;

    // Screen adjustments
    int screenWidth = 800, screenHeight = 600;

    cButton btnPlay;
    cButtonExit btnExit;

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
    }

    protected override void Initialize()
    {
        // TODO: Add your initialization logic here
        random = new Random();
        Position = new Vector2(150, 150);
        this.IsMouseVisible = true;
        base.Initialize();
    }

    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);

        player = new Sprite();
        player.Texture = Content.Load<Texture2D>("graphics/player");

       // Screen stuff
        graphics.PreferredBackBufferWidth = screenWidth;
        graphics.PreferredBackBufferHeight = screenHeight;
        //graphics.IsFullScreen = true;
        graphics.ApplyChanges();
        IsMouseVisible = true;

        btnPlay = new cButton(Content.Load<Texture2D>("Graphics/play"), graphics.GraphicsDevice);
        btnPlay.setPosition(new Vector2(350, 190));

        btnExit = new cButtonExit(Content.Load <Texture2D>("Graphics/exit"), graphics.GraphicsDevice);
        btnExit.setPosition(new Vector2(350, 220));

        enemyTexture = Content.Load<Texture2D>("graphics/enemy");

        player.Texture = Content.Load<Texture2D>("Graphics/player");
        int screenCenterX = GraphicsDevice.Viewport.Width / 2;
        player.Position = new Vector2(screenCenterX - (player.Texture.Width / 2), screenHeight - player.Texture.Height - 20);

        pauseTexture = Content.Load<Texture2D>("graphics/paused");
        pauseRectangle = new Rectangle(0, 0, pauseTexture.Width, pauseTexture.Height);

        Bullets.BulletTexture = Content.Load<Texture2D>("graphics/bullet");  
    }

    protected override void Update(GameTime gameTime)
    {
        MouseState mouse = Mouse.GetState();
        IsMouseVisible = true;

        switch (CurrentGameState)
        { 
            case GameState.MainMenu:
                if (btnPlay.isClicked == true) CurrentGameState = GameState.Playing;
                btnPlay.Update(mouse);

                if (btnExit.isClicked == true) CurrentGameState = GameState.Help;
                btnExit.Update(mouse);

                if (btnExit.isClicked == true) CurrentGameState = GameState.Options;
                btnExit.Update(mouse);

                if (btnExit.isClicked == true) CurrentGameState = GameState.Exit;
                btnExit.Update(mouse);
                break;

            case GameState.Playing:
                timer += (float)gameTime.ElapsedGameTime.TotalSeconds;

                if (timer >= dropInterval)
                {
                    int yPos = random.Next(GraphicsDevice.Viewport.Height - 50);
                    enemyList.Add(new EnemySprite(enemyTexture, new Vector2(GraphicsDevice.Viewport.Width + 100, yPos)));
                    timer = 0f;
                }

                HandleCollision();
                HandleMovingEnemy();

                MouseState curMouse = Mouse.GetState();
                Vector2 mouseLoc = new Vector2(curMouse.X, curMouse.Y);
                Vector2 direction = mouseLoc - Position;
                spriteRectangle = new Rectangle((int)Position.X, (int)Position.Y,
                    player.Texture.Width, player.Texture.Height);
                Position = spriteVelocity + Position;

                spriteOrigin = new Vector2(spriteRectangle.Width / 2, spriteRectangle.Height / 2);

                Distance.X = mouse.X - Position.X;
                Distance.Y = mouse.Y - Position.Y;

                rotation = (float)Math.Atan2(Distance.Y, Distance.X); //calculates the rotation(trigonometry)

                //angle = (float)(Math.Atan2(direction.Y, direction.X));

                KeyboardState keyState = Keyboard.GetState();
                if (keyState.IsKeyDown(Keys.A))
                    Position.X -= 2;
                if (keyState.IsKeyDown(Keys.D))
                    Position.X += 2;
                if (keyState.IsKeyDown(Keys.W))
                    Position.Y -= 2;
                if (keyState.IsKeyDown(Keys.S))
                    Position.Y += 2;

                //right and left edge detection
                if (Position.X < 0)
                    Position = new Vector2(0, Position.Y);
                int rightEdge = GraphicsDevice.Viewport.Width - player.Texture.Width;
                if (Position.X > rightEdge)
                    Position = new Vector2(rightEdge, Position.Y);

                //bottom and top edge detection
                if (Position.Y < 0)
                    Position = new Vector2(Position.X, 0);
                int bottomEdge = GraphicsDevice.Viewport.Height - player.Texture.Height;
                if (Position.Y > bottomEdge)
                    Position = new Vector2(Position.X, bottomEdge);

                if (!paused)
                {
                    if (Keyboard.GetState().IsKeyDown(Keys.Escape))
                    {
                        paused = true;
                        btnPlay.isClicked = false; //so that everytime its paused I can pause it again
                    }

                    enemy.Update();

                }
                else if(paused)
                {
                    if (btnPlay.isClicked)
                    {
                        paused = false;
                        speed = 4;
                    }
                    if (btnExit.isClicked)
                        Exit();

                    btnPlay.Update(mouse);
                    btnExit.Update(mouse);

                }

                if (Keyboard.GetState().IsKeyDown(Keys.C))
                {
                    spriteVelocity.X = (float)Math.Cos(rotation) * tangentialVelocity;
                    spriteVelocity.Y = (float)Math.Sin(rotation) * tangentialVelocity;
                }
                else if (spriteVelocity != Vector2.Zero)
                {
                    float i = spriteVelocity.X;
                    float j = spriteVelocity.Y;

                    spriteVelocity.X = i -= friction * i;
                    spriteVelocity.Y = j -= friction * j;
                }

                if (Keyboard.GetState().IsKeyDown(Keys.Space) && pastKey.IsKeyUp(Keys.Space))
                    Fire();

                pastKey = Keyboard.GetState();
                UpdateBullets();
                break;

            case GameState.Exit:
                this.Exit();
                break;
        }

        base.Update(gameTime);
    }

    public void UpdateBullets()
    {
        foreach (Bullets bullet in bulletsList) 
        {
            bullet.position += bullet.velocity;
            if(Vector2.Distance(bullet.position, Position) > 500) //finds position
                bullet.isVisible = false;
        }
        for (int i = 0; i < bulletsList.Count; i++)
        {
            if (!bulletsList[i].isVisible)
            {
                bulletsList.RemoveAt(i);
                i--;
            }
        }
    }

    //function to handle movement of enemies
    private void HandleMovingEnemy()
    {
        List<EnemySprite> toRemove = new List<EnemySprite>();

        foreach (EnemySprite e in enemyList)
        {
            if (e.Position.X < (-20))
            {
                toRemove.Add(e);
            }
            else
                e.Position -= new Vector2(speed, 0);
        }

        if (toRemove.Count > 0)
        {
            foreach (EnemySprite e in toRemove)
            {
                enemyList.Remove(e);
            }
        }
    }

    private void HandleCollision()//collision
    {            
        Sprite toRemove = null;

        if (bullet != null || enemyTexture != null)
        {
            foreach (EnemySprite e in enemyList) //checks each enemy sprite
            {
                if (bullet.BoundingBox.Intersects(enemy.BoundingBox)) //checks if a sprite has intersected an enemy
                {
                    enemyList.Remove(enemy); //removes enemy
                    //toRemove = enemy;
                    break;
                }
            }
        }
    }

    public void Fire()
    {
        Bullets newBullet = new Bullets(Content.Load<Texture2D>("graphics/bullet"));
        Bullets.BulletTexture = Content.Load<Texture2D>("graphics/bullet");
        //newBullet.LoadContent(LoadContent);

        newBullet.velocity = new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * 5f + spriteVelocity;
        newBullet.position = Position + newBullet.velocity * 5;
        newBullet.isVisible = true;

        if (bulletsList.Count() < 20)
            bulletsList.Add(newBullet);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        spriteBatch.Begin();
        switch (CurrentGameState)
        {
            case GameState.MainMenu:
                spriteBatch.Draw(Content.Load<Texture2D>("Graphics/SeaSideDefenderMainMenu"), new Rectangle(0,0,screenWidth,screenHeight),Color.White);
                btnPlay.Draw(spriteBatch);
                btnExit.Draw(spriteBatch);
                break;

            case GameState.Playing:
                spriteBatch.Draw(Content.Load<Texture2D>("Graphics/leveltest"), new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
                enemy = new EnemySprite();
                enemy.Texture = Content.Load<Texture2D>("graphics/enemy");
                enemy.Draw(spriteBatch);
                spriteBatch.Draw(player.Texture, Position, null, Color.White, rotation, spriteOrigin, 1f, SpriteEffects.None, 0);
                //player.Draw(spriteBatch); 

                foreach (EnemySprite e in enemyList)
                {
                    e.Draw(spriteBatch);
                }

                foreach (Bullets bullet in bulletsList)
                    bullet.draw(spriteBatch);

                /*for (int i; i < enemyList.Count; i++)
                {
                    enemyList[i].Draw(spriteBatch);
                }*/

                if (paused)
                {
                    speed = 0;
                    spriteBatch.Draw(Content.Load<Texture2D>("graphics/paused"), new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
                    btnPlay.Draw(spriteBatch);
                    btnExit.Draw(spriteBatch);

                }
                break;
        }
        spriteBatch.End();

        base.Draw(gameTime);
    }
}

Bullets.cs

public class Bullets
{
    public Texture2D texture;
    public static Texture2D BulletTexture;
    public Vector2 position;
    public Vector2 velocity;
    public Vector2 origin;
    public bool isVisible;

    public Rectangle BoundingBox
    {
        get { return new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height); }
    }

    public Bullets(Texture2D newTexture)
    {
        texture = newTexture;
        isVisible = false;
    }

    public void draw(SpriteBatch spriteBatch)
    {            
        spriteBatch.Draw(texture,position,null,Color.White,0f,origin,1f, SpriteEffects.None, 0);     
    }

    public void LoadContent(ContentManager Content)
    {
        BulletTexture = Content.Load<Texture2D>(@"graphics/bullet");
    }       
}

enemy.cs

public class EnemySprite
{
    public Texture2D Texture { get; set; }
    public Vector2 Position {get; set; }
    public Vector2 origin;
    public Vector2 velocity;
    public Rectangle rectangle;        
    float rotation = 0f;
    bool right;
    float distance;
    float oldDistance;

    public Rectangle BoundingBox
    {
        get { return new Rectangle((int)Position.X, (int)Position.Y, Texture.Width, Texture.Height); } //uses enemy position and wiwdth to create bounding box
    }

    public EnemySprite() { }

    public EnemySprite(Texture2D texture, Vector2 position)
    {
        Texture = texture;
        Position = position;
        oldDistance = distance;
    }

    float mouseDistance;
    public void Update()
    {
        Position += velocity;
        origin = new Vector2(Texture.Width / 2, Texture.Height / 2);

        if (distance <= 0)
        {
            right = true;
            velocity.X = 1f;
        }
        else if(distance <= oldDistance)
        {
            right = false;
            velocity.X = -1f;
        }

        if (right) distance += 1; else distance -= 1;

        MouseState mouse = Mouse.GetState();
        mouseDistance = mouse.X - Position.X;

        if (mouseDistance >= -200 && mouseDistance <= 200)
        {
            if (mouseDistance < -1)
                velocity.X = -1f;
            else if (mouseDistance > 1)
                velocity.X = 1f;
            else if (mouseDistance == 0)
                velocity.X = 0f;
        }
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        if (Texture != null)
            spriteBatch.Draw(Texture, Position, Color.White);

        if (velocity.X > 0)
        {           
            spriteBatch.Draw(Texture, Position, null, Color.White, rotation, origin, 1f, SpriteEffects.FlipHorizontally, 0f);              
        }
        else
        {                
            spriteBatch.Draw(Texture, Position, null, Color.White, rotation, origin, 1f, SpriteEffects.None, 0f);                
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您尚未在game1.cs中的任何位置初始化全局变量Bullet,因此您永远不会将bullet != null视为真。然而,由于您已经在LoadContent()中初始化了enemyTexture != null,因此您始终会enemyTexture为真。 这意味着,在if变量未初始化的情况下,您始终会输入Bullet块。

希望这会引导您找到解决方案。

PS:如果这是最有帮助的,请将答案标记为“已接受”。