Monogame - 等距图块,大地图上的低 FPS
Monogame - Isometric Tiles, low FPS on big maps
我在 Monogame 中的等距 2D 代码方面需要帮助。
我已经成功创建了以 60FPS 渲染 500*750 个图块(128x64 大小)的图块引擎(但我的电脑着火了),但问题是更大的图块会导致 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));
}
}
然后当我需要绘制时,我正在使用将绘制可见图块的收集方法:
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
我真的需要帮助我已经坐了很长时间了。
谢谢。
编辑:
所以我只用可见的替换了我在每个tile上的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 上午坐在这里思考
如果要绘制二维地图,为什么不以二维方式存储呢?二维数组就可以了。
这样您就可以计算出要渲染的区域的哪一部分,并使用 2 个 for 循环遍历数组。
永远不要在实时应用程序中使用 LinQ,仅当您调用它一次而不是在每次绘制调用时调用它。
您可以将转换矩阵添加到相机,这样您就可以跳过移动添加,而是通过 SpriteBatch 移动图块的顶点。
我在 Monogame 中的等距 2D 代码方面需要帮助。 我已经成功创建了以 60FPS 渲染 500*750 个图块(128x64 大小)的图块引擎(但我的电脑着火了),但问题是更大的图块会导致 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));
}
}
然后当我需要绘制时,我正在使用将绘制可见图块的收集方法:
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
我真的需要帮助我已经坐了很长时间了。
谢谢。
编辑: 所以我只用可见的替换了我在每个tile上的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 上午坐在这里思考
如果要绘制二维地图,为什么不以二维方式存储呢?二维数组就可以了。
这样您就可以计算出要渲染的区域的哪一部分,并使用 2 个 for 循环遍历数组。
永远不要在实时应用程序中使用 LinQ,仅当您调用它一次而不是在每次绘制调用时调用它。
您可以将转换矩阵添加到相机,这样您就可以跳过移动添加,而是通过 SpriteBatch 移动图块的顶点。