0

I seem to be getting a null error and I can't for the life of me solve it. I'm basically creating a Tetris clone, but I can't seem to get this to work. I'm creating an array to hold the square shape, and then I am creating rectangles that are the same size, position etc as the square shape so I can use it for collision detection. I've also created rectangles for every tile space on the grid.

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; 
using Microsoft.Xna.Framework.Net; 
using Microsoft.Xna.Framework.Storage; 
 
namespace tetris 
{ 
    class square : sprite 
    { 
        // declare random, to be used with the position of the square shape 
        Random Rand = new Random(); 
 
        public const int 
        START = 0, // newly created sprite 
        FALLING = 1, // square is falling 
        END = 2; // when sprite is finished 
 
 
        int _state;// state for the switch statement 
 
 
        //array for the square  
       public sprite[] squareArray = new sprite[4]; 
 
        //create a new rectangle array so each square tile has a rectangle around it 
       public Rectangle[] shapeTile = new Rectangle[4]; 
 
        const int startingWidth = 101; 
        const int startingHeight = 20; 
 
        const int height = 16; 
        const int width = 10; 
 
 
        // declare timer, to be used with the game clock for the square to be moving downward 
        int _timer; 
 
        // declare velocity for falling square 
        float _velocityX; 
        double _velocityY; 
 
        // declare rotation for square 
        double rotation; 
 
        // starting position for shape 
       public Vector2 startingPosition = new Vector2(205, 20); 
 
 
 
        // Constructor 
        public square(Texture2D tileImage, SpriteBatch sprite, Vector2 pos) 
            : base(tileImage, sprite, pos) 
        { 
            _velocityX = 1; 
 
            //starting position of the tile 
            pos = startingPosition; 
 
            //Initialises 2D array of tiles for square 
 
            //Array for the square! 
            for (int i = 0; i < 4; i++) 
            { 
                squareArray[i] = new sprite(tileImage, spriteBatch, startingPosition); 
            } 
 
 
            // put starting positions for each tile for the square 
            squareArray[0].position = new Vector2(startingPosition.X + 0, startingPosition.Y + 0); 
            squareArray[1].position = new Vector2(startingPosition.X + 35, startingPosition.Y + 0); 
            squareArray[2].position = new Vector2(startingPosition.X + 0, startingPosition.Y + 35); 
            squareArray[3].position = new Vector2(startingPosition.X + 35, startingPosition.Y + 35); 
 
            //shapeTile[0].X = squareArray[0].position.X; 
 
            //for (int q = 0; q < 4; q++) 
            //{ 
                //for (int w = 0; w < 4; w++) 
                //{ 
                    //shapeTile[0] = new Rectangle((startingWidth + (q * 35)), (startingHeight + (w * 35)), 35, 35); 
 
 
            ///// creating each rectangle so it has the same properties as the actual square (position, size etc) 
                    shapeTile[0] = new Rectangle((int)(squareArray[0].position.X), (int)(squareArray[0].position.Y), shapeTile[0].Width, shapeTile[0].Height); 
                    shapeTile[1] = new Rectangle((int)(squareArray[0].position.X), (int)(squareArray[1].position.Y), shapeTile[1].Width, shapeTile[1].Height); 
                    shapeTile[2] = new Rectangle((int)(squareArray[2].position.X), (int)(squareArray[2].position.Y), shapeTile[2].Width, shapeTile[2].Height); 
                    shapeTile[0] = new Rectangle((int)(squareArray[3].position.X), (int)(squareArray[3].position.Y), shapeTile[3].Width, shapeTile[3].Height); 
 
 
            { 
                _state = START; // start spawning square 
            } 
        } 
 
 
        public void Update(KeyboardState kbState) 
        { 
            switch (_state) 
            { 
                case START: // state 1, start 
                    // tiles for the square are visible 
                    squareArray[0].visible = true; 
                    squareArray[1].visible = true; 
                    squareArray[2].visible = true; 
                    squareArray[3].visible = true; 
                    _state = FALLING; 
                    break; 
 
 
                case FALLING: 
                    //movement of square using keyboard 
                    if (kbState.IsKeyDown(Keys.Right)) 
                    { 
                        squareArray[0].position.X += 35.0f * _velocityX; // X position moves 1 tile across 
                        squareArray[1].position.X += 35.0f * _velocityX; // X position moves 1 tile across 
                        squareArray[2].position.X += 35.0f * _velocityX; // X position moves 1 tile across 
                        squareArray[3].position.X += 35.0f * _velocityX; // X position moves 1 tile across 
                    } 
                    if (kbState.IsKeyDown(Keys.Left)) 
                    { 
                        squareArray[0].position.X -= 35.0f; // X position moves 1 tile across 
                        squareArray[1].position.X -= 35.0f; // X position moves 1 tile across 
                        squareArray[2].position.X -= 35.0f; // X position moves 1 tile across 
                        squareArray[3].position.X -= 35.0f; // X position moves 1 tile across                        
                    } 
                    if (kbState.IsKeyDown(Keys.Down)) 
                    { 
                        squareArray[0].position.Y += 35.0f; // X position moves 1 tile across 
                        squareArray[1].position.Y += 35.0f; // X position moves 1 tile across 
                        squareArray[2].position.Y += 35.0f; // X position moves 1 tile across 
                        squareArray[3].position.Y += 35.0f; // X position moves 1 tile across   
                    } 
 
                    //updating rectangles for square as it is moving 
                    shapeTile[0].X = (int)(squareArray[0].position.X); 
                    shapeTile[0].Y = (int)(squareArray[0].position.Y); 
                    shapeTile[1].X = (int)(squareArray[1].position.X); 
                    shapeTile[1].Y = (int)(squareArray[1].position.Y); 
                    shapeTile[2].X = (int)(squareArray[2].position.X); 
                    shapeTile[2].Y = (int)(squareArray[2].position.Y); 
                    shapeTile[3].X = (int)(squareArray[3].position.X); 
                    shapeTile[3].Y = (int)(squareArray[3].position.Y); 
 
                    //end square if bottom tile it goes below the grid 
                    if (squareArray[3].position.Y > 525) 
                    { 
                        _state = END; 
                    } 
 
                    //end square if bottom tile it goes below the grid 
                    if (squareArray[2].position.Y > 525) 
                    { 
                        _state = END; 
                    } 
                   break; 
 
                case END: 
                    // if square is finished, no longer see the tiles 
                    Finished = true; 
                    squareArray[0].visible = false; 
                    squareArray[1].visible = false; 
                    squareArray[2].visible = false; 
                    squareArray[3].visible = false; 
                    break; 
            } 
        } 
 
        //Draws tile using spritebatch 
        public void Draw(GameTime gameTime) 
        { 
            for (int i = 0; i < 4; i++) 
            { 
                squareArray[i].DrawTile(gameTime); 
            } 
        } 
    } 
}
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; 
using Microsoft.Xna.Framework.Net; 
using Microsoft.Xna.Framework.Storage; 
 
namespace tetris 
{ 
    class gameBoard 
    {  
        //create a new sprite array - tileArray 
       public sprite[,] tileArray; 
        const int height = 16; 
        const int width = 10; 
 
        // create a new rectangle array for the board 
       public Rectangle[,] recTile; 
 
 
        const int startingWidth = 101; 
        const int startingHeight = 20; 
 
        public gameBoard(SpriteBatch sprite, Texture2D tile) 
        { 
            //Initialises 2D array of tiles 
           tileArray = new sprite[width, height]; 
 
            //Create and position each tile 
            for (int x = 0; x < width; x++) 
            { 
                for (int y = 0; y < height; y++) 
                { 
                    tileArray[x, y] = new sprite(tile, sprite, new Vector2((startingWidth + (x * 35)), (startingHeight + (y * 35)))); 
                } 
            } 
 
 
            // create and position each rectangle at the exact coordinates as every tile on the grid 
            recTile = new Rectangle[width, height]; 
            for (int b = 0; b < width; b++) 
            { 
                for (int c = 0; c < height; c++) 
                { 
                    recTile[b, c] = new Rectangle((startingWidth + (b * 35)), (startingHeight + (c * 35)), 35, 35); 
 
                } 
            } 
 
        } 
 
        public void Update(GameTime gameTime) 
        { 
        } 
 
 
        //Draws each sprite in the grid, if it is visible 
        public void Draw(GameTime gameTime) 
        { 
            for (int x = 0; x < width; x++) 
            { 
                for (int y = 0; y < height; y++) 
                { 
 
                    if (tileArray[x, y].visible == true) 
                    { 
                        tileArray[x, y].DrawTile(gameTime); 
                    } 
                } 
            } 
        } 
    } 
}
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; 
using Microsoft.Xna.Framework.Net; 
using Microsoft.Xna.Framework.Storage; 
 
namespace tetris 
{ 
    /// <summary> 
    /// This is the main type for your game 
    /// </summary> 
    public class Game1 : Microsoft.Xna.Framework.Game 
    { 
        GraphicsDeviceManager graphics; 
        SpriteBatch spriteBatch; 
 
        Texture2D background; 
        Texture2D tile; 
 
        gameBoard board; 
 
        square shape; 
 
        int _state; 
        int score; 
 
        SpriteFont messageFont; 
 
        const int 
     INSERT_COIN = 0, 
     PLAYING = 1, 
     GAME_OVER = 2; 
 
        public Game1() 
        { 
            graphics = new GraphicsDeviceManager(this); 
 
            //Sets size of window 
            graphics.PreferredBackBufferHeight = 800; 
            graphics.PreferredBackBufferHeight = 600; 
            Content.RootDirectory = "Content"; 
        } 
 
        /// <summary> 
        /// Allows the game to perform any initialization it needs to before starting to run. 
        /// This is where it can query for any required services and load any non-graphic 
        /// related content.  Calling base.Initialize will enumerate through any components 
        /// and initialize them as well. 
        /// </summary> 
        protected override void Initialize() 
        { 
            // TODO: Add your initialization logic here 
 
           board = new gameBoard (spriteBatch, tile); 
 
           shape = new square(tile, spriteBatch, new Vector2(110, 10)); 
           //shape.shapeTile[0] = new Rectangle((int)(shape.squareArray[0].position.X), (int)(shape.squareArray[0].position.Y), shape.shapeTile[0].Width, shape.shapeTile[0].Height); 
           //shape.shapeTile[1] = new Rectangle((int)(shape.squareArray[0].position.X), (int)(shape.squareArray[1].position.Y), shape.shapeTile[1].Width, shape.shapeTile[1].Height); 
           //shape.shapeTile[2] = new Rectangle((int)(shape.squareArray[2].position.X), (int)(shape.squareArray[2].position.Y), shape.shapeTile[2].Width, shape.shapeTile[2].Height); 
           //shape.shapeTile[3] = new Rectangle((int)(shape.squareArray[3].position.X), (int)(shape.squareArray[3].position.Y), shape.shapeTile[3].Width, shape.shapeTile[3].Height); 
 
            base.Initialize(); 
        } 
 
        /// <summary> 
        /// LoadContent will be called once per game and is the place to load 
        /// all of your content. 
        /// </summary> 
        protected override void LoadContent() 
        { 
            // Create a new SpriteBatch, which can be used to draw textures. 
            spriteBatch = new SpriteBatch(GraphicsDevice); 
 
             
            //Load images 
            background = Content.Load<Texture2D>("Background"); 
            tile = Content.Load<Texture2D>("Tile"); 
            messageFont = this.Content.Load<SpriteFont>("font"); 
 
            // TODO: use this.Content to load your game content here 
        } 
 
        /// <summary> 
        /// UnloadContent will be called once per game and is the place to unload 
        /// all content. 
        /// </summary> 
        protected override void UnloadContent() 
        { 
            // TODO: Unload any non ContentManager content here 
        } 
 
        /// <summary> 
        /// Allows the game to run logic such as updating the world, 
        /// checking for collisions, gathering input, and playing audio. 
        /// </summary> 
        /// <param name="gameTime">Provides a snapshot of timing values.</param> 
        protected override void Update(GameTime gameTime) 
        { 
            // Allows the game to exit 
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) 
                this.Exit(); 
 
            KeyboardState kbState = Keyboard.GetState(); 
 
            // switch statement for the gameplay 
 
            switch (_state) 
            { 
                case INSERT_COIN: 
 
                    shape = null; 
                    score = 0; 
                    if (kbState.IsKeyDown(Keys.Escape)) _state = PLAYING; 
                    break; 
 
                case PLAYING: 
                    if (shape == null) shape = new square(tile, spriteBatch, new Vector2(205, 20)); 
                    shape.Update(kbState); 
                    board.Update(gameTime); 
                    if (shape.Finished) score += 30; 
                    if (shape.Finished) shape = null; 
                    
                 
                // create and position each rectangle at the exact coordinates as every tile on the grid 
                    board.recTile = new Rectangle[10, 16]; 
                    for (int b = 0; b < 10; b++) 
                    { 
                        for (int c = 0; c < 16; c++) 
                        { 
                            board.recTile[b, c] = new Rectangle((101 + (b * 35)), (20 + (c * 35)), 35, 35); 
 
                        } 
                    } 
 
 
                    ////// TEST COLLISION ////// 
 
                    //for each tile in the square x 
                    for (int q = 0; q < 4; q++) 
                    { 
                        //for each tile in the square y 
                        for (int w = 0; w < 4; w++) 
                        { 
                            //for each tile on the board x axis 
                            for (int b = 0; b < 10; b++) 
                            { 
                                //for each tile on the board y axis 
                                for (int c = 0; c < 16; c++) 
                                { 
                                    if ((shape.shapeTile[0].Intersects(board.recTile[b, c]))) //) // ERROR IS HERE!
                                    { 
                                        board.tileArray[b, c].visible = true; 
                                        //shape.squareArray[1].visible = true; 
                                        //shape.squareArray[2].visible = true; 
                                        //shape.squareArray[3].visible = true; 
                                    } 
                                } 
                            } 
                        } 
                    } 
                    break; 
 
                case GAME_OVER: 
                    if (score == 40) _state = INSERT_COIN; 
                    break; 
 
                default: 
                    break; 
            } 
 
 
 
            // TODO: Add your update logic here 
 
            base.Update(gameTime); 
        } 
 
        /// <summary> 
        /// This is called when the game should draw itself. 
        /// </summary> 
        /// <param name="gameTime">Provides a snapshot of timing values.</param> 
        protected override void Draw(GameTime gameTime) 
        { 
            GraphicsDevice.Clear(Color.CornflowerBlue); 
            spriteBatch.Begin(); 
 
            switch (_state) 
            { 
                case INSERT_COIN: 
                    spriteBatch.DrawString(messageFont, "Press ESC key to start game", new Vector2(220, 300), Color.White); 
                    break; 
 
                case PLAYING: 
                    spriteBatch.Draw(background, new Vector2(0, 0), Color.White); 
                    board.Draw(gameTime); 
                    if (shape != null) shape.Draw(gameTime); 
                    break; 
 
                case GAME_OVER: 
                    spriteBatch.Draw(background, new Vector2(0, 0), Color.White); 
                    break; 
 
                default: 
                    break; 
            } 
 
            spriteBatch.End(); 
            // TODO: Add your drawing code here 
 
            base.Draw(gameTime); 
        } 
    } 
 
}

Error at run-time is:
Object reference not set to an instance of an object.

Any help would be greatly appreciated.

DaveT

2
Contributors
5
Replies
7
Views
7 Years
Discussion Span
Last Post by zerocool21
0

u either missed a object creation/instatiation Or just created a object and did not use it!
check it
may be it would help!

0

I've got rid of the run-time error now by changing the definition on line 128 in the Game1.cs; but my collision detection refuses to work.

////// TEST COLLISION //////

                    //for each tile in the square x
                    for (int q = 0; q < 4; q++)
                    {
                        //for each tile in the square y
                        for (int w = 0; w < 4; w++)
                        {
                            //for each tile on the board x axis
                            for (int b = 0; b < 10; b++)
                            {
                                //for each tile on the board y axis
                                for (int c = 0; c < 16; c++)
                                {
                                    if ((shape.shapeTile[0].Intersects(board.recTile[b, c])) &&
                                        (shape.shapeTile[1].Intersects(board.recTile[b, c])) &&
                                        (shape.shapeTile[2].Intersects(board.recTile[b, c])) &&
                                        (shape.shapeTile[3].Intersects(board.recTile[b, c])) && (shape.Finished = true)) //)
                                    {
                                        board.tileArray[b, c].visible = true;
                                        board.tileArray[b, c].visible = true;
                                        board.tileArray[b, c].visible = true;
                                        board.tileArray[b, c].visible = true;
                                        
                                        shape.squareArray[0].visible = true;
                                        shape.squareArray[1].visible = true;
                                        shape.squareArray[2].visible = true;
                                        shape.squareArray[3].visible = true;
                                    }
                                }
                            }
                        }
                    }

Any ideas? When in debugging mode, the value of b and c are 0, which I think is the problem.

DaveT

0

try using for (int b = 1; b <= 10; b++)
i know array index starts from 0
but just for a test
for both b & c

Edited by zerocool21: n/a

0

try using for (int b = 1; b <= 10; b++)
i know array index starts from 0
but just for a test
for both b & c

Thanks for the reply.

I've done that and all I'm getting is array index is out of bounds at run-time

-DaveT

Edited by DaveTELFA: n/a

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.