Question

Situation: Within my game, I have tiles that collide with the player which is detected however when I attempt to cause an event to occur when they collide, nothing will happen.

Problem: I currently have a Collision class within each tile class. Within the tile class I have a method which passes in the player rectangle (x, y, width and height) using parameters. I then call the tiles Collision class check collision method. After some testing, I discovered that the collision IS being recognised however within my tileMap class (holds a 2D array of the Tile class) when I check through each tile (using foreach) and call the update method within each tile class, only the first tile collides. Nothing else.

enter image description here

Here is my code:

Tile:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;

namespace Project
{
    class Tile
    {              
        Texture2D tileTexture;
        Rectangle tileRect;
        public Collision collision;
        private Vector2 pos;
        public int tileNumber;
        private SpriteFont tileT;
        bool box;
        public enum tileCollision
        {
            passable,
            nonpassable,
            trigger,
        }

        public tileCollision tileValue;

        public Tile(string tileType,int number, Rectangle newTileRect, ContentManager Content)
        {                
            tileTexture = Content.Load<Texture2D>(tileType);
            tileT = Content.Load<SpriteFont>("TimesNewRoman");
            tileRect = newTileRect;
            tileNumber = number;

            pos.X = tileRect.X;
            pos.Y = tileRect.Y;

            //check if tile is within draw block 
            if (tileNumber >= 9 && tileNumber <= 13)
            {
                tileValue = tileCollision.passable;    
            }

            if (tileNumber >= 0 && tileNumber <= 8 )
            {                    
                tileValue = tileCollision.nonpassable;
                System.Console.WriteLine("NON PASSABLE TILE: " + " x: " + tileRect.X + " y: " + tileRect.Y);
            }                

            collision = new Collision(tileRect.X, tileRect.Y, tileRect.Width, tileRect.Height);
        }

        public void update(Rectangle rect)
        {
            //System.Console.WriteLine(playerRect.X, playerRect.Y);    
            if (collision.boundingBoxCollisionCheck(rect.X, rect.Y, rect.Width, rect.Height))
            {
                //if (tileValue == tileCollision.nonpassable)
                //{
                //    System.Console.WriteLine("COLLISION!!!!!");
                //}

                box = true;                    
            }
            if (box == true)
            {
                System.Console.WriteLine("COLLISION!!!!! at x: " + tileRect.X + "y: " + tileRect.Y );
            }    
        }

        public void draw(SpriteBatch spritebatch)
        {
            //if tile is within draw block then draw
            spritebatch.Draw(tileTexture, tileRect, Color.White);                                
            spritebatch.DrawString(tileT, pos.X.ToString(), pos, Color.White);               
        }
    }
}

tileMap:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using System.IO;

namespace Project
{
    class TileMap
    {

        //public Tile[,] tile = new Tile[10,10];
        public List<Tile> tiles = new List<Tile>();
        int width;
        int height;    

        string[] tileType = { "Tiles/BrickGrassTile1", "Tiles/BrickGrassTile2", "Tiles/BrickGrassTile3", "Tiles/BrickGrassTile4", 
                                "Tiles/BrickGrassTile5", "Tiles/BrickRoofTile1", "Tiles/BrickRoofTile2", "Tiles/BrickRoofTile3",
                                "Tiles/BrickTile1", "Tiles/GrassPuddleTile1", "Tiles/GrassRockTile1", "Tiles/WallTile1", "Tiles/GrassTile1", "Tiles/GrassTile2", "Tiles/BrickDoor1" };

        public void generateMap(int [,]map, int size, ContentManager content)
        {               
            for (int x = 0; x < map.GetLength(1); x++)
            {
                for (int y = 0; y < map.GetLength(0); y++)
                {
                    int number = map[y, x];

                    if (number >= 0)
                    {
                            tiles.Add(new Tile(tileType[number],number, new Rectangle(x * size, y * size, size, size), content));
                    }

                    width = (x + 1) * size;
                    height = (y + 1) * size;
                }
            }
        }

        public void update(Rectangle playerRect)
        {
            foreach (Tile tile in tiles)
            {    
                tile.update(playerRect);                    
            }
        }

        public void draw(SpriteBatch spritebatch)
        {
            foreach (Tile tile in tiles)
            {
                tile.draw(spritebatch);
            }    
        }          
    }
}
Was it helpful?

Solution

... each tile (using foreach) and call the update method within each tile class, only the first tile collides. Nothing else.

I suspect your player rectangle is smaller than one of your tiles, which is why you are only getting 1 collision.

EDIT

The way your logic works now, once you collide with an item, it permanently says you are colliding with the item. This is incorrect. Use this:

public void update(Rectangle rect)
{
    //System.Console.WriteLine(playerRect.X, playerRect.Y);    
    if (collision.boundingBoxCollisionCheck(rect.X, rect.Y, rect.Width, rect.Height))
    {
        System.Console.WriteLine("COLLISION!!!!! at x: " + tileRect.X + "y: " + tileRect.Y );                  
    }  
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top