Question

Im a C#/XNA student and I've recently been working on an isometric tile engine and so far it works fairly well. But im having problem trying to figure out on how to do collision, this is what my tile engine does at the moment:

  • Draws the world from an image and place a tile depending on what color is on my image. For instance color red would draw a grass tile. (Tiles are 64x32)

  • Camera following player, and my draw loop only draws what the camera sees.

This is how my game looks if that would be of any help: enter image description here

I don't know what sort of collision would work best. Should i do collision points, or intersects or any other sort of collision. I've read somewhere that you could do Worldtoscreen/Screentoworld but im far to inexperienced and don't know how that works nor how the code would look like.

Here is my code drawing tiles etc:

class MapRow
    {
        public List<MapCell> Columns = new List<MapCell>();
    }



    class TileMap
    {
        public List<MapRow> Rows = new List<MapRow>();

        public static Texture2D image;
        Texture2D tileset;


        TileInfo[,] tileMap;


        Color[] pixelColor;


        public TileMap(string TextureImage, string Tileset)
        {
            tileset = Game1.Instance.Content.Load<Texture2D>(Tileset);

            image = Game1.Instance.Content.Load<Texture2D>(TextureImage);
            pixelColor = new Color[image.Width * image.Height]; // pixelColor array that is holding all pixel in the image
            image.GetData<Color>(pixelColor); // Save all the pixels in image to the array pixelColor

            tileMap = new TileInfo[image.Height, image.Width];

            int counter = 0;
            for (int y = 0; y < image.Height; y++)
            {
                MapRow thisRow = new MapRow();
                for (int x = 0; x < image.Width; x++)
                {
                    tileMap[y, x] = new TileInfo();


                    if (pixelColor[counter] == new Color(0, 166, 81))
                    {
                        tileMap[y, x].cellValue = 1;//grass

                    }
                    if (pixelColor[counter] == new Color(0, 74, 128))
                    {

                        tileMap[y, x].cellValue = 2;//water
                    }

                    if (pixelColor[counter] == new Color(255, 255, 0))
                    {
                        tileMap[y, x].cellValue = 3;//Sand
                    }


                    tileMap[y, x].LoadInfoFromCellValue();//determine what tile it should draw depending on cellvalue
                    thisRow.Columns.Add(new MapCell(tileMap[y, x]));


                    counter++;
                }
                Rows.Add(thisRow);
            }
        }


        public static int printx;
        public static int printy;

        public static int squaresAcross = Settings.screen.X / Tile.TileWidth;
        public static int squaresDown = Settings.screen.Y / Tile.TileHeight;

        int baseOffsetX = -32;
        int baseOffsetY = -64;

            public void draw(SpriteBatch spriteBatch)
        {
            printx = (int)Camera.Location.X / Tile.TileWidth;
            printy = (int)Camera.Location.Y / Tile.TileHeight;

            squaresAcross = (int)Camera.Location.X / Tile.TileWidth + Settings.screen.X / Tile.TileWidth;
            squaresDown = 2*(int)Camera.Location.Y / Tile.TileHeight + Settings.screen.Y / Tile.TileHeight + 7;


            for (printy = (int)Camera.Location.Y / Tile.TileHeight; printy < squaresDown; printy++)
            {
                int rowOffset = 0;
                if ((printy) % 2 == 1)
                    rowOffset = Tile.OddRowXOffset;

                for (printx = (int)Camera.Location.X / Tile.TileWidth; printx < squaresAcross; printx++)
                {
                    if (tileMap[printy, printx].Collides(MouseCursor.mousePosition))
                        Console.WriteLine(tileMap[printy, printx].tileRect);

                    foreach (TileInfo tileID in Rows[printy].Columns[printx].BaseTiles)
                    {

                        spriteBatch.Draw(

                            tileset,
                            tileMap[printy, printx].tileRect = new Rectangle(
                                (printx * Tile.TileStepX) + rowOffset + baseOffsetX,
                                (printy * Tile.TileStepY) + baseOffsetY,
                                Tile.TileWidth, Tile.TileHeight),
                            Tile.GetSourceRectangle(tileID.cellValue),
                            Color.White,
                            0.0f,
                            Vector2.Zero,
                            SpriteEffects.None,
                            tileID.drawDepth);





                    }



                }

            }

            }

        }
Était-ce utile?

La solution

Why don't you just draw stuff just like in normal tile based games, and then rotate the camera with a 45degree? Of course then you'd need to make your graphics a bit odd, but would be easier to handle the tiles.

But if you prefer your way, then I'd suggest using simple math to calculate the "tile to the right", "tile to the left" , "tile to the up" and "tile to the down" ones, you know, the tiles around the player(or another tile). You can simply work with your lists, and with some math, basic math, like getting the next tile, is quite simple.

Edit:
You could get the player's next position's tile value with a code something like this:

tileMap[Math.Floor((player.y+playerVelociy.Y)/tileHeight)]
       [Math.Floor((player.x+playerVelocity.X)/tileWidth)]

In this code, I assume that the first tile is at 0,0 and you're drawing to right and down. (If not, then just change the Math.Floor to Math.Ceil)
THIS link could help you get the idea, however it's in AS3.0, only the syntax is different.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top