我正在使用 .NET Framework 4 中的 C# 进行编程,旨在使用 XNA 制作瓦片式游戏。我有一个大纹理(256 像素 × 4096 像素)。请注意,这是一款瓦片式游戏,所以这个纹理非常庞大,因为它包含了许多 32 像素 × 32 像素的小块。我想专家们肯定知道什么是瓦片式游戏。方向是正交的(像棋盘),而不是等距的。
在 Game.Draw() 方法中,我有两种选择,其中一种比另一种效率高得多。
方法1/选择1:
半伪代码:
在 Game.Draw() 方法中,我有两种选择,其中一种比另一种效率高得多。
方法1/选择1:
半伪代码:
public void Draw()
{
// map tiles are drawn left-to-right, top-to-bottom
for (int x = 0; x < mapWidth; x++)
{
for (int y = 0; y < mapHeight; y++)
{
SpriteBatch.Draw(
MyLargeTexture, // One large 256 x 4096 texture
new Rectangle(x, y, 32, 32), // Destination rectangle - ignore this, its ok
new Rectangle(x, y, 32, 32), // Notice the source rectangle 'cuts out' 32 by 32 squares from the texture corresponding to the loop
Color.White); // No tint - ignore this, its ok
}
}
}
标题:因此,第一种方法有效地是多次引用一个大纹理,每次使用这个大纹理的一个小矩形来绘制适当的瓷砖图像。
选择/方法#2:
半伪代码:
public void Draw()
{
// map tiles are drawn left-to-right, top-to-bottom
for (int x = 0; x < mapWidth; x++)
{
for (int y = 0; y < mapHeight; y++)
{
Texture2D tileTexture = map.GetTileTexture(x, y); // Getting a small 32 by 32 texture (different each iteration of the loop)
SpriteBatch.Draw(
tileTexture,
new Rectangle(x, y, 32, 32), // Destination rectangle - ignore this, its ok
new Rectangle(0, 0, tileTexture.Width, tileTexture.Height), // Notice the source rectangle uses the entire texture, because the entire texture IS 32 by 32
Color.White); // No tint - ignore this, its ok
}
}
}
注释:因此,第二种方法是多次绘制许多小纹理。
问题:哪种方法以及为什么?个人认为使用第一种方法会更加高效。如果您考虑地图中的瓦片数组(想象一下一个有2000x2000个瓦片的大地图),每个Tile对象只需要包含2个整数,用于表示一个大纹理中源矩形的X和Y位置 - 8字节。然而,如果您使用第二种方法,在地图的瓦片数组中的每个Tile对象都必须存储一个32x32的Texture(即图像),该图像必须为R G B A像素分配32×32次内存 - 每个瓦片大约需要4096个字节。那么,哪种方法以及为什么?首要考虑速度,然后是内存负载,然后是效率或者您专家们所信任的任何其他因素。