【问题标题】:Monogame - Isometric Tiles, low FPS on big mapsMonogame - Isometric Tiles,大地图上的低 FPS
【发布时间】:2017-07-15 06:33:13
【问题描述】:

我在 Monogame 中的等距 2D 代码方面需要帮助。 我已经成功创建了 500*750 瓦片(128x64 大小)以 60FPS 渲染的瓦片引擎(但我的电脑着火了),但问题在于较大的尺寸,FPS 会下降很多。

首先我会将所有图块加载到图块列表中:

for (int i = 0; i < 500; i++)
        {
            for (int j = 0; j < 750; j++)
            {
                int x = j * 128 / 2;
                int y = i * 64;

                int ix = x - y;
                int iy = (x + y) / 2;
                tiles.Add(new Tile("001", new Vector2(ix, iy), new Vector2(j, i), spriteBatch, spriteFont, content));
            }
        }

然后当我需要绘制时,我会使用 colling 方法来绘制可见图块:

public void drawMap(Camera camera)
    {
        if (spriteBatch != null)
        {
            tilesDrawed = 0;
            foreach (Tile tile in tiles) // the problem
            {
                if (camera.isTileVisibe((int)tile.position.X, (int)tile.position.Y))
                {
                    Point isoCoords = new Point((int)tile.position.X, (int)tile.position.Y);
                    isoCoords.X -= camera.xOffset;
                    isoCoords.Y -= camera.yOffset;

                    tile.drawTile(isoCoords);
                    tilesDrawed++;
                }
            }


        }
    }

我知道问题是我要遍历每一个可能的图块。 但我不知道如何处理这个:/。我在想我只会将可见的图块添加到图块列表中,但最后它是相同的,我必须考虑所有图块以检查它们是否对相机可见。

结果: Result

我真的需要帮助,我已经坐了很长时间了。

谢谢。

编辑: 所以我只用可见的替换了我在everytile 上的foreach:

            List<Tile> visibleTiles = tiles.FindAll(r => (
                           (int)r.position.X + 128 > camera.width + camera.xOffset - camera.width && (int)r.position.X - 128 < camera.width + camera.xOffset) &&
                          ((int)r.position.Y + 64 > camera.height + camera.yOffset - camera.height && r.position.Y - 64 < camera.height + camera.yOffset));


            foreach (Tile tile in visibleTiles)
            {
                Point isoCoords = new Point((int)tile.position.X, (int)tile.position.Y);
                isoCoords.X -= camera.xOffset;
                isoCoords.Y -= camera.yOffset;

                tile.drawTile(isoCoords);
                tilesDrawed++;
            }

我觉得 findAll 很慢,只是快了一点。

我切换到二维数组 我需要找到可见的瓷砖.. 当我计算时:

            int si = (-camera.xOffset - tileWidth) / 64;
            int ei = (-camera.xOffset + camera.width + tileWidth) / 64;
            int sj = (-camera.yOffset - tileHeight) / 64;
            int ej = (-camera.yOffset + camera.height + tileHeight) / 64;

            Point start = twoDToIso(new Point(si,sj));
            Point end = twoDToIso(new Point(ei, ej));

有点不对劲,如果它出站,我会检查是否存在图块。

我想不通.. 凌晨 3:00 坐在这里思考

【问题讨论】:

    标签: xna monogame tile frame-rate isometric


    【解决方案1】:

    如果你想画一张 2D 地图,为什么不把它存成 2D 呢?一个二维数组就可以了。

    这样你就可以计算出你想要渲染区域的哪一部分,并使用 2 个 for 循环来遍历数组。

    永远不要在实时应用程序中使用 LinQ,只有在您调用一次而不是每次绘图调用时才使用它。

    您可以向相机添加一个转换矩阵,这样您就可以跳过移动添加,而是通过 SpriteBatch 移动图块的顶点。

    【讨论】:

    • 感谢您的回复,iso 我将它放入 tile[][] 二维数组中,现在我正在尝试计算要绘制的内容.. 还不是很好:/
    • 您之前确实通过限制绘制的图块数量优化了您的绘图。使用相同的算法,但使用它来获取您想要查看的区域。
    • 嗯,我现在真的迷路了,以前的方法是有限的,但是如果我绘制指定的瓷砖它更有效,我试图计算右上角并从中绘制,但由于某种原因它不行当我移动相机时,它会开始计算错误并且绘制的瓷砖数量正在增加。
    • 在我参与过的一些项目中,我还最终在较大的图块中预先绘制了关卡,这样我们就可以减少绘制调用(在绘制成百上千个小块时会影响性能)纹理)。我这样做的方法是将地图的块渲染为纹理,并在实际实时绘制地图时使用这些块。这极大地提升了性能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多