Get tile texture from map

From TRCCompSci - AQA Computer Science
Jump to: navigation, search

New Method

I have added a couple of methods to Squared.Tiled, these are available if you have downloaded the code from the links below. So make sure the Layer class definition in your Squared.Tiled has GetTileTexture() and GetTextureData methods:

Square.Tiled Class

GitHub TRCCompSci tiled-xna

To use these methods make sure you have the following declared in Game1.cs:

        Texture2D tiletext;
        Tileset tiles;

        Rectangle playerrec;
        Color[] TileTextureData, PlayerTextureData;

Now in the LoadContent method of Game1.cs, make sure you have setup the Tileset:

tiles = map.Tilesets["dungeon"];
PlayerTextureData = new Color[hero.Width * hero.Height];
hero.GetData(PlayerTextureData);

Now wherever you need to get the texture of a tile we can use the methods instead. The code below shows how, and is from a checkbounds method which checks every tile on the collision layer to see if the tile is empty or not:

                    if (collision.GetTile(x, y) != 0)
                    {
                        //Player rectangle, this could really go in update method
                        Rectangle playrec = map.ObjectGroups["objects"].Objects["player"].Bounds;
                        
                        //Rectangle for position of the tile on the screen (my tiles are 16x16
                        Rectangle tilerec = new Rectangle(x*16,y*16,16,16);
                        Texture2D test = testtext;

                        //Check if it intersects first
                        if (tilerec.Intersects(playrec))
                        {
                            //Get the texture used for the tile
                            tiletext = collision.GetTileTexture(collision.GetTile(x, y),tiles, test);

                            //Get pixel data from the texture
                            Color[] testdata = collision.GetTextureData(tiletext);

                            //use intersectpixels to test new texture and see if overlapping pixels exist
                            if(IntersectPixels(playrec,playerData,tilerec, testdata))
                                check = true;
                        }

                    }

GetTileTexture accepts an int for the tile (this is via GetTile(x,y)), the Tileset, and the Texture2D to use for the tile. It returns the Texture2D. You must pass it the texture to use because it must be initialised and the correct dimensions.

GetTextureData accepts just a Texture2D and returns a Color[] (ie a array of Color).

You can get the IntersectPixels methods from Basic Per Pixel Collision.

Original Method

Getting a texture for a tile is possible, its only taken about 6 hours to figure out the best method. This is assuming you have a game with some form of check bounds.

Declare the following at the top of Game1.cs:

Texture2D tilesheet, tiletexture;
Rectangle tilehit;
Color[] TileTextureData, PlayerTextureData;

In load content you need to add the following (assuming you have a texture declared for hero, my tileset is called dungeon in my map):

            PlayerTextureData = new Color[hero.Width * hero.Height];
            hero.GetData(PlayerTextureData);
            tilesheet = map.Tilesets["dungeon"].Texture;

Inside your check bounds method you should have the first line below, add the rest to check the bounds and per pixel collision:

if (collision.GetTile(x, y) != 0)
        {
            //Rectangle for position of the tile on the screen (my tiles are 16x16)
            Rectangle tilerec = new Rectangle(x*16,y*16,16,16);

            //Check if it intersects first
            if (tilerec.Intersects(playrec))
            {
                //initialize the the texture data for the tilesheet
                TileTextureData = new Color[tilesheet.Width * tilesheet.Height];
                //position of tile to test on your tileseet
                //you could get this from collision.GetTile(x,y) -1
                //you could then do mod division etc to get the 0 & 3 below
                //you could \ this by number of tiles in a row on tile sheet
                //you could % this by the number of rows in your tilesheet
                tilehit = new Rectangle(0 * 16, 3 * 16, 16, 16);
                
                //set texture to an empty texture of the right size for new tile
                tiletext = testtext;
                //this gets all the data and adds it to TileTextureData
                tilesheet.GetData(TileTextureData);

                //create a new color array to match size of tile (1D array of each pixel)
                Color[] test = new Color[16 * 16];
                //set counter for location in new Color array
                int count = 0;

                //for loops to cycle through every pixel in the tile
                for (int c = tilehit.Top; c < tilehit.Bottom; c++)
                {
                    for (int r = tilehit.Left; r < tilehit.Right; r++)
                    {
                        //get current pixel from texture data
                        Color colorA = TileTextureData[r + (c  * tilesheet.Width)];
                        //add to our new array
                        test[count] = colorA;
                        count++;
                     }
                  }

                  //add colour data to make texture for the tile
                  tiletext.SetData(test);

                  //use intersectpixels to test new texture
                  if(IntersectPixels(playrec,PlayerTextureData,tilerec, test))
                        check = true;
            }

        }

You can get the IntersectPixels methods from Basic Per Pixel Collision.