XNA Изометрическая черепица столкновение

Я студент C#/XNA, и недавно я работал над движком изометрических плиток, и пока он работает довольно хорошо. Но у меня возникла проблема, пытаясь выяснить, как сделать столкновение, вот что сейчас делает мой движок плиток:

  • Рисует мир из изображения и размещает плитку в зависимости от того, какой цвет на моем изображении. Например, красный цвет нарисует плитку травы. (Плитка размером 64х32)

  • Камера следует за игроком, и мой цикл прорисовки рисует только то, что видит камера.

Вот как выглядит моя игра, если бы это помогло: введите описание изображения здесь

Я не знаю, какое столкновение будет работать лучше всего. Должен ли я сделать точки столкновения, или пересекается или любой другой вид столкновения. Я где-то читал, что вы могли бы сделать Worldtoscreen/Screentoworld, но я далеко неопытен и не знаю, как это работает, и как будет выглядеть код.

Вот мой лист рисования кода и т. Д.

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);





                    }



                }

            }

            }

        }

1 ответ

Решение

Почему бы вам просто не нарисовать вещи, как в обычных играх на основе плиток, а затем повернуть камеру на 45 градусов? Конечно, тогда вам нужно сделать свою графику немного странной, но проще будет обрабатывать плитки.

Но если вы предпочитаете свой путь, то я бы предложил использовать простую математику для вычисления "плитки направо", "плитки налево", "плитки вверх" и "плитки вниз", вы знаете, плитки вокруг игрока (или другой плитки). Вы можете просто работать со своими списками, а с некоторой математикой базовая математика, такая как получение следующей плитки, довольно проста.

Редактировать:
Вы можете получить значение тайла следующей позиции игрока с помощью кода примерно так:

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

В этом коде я предполагаю, что первый тайл имеет 0,0, а вы рисуете вправо и вниз. (Если нет, просто измените Math.Floor на Math.Ceil)
Эта ссылка может помочь вам понять идею, однако она в AS3.0, только синтаксис другой.

Другие вопросы по тегам