Я повсюду искал обходной путь к этой проблеме (я могу просто быть слепым, чтобы увидеть, как лежат решения). Моя игра в настоящее время отображает tilemap на экране и не будет отображать фрагменты, которые на самом деле не находятся на границах экрана. Однако каждая плитка имеет 16x16 пикселей, что означает 8100 плиток для рисования, если каждый пиксель на экране содержит плитку с разрешением 1920x1080.Как нарисовать тысячи плиток, не убивая FPS
Рисование того, что много плиток каждый цикл действительно убивает мой FPS. Если я использую разрешение 800x600, то мой FPS будет ~ 20, а в 1920x1080 он будет работать примерно на 3-5 FPS. Это действительно сводит меня с ума.
Я попытался нарезать резьбу и использовать async-задачи, но они просто мерцают на экране. Наверное, я просто неправильно его кодирую.
Вот код чертежа, который я использую в настоящее время.
// Get top-left tile-X
Vector topLeft = new Vector(Screen.Camera.X/16 - 1,
Screen.Camera.Y/16 - 1);
Vector bottomRight = new Vector(topLeft.X + (Screen.Width/16) + 2,
topLeft.Y + (Screen.Height/16) + 2);
// Iterate sections
foreach (WorldSection section in Sections)
{
// Continue if out of bounds
if (section.X + ((Screen.Width/16) + 2) < (int)topLeft.X ||
section.X >= bottomRight.X)
continue;
// Draw all tiles within the screen range
for (int x = topLeft.X; x < bottomRight.X; x++)
for (int y = topLeft.Y; y < bottomRight.Y; y++)
if (section.Blocks[x - section.X, y] != '0')
DrawBlock(section.Blocks[x - section.X, y],
x + section.X, y);
}
От 8 до 12 секций. Каждый фрагмент представлен объектом char в двумерном массиве.
метод Draw блок:
public void DrawBlock(char block, int x int y)
{
// Get the source rectangle
Rectangle source = new Rectangle(Index(block) % Columns * FrameWidth,
Index(block)/Columns * FrameHeight, FrameWidth, FrameHeight);
// Get position
Vector2 position = new Vector2(x, y);
// Draw the block
Game.spriteBatch.Draw(Frameset, position * new Vector2(FrameWidth, FrameHeight) - Screen.Camera, source, Color.White);
}
Метод Индекс() просто возвращает индекс кадра плитки, соответствующего полукокса.
Мне интересно, как я мог бы позволить на самом деле позволить так много рисовать сразу, не убивая частоту кадров таким образом. Является ли код, который я предоставил, явно не очень оптимизирован, или это что-то конкретное, что я должен делать, чтобы сделать это много отдельных плит без снижения производительности?
Код, который вы вложили, выглядит нормально, я бы искал проблемы с производительностью в DrawBlock() или Разделах. Пожалуйста, разместите эти части своего кода. – borkovski
Как насчет одного призывного вызова для каждого раздела? Если секция представляет собой сетку ячеек, скажите (3x3) вместо 9 вызовов, нарисуйте их один раз в подходящее изображение и только рисуйте это. Вы даже можете заранее создать эти разделы на лету, кешировать их и рисовать. Если кеш станет большим, отбросьте старые разделы и снова постройте новые. – dowhilefor
очень незначительный по разделу.Blocks [x - section.X, y], вызываемый дважды и (при отсутствии побочных эффектов), вы можете лучше хранить это в переменной и повторно использовать. Defo post DrawBlock, а также как и где вы измеряете свой FPS? – tolanj