我正在使用Substrate解析minecraft文件数据。 Minecraft由“块”组成,块由块组成。所以我有一个spritesheet与不同的16x16瓷砖。我在WPF中使用croppedbitmap来查找合适的图形切片以构成地图的一部分。然后我在WPF中指定一个Image()控件'source',这是我的croppedbitmap。最后,我做了myCanvas.Children.Add(myImage)...问题是在我的画布中大约30个左右的图像后,应用程序变慢了爬行速度。这是一个问题,因为典型的我的地图将有数百或数千个图像。有没有更好的方法来绘制大量的位图数据?我喜欢使用Image控件,因为我可以将工具提示放在地图上并使其具有交互性。但我接受一个Image控件可能更昂贵,并且有数千个可能无法工作。这是我的代码。 (这只解析某个值的切片,因此如果id == 9)
var mapTiles = (BitmapImage)FindResource("mapTiles");
CroppedBitmap waterImage = new CroppedBitmap(mapTiles, new Int32Rect(352, 48, 16, 16));
CroppedBitmap grassImage = new CroppedBitmap(mapTiles, new Int32Rect(0, 0, 16, 16));
foreach (ChunkRef chunk in chunkManager)
{
countOfTiles++;
for (int x = 0; x <= 15; x++)
{
for (int z = 0; z <= 15; z++)
{
int height = chunk.Blocks.GetHeight(x, z);
//TODO: Normalize Chunk X, Z so 0,0 is the smallest chunk so everything is visible on the canvas.
if (height > 0 && chunk.X > 0 && chunk.Z > 0)
{
var block = chunk.Blocks.GetBlock(x, height - 1, z);
if (block.ID == 9)
{
//352, 48
Image image = new Image();
image.Source = waterImage;
worldMap.Children.Add(image);
Canvas.SetTop(image, (chunk.X + x) * 16);
Canvas.SetLeft(image, (chunk.Z + z) * 16);
image.ToolTip = countOfTiles.ToString();
}
答案 0 :(得分:2)
您可以使用ImageBrush:
,而不是使用较重的Image// use ImageBrush's instead
var waterImage = new ImageBrush(new CroppedBitmap(...));
var grassImage = new ImageBrush(new CroppedBitmap(...));
waterImage.Freeze();
grassImage.Freeze();
随后:
if (block.ID == 9)
{
var water = new Rectangle
{
Width = 16,
Height = 16,
Fill = waterImage
};
worldMap.Children.Add(water);
Canvas.SetTop(water, (chunk.X + x) * 16);
Canvas.SetLeft(water, (chunk.Z + z) * 16);
water.ToolTip = countOfTiles.ToString();
}
如果我遗漏了Freeze,我无法获得具有100x100平铺世界的测试应用程序以正确显示。当我冻结每个画笔时,我可以让地图无缝显示到大约300x300。在1000x1000它几乎不加载,但此时你需要consider virtualizing the view因为UI不会优雅地处理那么多UIElement。