繁体   English   中英

如何调试类中意外的空值来自何处?

[英]How to debug where an unexpected null is coming from in my class?

在我的Boss班上,它说我的列表“ bulletlist”为空,并给我一个运行时错误,但是我看不到有人可以告诉我我做错了什么错误? 如果我不更新老板课程,则游戏运行良好。 我也加入了主班,球员班和子弹班。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 Space_Shooter
{
    public class Boss
    {
        public Texture2D texture, bulletTexture , healthBarTexture;
        public Vector2 position;
        public float randomPositionX, randomPositionY , bulletDamage, shipDamage , health , MaxBullets;
        public int speed, bulletSpeed , bulletDelayTime, bulletDelayTimeReset;
        public bool isVisible;
        public Rectangle boundingBox , bossHealthBar;
        public List<Bullet> bulletList;
        Random random = new Random();
        Player p = new Player();


        public Boss(Texture2D newTexture, Vector2 newPosition, Texture2D newBulletTexture)
        {
            texture = newTexture;
            position = newPosition;
            bulletTexture = newBulletTexture;
            bulletList = new List<Bullet>();
            bulletSpeed = 25;
            bulletDamage = 25;
            shipDamage = p.health / 2;
            health = 2000;
            bulletDelayTime = 30;
            bulletDelayTimeReset = 30;
            MaxBullets = 30;
            isVisible = true;

        }
        public Boss()
        {

        }

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(texture, position, Color.White);
            spriteBatch.Draw(healthBarTexture, bossHealthBar, Color.White);

            foreach (Bullet b in bulletList)
            {
                b.Draw(spriteBatch);
            }

        }

        public void loadContent(ContentManager content)
        {
            texture = content.Load<Texture2D>("Ship4");
            bulletTexture = content.Load<Texture2D>("EnemyBullet");
            healthBarTexture = content.Load <Texture2D> ("healthbar");

        }
        public void update(GameTime gameTime)
        {
            updateBullets();
            Shoot();
            checkBossCollison();

            // Making bosses health bar
            bossHealthBar = new Rectangle((int)position.X, (int)position.Y + 30, (int)health, 25);

            // Creating collision box for boss
            boundingBox = new Rectangle((int)position.X, (int)position.Y, (int)texture.Width, (int)texture.Height);

            randomPositionX = random.Next(50, 750);
            randomPositionY = random.Next(50, 400);

            // setting boss movement
            if (position.Y > randomPositionY)
                position.Y -= speed;

            if (position.Y < randomPositionY)
                position.Y += speed;

            if (position.X > randomPositionX)
                position.X -= speed;

            if (position.X < randomPositionX)
                position.X += speed;
        }
        public void updateBullets()
        {
            // for each bullet in the bulletList: update the movement and if the bullet hits the bottom of the screen, remove it from the list
            foreach (Bullet b in bulletList)
            {
                //make a Bounding box for every bullet in the bulletList
                b.boundingBox = new Rectangle((int)b.position.X, (int)b.position.Y, b.texture.Width, b.texture.Height);

                // set movement for the bullets

                // if a bullet hits the bottom of the screen, then make visable false
                if (b.position.Y >= 850)
                    b.isVisible = false;

                // go through the bulletList and see if any of the bullets are not visible, if they are not then remove that bullet from the bulletList
                for (int i = 0; i < bulletList.Count; i++)
                {
                    if (!bulletList[i].isVisible)
                    {
                        bulletList.RemoveAt(i);
                        i--;
                    }
                }
            }
        }

        public void checkBossCollison()
        {
            // if boss ship comes in bcontact with player ship player is damaged
            if (boundingBox.Intersects(p.boundingBox))
                p.health -= shipDamage;

            // if player bullets hit boss then boss is damaged and player bullets go invisible
            for(int i = 0; i < p.bulletList.Count; i++)
            {
                if (boundingBox.Intersects(p.bulletList[i].boundingBox))
                {
                    health -= p.bulletDamage;
                    p.bulletList[i].isVisible = false;

                    if (health == 0)
                        isVisible = false;
                }
            }

            // if boss shoots player player is damaged and boss bullets go invisible
            for(int i = 0; i < bulletList.Count; i++)
            {
                if (p.boundingBox.Intersects(bulletList[i].boundingBox))
                {
                    p.health -= bulletDamage;
                    bulletList[i].isVisible = false;

                }
            }
        }

        public void Shoot()
        {
            // shoot only if our bullet delay resets
            if (bulletDelayTime >= 0)
                bulletDelayTime--;

            // If bulletDelay is at 0, create a new bullet at enemy position, make it visible on the screen, then add that bullet to bulletList
            if (bulletDelayTime <= 0)
            {
                // create new bullet and center it front and center of enemy ship
                Bullet newBullet = new Bullet(bulletTexture);
                newBullet.position = new Vector2(position.X + texture.Width / 2 - newBullet.texture.Width / 2, position.Y + 30);

                newBullet.isVisible = true;

                if (bulletList.Count() < MaxBullets)
                    bulletList.Add(newBullet);
            }

            // Reset bullet delay
            if (bulletDelayTime == 0)
                bulletDelayTime = bulletDelayTimeReset;
        }
    }
}







    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 Space_Shooter
{

    // Main
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;

        // variabls
        SpriteBatch spriteBatch;
        Random random = new Random();
        Random randomNumberOfAsteroids = new Random();
        int maxNumberOfAsteroids;
        int numbersOfInvisibleEnemies;



        // Lists
        List<Asteroid> asteroidList = new List<Asteroid>();
        List<Enemy> enemyList = new List<Enemy>();

        // making player and starfield objects
        Player P = new Player();
        StarField starfield = new StarField();
        Enemy E = new Enemy();
        Boss boss = new Boss();

        // Construtor
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);

            // setting full scren to off and setting screen measurments
            graphics.IsFullScreen = false;
            graphics.PreferredBackBufferWidth = 800;
            graphics.PreferredBackBufferHeight = 850;
            maxNumberOfAsteroids = 5;  // Set the max number of asteroids that will be on the screen at one time ( randomly 0 to Max number)
            numbersOfInvisibleEnemies = 0;

            // Setting Title of screen 
            this.Window.Title = "Star Voyage";

            Content.RootDirectory = "Content";
        }

        // Initialize
        protected override void Initialize()
        {
            base.Initialize();
        }

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

            // Call Load content function from Player.cs
            P.LoadContent(Content);
            starfield.LoadContent(Content);
            boss.loadContent(Content);


        }

        // unload content
        protected override void UnloadContent()
        {

        }

        // update game screen
        protected override void Update(GameTime gameTime)
        {

            // updating enemies and checking collision of thier ships to player ship
            foreach (Enemy e in enemyList)
            {
                if (e.boundingBox.Intersects(P.boundingBox))
                {
                    P.health -= e.enemyShipDamage;
                    e.isVisible = false;
                }

                // check enemy bullet collision with player ship
                for (int i = 0; i < e.bulletList.Count; i++)
                {
                    if (P.boundingBox.Intersects(e.bulletList[i].boundingBox))
                    {
                        P.health -= e.enemyBulletDamage;
                        e.bulletList[i].isVisible = false;
                    }
                }

                // check player bullet collision with enemy ships
                for (int i = 0; i < P.bulletList.Count; i++)
                {
                    if (e.boundingBox.Intersects(P.bulletList[i].boundingBox))
                    {
                        // when bullet hits enemy ship they disapear
                        P.bulletList[i].isVisible = false;
                        e.health -= P.bulletDamage;

                        if (e.health == 0)
                            e.isVisible = false;

                    }
                }
                e.Update(gameTime);
            }
            // for each asteroid in the asteroid list call the update function from Asteroid.cs
            foreach (Asteroid a in asteroidList)
            {
                //Check to see if any of the arteroids are colliding with player ship
                if (a.boundingBox.Intersects(P.boundingBox))
                {
                    P.health -= a.asteroidDamage;  // taking 20 off of player health bar each time the play shit is hit by an asteroid
                    a.isVisible = false;
                }
                // going through bullet list to see if any bullets come in contact with asteroids if they do set both the bullet and the asteroid to not visible
                for (int i = 0; i < P.bulletList.Count; i++)
                {
                    if (a.boundingBox.Intersects(P.bulletList[i].boundingBox))
                    {
                        a.isVisible = false;
                        P.bulletList.ElementAt(i).isVisible = false;
                    }
                }
                a.Update(gameTime);
            }

            loadAsteroids();
            loadEnemyShips();
            // Call fucntion Update from Player,cs
            P.Update(gameTime);
            // Call function update from StarField.cs
            starfield.Update(gameTime);
            boss.update(gameTime);
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            base.Update(gameTime);
        }

        // Draw to game screen
        protected override void Draw(GameTime gameTime)
        {
            spriteBatch.Begin();

            starfield.Draw(spriteBatch);

            foreach (Asteroid a in asteroidList)
            {
                a.Draw(spriteBatch);
            }

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

            // Backgound color
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // Call Draw fuction from Player.cs
            P.Draw(spriteBatch);
          //  boss.Draw(spriteBatch);
            spriteBatch.End();
            base.Draw(gameTime);
        }

        // Load Asteroids function
        public void loadAsteroids()
        {
            // creating random variabls for X and Y positions of asteroids
            int random_x = random.Next(0, 750), random_y = random.Next(-600, -50);

            // if the number of Asteroids on the screen is less than the variable (numberOfAsteroids), create more untill it is not
            if (asteroidList.Count() < randomNumberOfAsteroids.Next(0, maxNumberOfAsteroids))
            {
                asteroidList.Add(new Asteroid(Content.Load<Texture2D>("asteroid"), new Vector2(random_x, random_y)));
            }

            // if any of the asteroids from the list are destroyed (not visible) then remove them from the list
            for (int i = 0; i < asteroidList.Count; i++)
            {
                if (!asteroidList[i].isVisible)
                {
                    asteroidList.RemoveAt(i);
                    i--;
                }
            }
        }

        public void loadEnemyShips()
        {
            // creating random variabls for X and Y positions of asteroids
            int random_x = random.Next(0, 750), random_y = random.Next(-600, -50);

            // if the number of enemies on the screen is less than the variable (numberOfEnemies), create more untill it is not
            if (enemyList.Count() < 3 && numbersOfInvisibleEnemies <= 9)
            {
                enemyList.Add(new Enemy(Content.Load<Texture2D>("enemyship"), new Vector2(random_x, random_y), Content.Load<Texture2D>("EnemyBullet")));
            }

            // keeping count of the number of destroied enemies
            for (int i = 0; i < enemyList.Count; i++)
            {
                if (!enemyList[i].isVisible)
                    numbersOfInvisibleEnemies += 1;

                // if any of the enemies from the list are destroyed (not visible) or if they go passed the bottom of the screen, then remove them from the list
                if (!enemyList[i].isVisible || enemyList[i].position.Y >= 840)
                {
                    enemyList.RemoveAt(i);
                    --i;
                }
            }

        }

    }
}




    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 Space_Shooter
{
    // main
    public class Player
    {   
        // Variables
        public Texture2D texture , bulletTexture , healthTexture;
        public Vector2 position , healthBarPosition;
        public int speed;
        public float health , bulletDamage , bulletDelay , bulletDelayReset;
        double bulletCount;

        // Lists
        public List<Bullet> bulletList;



        // Collision variables
        public bool isColliding;
        public Rectangle boundingBox , healthRectangle;

        // Constructor
        public Player()
        {
            bulletList = new List<Bullet>();
            bulletDelay = 1;                // for faster fire rate reduce number
            bulletDelayReset = 5;           // bullet delay reset has to be the same number as bullet delay
            bulletCount = 1000;             // amount of bullets alowed on the screen at a time
            texture = null;
            health = 200;
            bulletDamage = 3;
            healthBarPosition = new Vector2(50, 50);
            position = new Vector2 (300, 300) ;
            speed = 10;
            isColliding = false;
        }

        // Load content 
        public void LoadContent(ContentManager Content)
        {
            texture = Content.Load<Texture2D>("player01");
            bulletTexture = Content.Load<Texture2D>("playerbullet");
            healthTexture = Content.Load<Texture2D>("healthbar");
        }

        // Draw
        public void Draw(SpriteBatch spritebatch)
        {
            spritebatch.Draw(texture, position, Color.White);
            spritebatch.Draw(healthTexture, healthRectangle, Color.White);

            // For each Bullet b (bullet) in our bullet list, draw the bullet
            foreach (Bullet b in bulletList)
            {
                b.Draw(spritebatch);
            }
        }

        // Update
        public void Update(GameTime gametime)
        {
            // Checking for keyboard input every frame
            KeyboardState keystate = Keyboard.GetState();

            // setting collision box for player ship
            boundingBox = new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height);

            //set rectangle for healthbar (where to print on the screen and the height and width (25) is height (health is width
            healthRectangle = new Rectangle((int) healthBarPosition.X, (int) healthBarPosition.Y, (int)health, 25);

            if (keystate.IsKeyDown(Keys.Space))
            {
                shoot();
            }
            updateBullets();

            // ship controls
            if (keystate.IsKeyDown(Keys.W))
             position.Y = position.Y - speed;

            if (keystate.IsKeyDown(Keys.S))
            position.Y = position.Y + speed;

            if (keystate.IsKeyDown(Keys.A))
                position.X = position.X - speed;

            if (keystate.IsKeyDown(Keys.D))
                position.X = position.X + speed;


            // Keep ship in screen bounds
            if (position.X <= 0)
                position.X = 0;

            if (position.X >= 800 - texture.Width)
                position.X = 800 - texture.Width;

            if (position.Y <= 0)
                position.Y = 0;

            if (position.Y >= 850 - texture.Height)
                position.Y = 850 - texture.Height;

        }

        // Shoot Function, used to set the starting position of the players bullet
        public void shoot()
        {
            // Shoot only if the bullet delay resets
            if (bulletDelay >= 0)
                bulletDelay--;

        // If bulletDelay is at 0, create a new bullet at player position, make it visible on the scrren, then add that bullet to bulletList
            if (bulletDelay <= 0)
            {
                Bullet newBullet1 = new Bullet(bulletTexture);
                newBullet1.position = new Vector2(position.X  - newBullet1.texture.Width / 2, position.Y + 30);
                newBullet1.isVisible = true;

                Bullet newBullet2 = new Bullet(bulletTexture);
                newBullet2.position = new Vector2(position.X + 64 - newBullet2.texture.Width / 2, position.Y + 30);
                newBullet2.isVisible = true;

                // control the amount of bullets on the screen by increasing number
                if (bulletList.Count() < bulletCount)
                    bulletList.Add(newBullet1);
                    bulletList.Add(newBullet2);    
            }

            // Reset bullet dleay
            if (bulletDelay == 0)
                bulletDelay = bulletDelayReset;
        }
        public void updateBullets()
        {
            // for each bullet in the bulletList: update the movement and if the bullet hits the top of the screen, remove it from the list
            foreach (Bullet b in bulletList)
            {
                // set movement for the bullets
                b.position.Y = b.position.Y - b.speed;

                //make a Bounding box for every bullet in the bullet list
                b.boundingBox = new Rectangle((int)b.position.X, (int)b.position.Y, b.texture.Width, b.texture.Height);

                // if a bullet hits the top of the screen, then make visable false
                if (b.position.Y <= 0)
                    b.isVisible = false;
            }

            // go through the bulletList and see if any of the bullets are not visible, if they are not then remove that bullet from the bulletList
            for (int i = 0; i < bulletList.Count; i++)
            {
                if (!bulletList[i].isVisible)
                {
                    bulletList.RemoveAt(i);
                    i--;    
                }
            }
        } 
    }
}




    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 Space_Shooter
{


    public class Bullet
    {
        public Rectangle boundingBox;
        public Texture2D texture;
        public Vector2 position , origin;
        public float speed;
        public bool isVisible;

        public Bullet(Texture2D newTexture)
        {
            speed = 25;
            texture = newTexture;
            isVisible = false;
        }

        public void Draw(SpriteBatch spritebatch)
        {
            spritebatch.Draw(texture, position, Color.White);
        }

    }

}

您可以在构造函数中初始化列表:

public Boss(Texture2D newTexture, Vector2 newPosition, Texture2D newBulletTexture)

但是,您不调用此构造函数。 您称Boss boss = new Boss();

因此,不会调用初始化列表的构造函数。

您应该在所有构造函数中初始化列表:

public Boss()
{
    bulletList = new List<Bullet>();
}

更好的方法是使默认构造函数设置所有默认值,如果需要在其他构造函数中设置其他值,则可以使用: this()从“第二个”构造函数中调用默认构造函数:

public Boss()
{
    bulletList = new List<Bullet>();
    bulletSpeed = 25;
    bulletDamage = 25;
    shipDamage = p.health / 2;
    health = 2000;
    bulletDelayTime = 30;
    bulletDelayTimeReset = 30;
    MaxBullets = 30;
    isVisible = true;
}

public Boss(Texture2D newTexture, Vector2 newPosition, Texture2D newBulletTexture)
    : this() //Call default constructor
{
    texture = newTexture;
    position = newPosition;
    bulletTexture = newBulletTexture;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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