【问题标题】:XNA Isometric tile collisionXNA 等距瓷砖碰撞
【发布时间】:2014-01-25 10:53:01
【问题描述】:

我是一名 C#/XNA 学生,我最近一直在研究等距平铺引擎,到目前为止它运行良好。但是我在试图弄清楚如何进行碰撞时遇到了问题,这就是我的瓦片引擎目前所做的:

  • 从图像中绘制世界并根据图像上的颜色放置图块。例如,红色将绘制草瓦。 (图块为 64x32)

  • 摄像头跟随玩家,我的绘制循环只绘制摄像头看到的内容。

如果有帮助的话,这就是我的游戏的外观:

我不知道哪种碰撞效果最好。我应该做碰撞点,还是相交或任何其他类型的碰撞。我在某处读过你可以做 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);





                    }



                }

            }

            }

        }

【问题讨论】:

    标签: c# xna collision tile isometric


    【解决方案1】:

    您为什么不像在普通的基于瓷砖的游戏中那样绘制东西,然后将相机旋转 45 度?当然,你需要让你的图形有点奇怪,但处理瓷砖会更容易。

    但是,如果您更喜欢自己的方式,那么我建议使用简单的数学来计算“向右的瓷砖”、“向左的瓷砖”、“向上的瓷砖”和“向下的瓷砖”,你知道,玩家周围的瓷砖(或另一个瓷砖)。您可以简单地处理您的列表,并且使用一些数学、基本数学(例如获取下一个图块)非常简单。

    编辑
    您可以使用如下代码获取玩家下一个位置的 tile 值:

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

    在这段代码中,我假设第一个图块位于 0,0 并且您正在向右和向下绘制。 (如果不是,那么只需将 Math.Floor 更改为 Math.Ceil)
    THIS 链接可以帮助您了解这个想法,但是它在 AS3.0 中,只是语法不同。

    【讨论】:

    • 是的,我想我可以做到(alt nr.2)。但这会使用正常的矩形碰撞吗?而且由于我的瓷砖是等距的,这意味着角落是透明的,程序是否也会认为角落也是碰撞的一部分?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 2013-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多