specific tile collision not detecting c# xna monogame

  • (2 Pages)
  • +
  • 1
  • 2

19 Replies - 1462 Views - Last Post: 21 December 2016 - 06:32 PM

#1 AnonymousUser1508  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 18
  • Joined: 29-April 16

specific tile collision not detecting c# xna monogame

Posted 20 December 2016 - 03:21 AM

Currently the tile map is drawing fine but I am not sure how to proceed with collisions between the player and some of the tiles. Would it be better to specify certain tiles that the player can't move through or is there a better way to go about this? I basically want tile number 4 to not be passable when the player hits it. The issue as far as I'm aware is with the logic in the method Check for colllision in the TileMap class. At the minute I simply want it to state when it hits the tile 4 in the console log. After using debug tools to try and figure out the problem the whole checkForCollision method isn't being executed at all.

Thank you very much in advance and any help is greatly appreciated.

MapCell
    public class MapCell
    {
        
        public int TileID { get; set; }
        
        public MapCell(int tileID) 
        {
            TileID = tileID;              
        }
    }
`}


Player class

in the update method
    playerRect = new Rectangle((int)Position.X, (int)Position.Y, playerRect.Width, playerRect.Height);


TileMap
    class TileMap
    {
        Player player = new Player(null, Vector2.Zero);
        private List<Texture2D> tileList = new List<Texture2D>();
        MapCell[,] mapCell;

        public const int TILE_WIDTH = 64;
        public const int TILE_HEIGHT = 64;
        private bool passable = true;

        public TileMap(int[,] exisitingMap)
        {
            //initialise this to a new multidimensional array;
            mapCell = new MapCell[exisitingMap.GetLength(0), exisitingMap.GetLength(1)];
            
            // x always starts on one 
            for (int x = 0; x < mapCell.GetLength(1); x++)
            {
                for (int y = 0; y < mapCell.GetLength(0); y++)
                {
                    mapCell[y, x] = new MapCell(exisitingMap[y, x]);
                }
            }       

         }

        public void loadTextureFiles(ContentManager content, params string[] fileNames)
        {
            Texture2D tileTexture;
            foreach (string fileName in fileNames)
            {
                tileTexture = content.Load<Texture2D>(fileName);
                tileList.Add(tileTexture);
            }
        }

        public void checkForCollision()
        {
            int tileX = (int)(player.Position.X) / TILE_WIDTH;
            int tileY = (int)(player.Position.Y) / TILE_HEIGHT;

            int left = player.playerRect.Left / TILE_WIDTH;
            int top = player.playerRect.Top / TILE_HEIGHT;
            int right = (int)Math.Ceiling((float)player.playerRect.Right / TILE_WIDTH) - 1;
            int bottom = (int)Math.Ceiling((float)player.playerRect.Bottom / TILE_HEIGHT) - 1;

            int posX = tileX * TILE_WIDTH;
            int posY = tileY * TILE_HEIGHT;

            Rectangle tileRect = new Rectangle(posX, posY, TILE_WIDTH, TILE_HEIGHT);

            for(int y = top; y<= bottom; ++y)
            {
                for (int x = left; x <= right; ++x)
                {
                    if (tileRect.Intersects(player.playerRect))
                    {
                      if (mapCell[tileY, tileX].TileID == 4)
                        {
                            Console.WriteLine("tile 4 has been hit");
                            passable = false;
                            
                        }
                    } 
                }
            }
        }
        public void Update()
        {
            checkForCollision();

        }

        public void Draw(SpriteBatch spriteBatch)
        {
            for (int x = 0; x < mapCell.GetLength(1); x++)
            {
                for (int y = 0; y < mapCell.GetLength(1); y++)
                {
                    // setting the index to the tile ID
                    int index = mapCell[y,x].TileID;
                   

                    // checking if there is a tile
                    if(index > 0)
                    {
                        // start from the first index.
                        Texture2D texture = tileList[index -1 ];
                        spriteBatch.Draw(texture, new Rectangle(x * TILE_WIDTH, y * TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT), Color.White);
                    }       
                }
            }   
        }


Game 1
        TileMap tileMap = new TileMap(new int[,]
        {
            // needs to be separated by a comma
            { 4,4,4,4,4,4,4 },
            { 4,1,1,1,1,1,4 },
            { 4,1,1,0,1,1,4 },
            { 4,0,1,0,1,3,4 },
            { 4,3,3,3,3,2,4 },
            { 4,2,0,2,0,0,4 },
            { 4,4,4,4,4,4,4 },
        });

 


Is This A Good Question/Topic? 0
  • +

Replies To: specific tile collision not detecting c# xna monogame

#2 AnonymousUser1508  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 18
  • Joined: 29-April 16

Re: specific tile collision not detecting c# xna monogame

Posted 20 December 2016 - 03:36 AM

As i can't edit the post, just to clarify in the actual code the Update in TileMap is like this
public void Update(GameTime gameTime)

Was This Post Helpful? 0
  • +
  • -

#3 andrewsw  Icon User is offline

  • lashings of ginger beer
  • member icon

Reputation: 6341
  • View blog
  • Posts: 25,584
  • Joined: 12-December 12

Re: specific tile collision not detecting c# xna monogame

Posted 20 December 2016 - 03:56 AM

If checkForCollision isn't called then presumably your Update method is never called?

At the risk of embarrassing myself, as I know nothing about this, for your custom Update method to be called it would need to be called from the Game's Update method, which would have the signature protected override void Update(GameTime gameTime) and then call map.Update(gameTime); as demonstrated here.

Otherwise, your method is named Update but there is nothing causing it to be executed.
Was This Post Helpful? 1
  • +
  • -

#4 AnonymousUser1508  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 18
  • Joined: 29-April 16

Re: specific tile collision not detecting c# xna monogame

Posted 20 December 2016 - 06:05 AM

You have got to be kidding me, can't believe I didn't see that. Well the update is running now and it is specifying when a tile is hit and it is changing passable to false. However, I am currently getting an out of range exception and the tile ID 4 was outside the bounds of the array.
 for (int y = top; y <= bottom; ++y)
            {
                for (int x = left; x <= right; ++x)
                {
                    if (player.playerRect.Intersects(tileRect))
                    {
                        if (mapCell[tileY, tileX].TileID == 4)
                        {
                            Console.WriteLine("none passable tile has been hit");
                            passable = false;
                            if (passable == false)
                            {

                                player.Accel = 0;
                            }
                        }
                    }
                }
            }


Thank you very much for your help anyway, it has been greatly aprecciated.

This post has been edited by andrewsw: 20 December 2016 - 06:21 AM
Reason for edit:: Removed previous quote, just press REPLY

Was This Post Helpful? 0
  • +
  • -

#5 andrewsw  Icon User is offline

  • lashings of ginger beer
  • member icon

Reputation: 6341
  • View blog
  • Posts: 25,584
  • Joined: 12-December 12

Re: specific tile collision not detecting c# xna monogame

Posted 20 December 2016 - 06:23 AM

What are the exact error details and what line do they refer to in your posted code?

outside the bounds of the array means that, if you have an array of size 4, then the elements are referenced using indexes 0-3, if you try to reference an element with index 4 you will get this error.
Was This Post Helpful? 0
  • +
  • -

#6 andrewsw  Icon User is offline

  • lashings of ginger beer
  • member icon

Reputation: 6341
  • View blog
  • Posts: 25,584
  • Joined: 12-December 12

Re: specific tile collision not detecting c# xna monogame

Posted 20 December 2016 - 06:34 AM

That nested x-y loop is no longer correct, you aren't using the values x or y. You are examining the same rectangle and player-rectangle multiple times.

(You also wouldn't need the statement if (passable == false) as it will be false because you've set it to that value on the line immediately before this statement.)
Was This Post Helpful? 0
  • +
  • -

#7 AnonymousUser1508  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 18
  • Joined: 29-April 16

Re: specific tile collision not detecting c# xna monogame

Posted 20 December 2016 - 06:47 AM

The error message is this.
An unhandled exception of type 'System.IndexOutOfRangeException' occurred in ... .exe
Additional information: Index was outside the bounds of the array.

System.IndexOutOfRangeException was unhandled
HResult=-2146233080
Message=Index was outside the bounds of the array.

The line it happens on is
if (mapCell[tileY, tileX].TileID == 4)

                    if (player.playerRect.Intersects(tileRect))
                    {
                        if (mapCell[tileY, tileX].TileID == 4) // the error happens right here
                        {
                            Console.WriteLine("unpassable tile has been hit");
                            passable = false;
                            player.Accel = 0;
                        }
                    }
            }


I know how an index out of range exception works, as far as I'm aware if you are trying to access index 7 and there is 6 in the array this error will occur. However, in Game1 where the map is being drawn there are enough.

  TileMap tileMap = new TileMap(new int[,]
        {
            
            { 4,4,4,4,4,4,4 },
            { 4,1,1,1,1,1,4 },
            { 4,1,1,0,1,1,4 },
            { 4,0,1,0,1,3,4 },
            { 4,3,3,3,3,2,4 },
            { 4,2,0,2,0,0,4 },
            { 4,4,4,4,4,4,4 },
        });



The only thing I can think of is, in the draw method of TileMap I am typing index -1 but surely that wouldn't cause it to go out the bounds...

 
                    // checking if there is a tile
                    if (index > 0)
                    {
                        // start from the first index.
                        Texture2D texture = tileList[index - 1]; // here




Thank you very much, again.
Was This Post Helpful? 0
  • +
  • -

#8 andrewsw  Icon User is offline

  • lashings of ginger beer
  • member icon

Reputation: 6341
  • View blog
  • Posts: 25,584
  • Joined: 12-December 12

Re: specific tile collision not detecting c# xna monogame

Posted 20 December 2016 - 07:16 AM

What are the values of tileY and tileX when the error occurs?
Was This Post Helpful? 0
  • +
  • -

#9 AnonymousUser1508  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 18
  • Joined: 29-April 16

Re: specific tile collision not detecting c# xna monogame

Posted 20 December 2016 - 07:29 AM

Hi again,

It seems to vary, quite a few times TileX = 7 and TileY = 1. However, it just bought the error up on TileX = 0, TIleY = 7. Just ran it 3 more times and it 'broke' at TileX = 7 and TileY = 1, so that is the most common time it breaks.
Was This Post Helpful? 0
  • +
  • -

#10 AnonymousUser1508  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 18
  • Joined: 29-April 16

Re: specific tile collision not detecting c# xna monogame

Posted 20 December 2016 - 07:45 AM

Just noticed something when debugging, it seems to be whenever the player hits any 0's in the tile map. when this occurs thats when the program breaks. The 0's that are in the game1 map represent blank spaces. I thought this might have been part of the issue but I was wrong, it still appears to break the majority of the time on tileX = 7, tileY = 0.

Sorry, I meant tileX = 7, tileY = 1.
Was This Post Helpful? 0
  • +
  • -

#11 andrewsw  Icon User is offline

  • lashings of ginger beer
  • member icon

Reputation: 6341
  • View blog
  • Posts: 25,584
  • Joined: 12-December 12

Re: specific tile collision not detecting c# xna monogame

Posted 20 December 2016 - 07:52 AM

If mapCell relates to your tileMap then that explains why 7 is out of bounds.
Was This Post Helpful? 0
  • +
  • -

#12 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 5830
  • View blog
  • Posts: 19,876
  • Joined: 05-May 12

Re: specific tile collision not detecting c# xna monogame

Posted 20 December 2016 - 08:02 AM

Not related, but there is a typo on line 78 of TileMap from post #1.
Was This Post Helpful? 0
  • +
  • -

#13 AnonymousUser1508  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 18
  • Joined: 29-April 16

Re: specific tile collision not detecting c# xna monogame

Posted 20 December 2016 - 08:43 AM

View Postandrewsw, on 20 December 2016 - 07:52 AM, said:

If mapCell relates to your tileMap then that explains why 7 is out of bounds.



But when the out of bounds exception happens, the player is still at least a tile or so within the map. Any links or tips on where to go from here. You've been a great help by the way, Thank you.
Was This Post Helpful? 0
  • +
  • -

#14 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 5830
  • View blog
  • Posts: 19,876
  • Joined: 05-May 12

Re: specific tile collision not detecting c# xna monogame

Posted 20 December 2016 - 08:50 AM

How can the player be still on a tile or so within the map? You computed tileX and tileY as:
        int tileX = (int)(player.Position.X) / TILE_WIDTH;
        int tileY = (int)(player.Position.Y) / TILE_HEIGHT;



If tileY is 7, then that means that player.Position.Y is at least 7 * TILE_HEIGHT.
Was This Post Helpful? 0
  • +
  • -

#15 AnonymousUser1508  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 18
  • Joined: 29-April 16

Re: specific tile collision not detecting c# xna monogame

Posted 20 December 2016 - 10:00 AM

Thats the thing I have no idea about.

            { 4,4,4,4,4,4,4 },
            { 4,1,1,1,1,1,4 },
            { 4,1,1,1,1,1,4 },
            { 4,1,1,1,1,3,4 },
            { 4,3,3,3,3,3,4 },
            { 4,2,2,2,2,2,4 }, // it crashes here saying it has crashed on tileY = 7.
            { 4,4,4,4,4,4,4 },




It doesn't happen every time though, it just seems (as far as I'm aware after many tests) to happen every time on the TileY with that map above. However, I can sometimes go out the map and it won't bring up an out of range exception. it literally just crashed on TileY = 7, TileX = 5.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2