1

这种绘制我的瓷砖的方法似乎很慢,我不确定到底出了什么问题,它相信我的剔除方法不起作用并且在屏幕外绘制东西,但我不完全确定。这里是:

        // Calculate the visible range of tiles.
        int left = (int)Math.Floor(cameraPosition.X / 16);
        int right = left + spriteBatch.GraphicsDevice.Viewport.Width / 16;
        right = Math.Min(right, Width) + 1; // Width -1 originally - didn't look good as tiles drawn on screen
        if (right > tiles.GetUpperBound(0))
            right = tiles.GetUpperBound(0) + 1; // adding 1 to get the last right tile drawn

        int top = (int)Math.Floor(cameraPosition.Y / 16);
        int bottom = left + spriteBatch.GraphicsDevice.Viewport.Height/ 16;
        bottom = Math.Min(bottom, Height) + 1; // Height -1 originally - didn't look good as tiles drawn on screen
        if (bottom > tiles.GetUpperBound(1))
            bottom = tiles.GetUpperBound(1) + 1; // adding 1 to get the last bottom tile drawn

        // For each tile position
        for (int y = top; y < bottom; ++y)
        {
            for (int x = left; x < right; ++x)
            {
                // If there is a visible tile in that position, draw it
                if (tiles[x, y].BlockType.Name != "Blank")
                {
                    Texture2D texture = tileContent["DirtBlock_" + getTileSetType(tiles,x,y)];
                    spriteBatch.Draw(texture, new Vector2(x * 16, y * 16), Color.White);
                    if (isMinimap)
                    spriteBatch.Draw(pixel, new Vector2(30+x, 30+y), Color.White);
                }

            }
        }

GetTileSetTypes 是一个函数,用于获取它周围的瓦片,用于不同的纹理,如 DirtBlock_North、DirtBlock_Center 等。

平铺内容只是我的块纹理的一个类。

4

1 回答 1

1

尝试将 SpriteBatch.Begin 更改为延迟并将所有图块组合到一个纹理上。

请参阅GameDev 问题,了解为什么延迟最有可能是您最快的选择。

还要意识到,每次绘制新纹理时,都必须将旧纹理从 GPU 中取出并放入新纹理。此过程称为纹理交换,通常不是问题,但每个图块交换纹理两次可能会显着影响性能。

这可以通过将多个精灵组合到一个纹理上并使用源矩形参数来解决。这允许您在没有纹理交换的情况下绘制多个精灵。为此有一些 OSS 库。Sprite Sheet Packer是我个人的最爱。

不幸的是,没有项目和分析器,我只是在猜测;然而,这是我所知道的渲染瓷砖地图的两个最大问题。从这里我真的看不出有什么问题。下面是我用来绘制瓦片地图的代码,您可以看到它与您的非常相似。

如果一切都失败了,我建议使用分析器来确定哪些位运行缓慢。

        //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);
            }
        }
于 2012-03-26T18:14:30.963 回答