help me out with tile collision?

Sep 27, 2011 at 4:47 PM

awesome tool i must admit it is incredible and easy to create animated tile maps but i've got a problem that doesnt even allow me to sleep well, the tile collision stuff.

First of all i've already checked the zelda like top down discussion about the tile collision but i had to change the code on my game cuz it was showing some errors. Im a complete novice to xna and also c# so i really cant figure out how to do the very simplest tile collision,so i want to show whats going on in my code:


    class PlayerSprite
    {
        Map map;
        Layer collision;
        Texture2D Texture;
        Point Position;
        Microsoft.Xna.Framework.Rectangle Collisionbox;


        public PlayerSprite(Texture2D texture, Point position, Microsoft.Xna.Framework.Rectangle collisionBox, Map map)
            
        {
            this.map = map;
            collision = map.Layers[2];
            Position = position;
            Texture = texture;
            Collisionbox = collisionBox;



        }

        public void Update(GameTime gametime)
        {
            Point newPos = Position;

            KeyboardState keyState = Keyboard.GetState();

            if (keyState.IsKeyDown(Keys.W))
                newPos.Y -= 2;
            if (!calculateCollision(newPos))
                Position.Y = newPos.Y;
            else
                newPos.Y = Position.Y;
            jin = 3;
            if (keyState.IsKeyDown(Keys.S))
                newPos.Y += 2;
            if (!calculateCollision(newPos))
                Position.Y = newPos.Y;
            else
                newPos.Y = Position.Y;

            if (keyState.IsKeyDown(Keys.A))
                newPos.X -= 2;
            if (!calculateCollision(newPos))
                Position.X = newPos.X;
            else
                newPos.X = Position.X;

            if (keyState.IsKeyDown(Keys.D))
                newPos.X += 2;
            if (!calculateCollision(newPos))
                Position.X = newPos.X;
            else
                newPos.X = Position.X;
        }

        private bool calculateCollision(Point newPos)
        {
            Tile tile;
            Location tileLocation;

            Debug.WriteLine("cx: " + Collisionbox.X + " cy: " + Collisionbox.Y + "\n");

            tileLocation = new Location((newPos.X - Collisionbox.Width / 2) / 64,
                (newPos.Y - Collisionbox.Height / 2) / 64);
            tile = collision.Tiles[tileLocation];
            if (tile.TileIndex == 51)
                return true;

            tileLocation = new Location((newPos.X + Collisionbox.Width / 2) / 64,
                (newPos.Y - Collisionbox.Height / 2) / 64);
            tile = collision.Tiles[tileLocation];
            if (tile.TileIndex == 51)
                return true;

            tileLocation = new Location((newPos.X + Collisionbox.Width / 2) / 64,
                (newPos.Y + Collisionbox.Height / 2) / 64);
            tile = collision.Tiles[tileLocation];
            if (tile.TileIndex == 51)
                return true;

            tileLocation = new Location((newPos.X - Collisionbox.Width / 2) / 64,
                (newPos.Y + Collisionbox.Height / 2) / 64);
            tile = collision.Tiles[tileLocation];
            if (tile.TileIndex == 51)
                return true;

            return false;
        }

        public void draw(SpriteBatch spritebatch)
        {
            spritebatch.Draw(Texture, Collisionbox, Color.White);
        }
    }
}



it looks ok to me but not for the xna cuz it keeps telling me that message:   "Object reference not set to an instance of an object."

it happens on the calculateCollision() method here:

 tileLocation = new Location((newPos.X - Collisionbox.Width / 2) / 64,
                (newPos.Y - Collisionbox.Height / 2) / 64);
            tile = collision.Tiles[tileLocation];
    HERE IS THE PROBLEM  ----->  if (tile.TileIndex == 51)
                return true;

51 is the index off my collision tile.
sorry for my bad english and i really appreciate some help here or maybe another way off doing tile collisions plz?









Sep 27, 2011 at 10:34 PM

Hi thalez0r,

I think the problem is that you're not checking if a tile is null before quering the TileIndex property. Please bear in mind that by default the clear areas of a layer are null tiles. Hence you would need to modify your if condition to something like:

if (tile != null && tile.TileIndex == 51)

Hope that helps.