Попробуйте изменить SpriteBatch.Begin на защищенный и объединить все плитки в одну текстуру.
См. этот вопрос GameDev для получения информации о том, почему deferred, скорее всего, самый быстрый вариант для вас.
Также поймите, что каждый раз, когда вы рисуете новую текстуру, вы должны вынимать старую из GPU и вставлять новую. Этот процесс называется свопинг текстур и обычно не является проблемой, но вы меняете текстуру дважды за плитку, что может заметно повлиять на производительность.
Это можно исправить, объединив несколько спрайтов в одну текстуру и используя аргумент исходного прямоугольника. Это позволяет вам рисовать несколько спрайтов без замены текстуры. Для этого есть несколько библиотек OSS. Упаковщик листов спрайта - мой личный фаворит.
К сожалению, без проекта и профилировщика, я просто догадываюсь; Тем не менее, это две самые большие ошибки для рендеринга тайловых карт, которые я знаю. Я действительно не вижу ничего плохого отсюда. Ниже приведен код, который я использую для рисования своих карт тайлов, и, как вы видите, он очень похож на ваш.
Если ничего не помогает, я бы предложил использовать профилировщик, чтобы выяснить, какие биты работают медленно.
//Init the holder
_holder = new Rectangle(0, 0, TileWidth, TileHeight);
//Figure out the min and max tile indices to draw
var minX = Math.Max((int)Math.Floor((float)worldArea.Left / TileWidth), 0);
var maxX = Math.Min((int)Math.Ceiling((float)worldArea.Right / TileWidth), Width);
var minY = Math.Max((int)Math.Floor((float)worldArea.Top / TileHeight), 0);
var maxY = Math.Min((int)Math.Ceiling((float)worldArea.Bottom / TileHeight), Height);
for (var y = minY; y < maxY; y++) {
for (var x = minX; x < maxX; x++) {
_holder.X = x * TileWidth;
_holder.Y = y * TileHeight;
var t = tileLayer[y * Width + x];
spriteBatch.Draw(
t.Texture,
_holder,
t.SourceRectangle,
Color.White,
0,
Vector2.Zero,
t.SpriteEffects,
0);
}
}