有效的方法来呈现瓷砖

我已经建立了一个tilemap系统,并且以一种让我通过摄影机偏移来平移地图的方式。 但是,我发现这是非常低效的,但我不确定如何提高效率。

这是我目前的渲染代码:

float lastCamOffSetX = -1, lastCamOffSetY = -1; public override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.Black); spriteBatch.Begin(); int count = 0; int startCol = (int)camOffsetX/world.TileWidth; int startRow = (int)camOffsetY/world.TileHeight; int endCol = (int)(startCol + viewPortWidth - (camOffsetX/world.TileWidth)); int endRow = (int)(startRow + viewPortHeight - (camOffsetY/world.TileHeight)); if (startCol < 0) startCol = 0; if (startRow < 0) startRow = 0; if (endCol > world.Width) endCol = world.Width; if (endRow > world.Height) endRow = world.Height; for (int x = startCol; x < endCol; x++) { for (int y = startRow; y < endRow; y++) { int screenPosX = (int)((x * world.TileWidth) - (camOffsetX)); int screenPosY = (int)((y * world.TileHeight) - (camOffsetY)); Tile tile = world.Data[x, y]; if (screenPosX >= -1 * world.TileWidth && screenPosX <= (viewPortWidth + 1) * world.TileWidth && screenPosY >= -1 * world.TileHeight && screenPosY <= (viewPortHeight + 1) * world.TileHeight) { Color color = (tile.TileType == TileType.Land ? Color.Green : Color.Blue); DrawRectangle(spriteBatch, new Rectangle(screenPosX, screenPosY, world.TileWidth, world.TileHeight), color); count++; } } } //Debug.WriteLine(count + " - " + (endCol-startCol)*(endRow-startRow)); spriteBatch.End(); lastCamOffSetX = camOffsetX; lastCamOffSetY = camOffsetY; } private void DrawRectangle(SpriteBatch spriteBatch, Rectangle coords, Color color) { var rect = new Texture2D(this.GraphicsDevice, 1, 1); rect.SetData(new[] { color }); spriteBatch.Draw(rect, coords, color); } 

目前,我只绘制屏幕/相机区域内的瓷砖。 我怎样才能提高脚本的效率?

你的DrawRectangle是瓶颈。 创建纹理是非常非常昂贵的操作。 首先创建纹理,然后使用它的引用来绘制纹理。

你正在创建一个新的纹理每一帧(甚至更糟,在Draw()而不是Update() )。

 private void DrawRectangle(SpriteBatch spriteBatch, Rectangle coords, Color color) { var rect = new Texture2D(this.GraphicsDevice, 1, 1); rect.SetData(new[] { color }); spriteBatch.Draw(rect, coords, color); } 

你可以创建一个更持久的variables来保存纹理,然后重复使用纹理。 由于您使用的颜色有两种方法。

使用一个sorting字典,并在遇到颜色时caching颜色,如果颜色尚不存在,只需创建一个新的纹理。 在这种情况下这可能有点矫枉过正。

更好的方法是创建纹理一次,并使用SpriteBatch来着色,您需要将纹理颜色设置为白色,可以这样做:

 Texture2D rect = ... // do your new texture here. 1x1 and colored Color.White. // Create this ONCE! not inside Update or Draw loops. public override void Draw(GameTime gameTime) { // Start of your drawing code Color color = GetColorLogicMethod(); // or your inline stuff above. spriteBatch.Draw(rect, coords, color); // This will tint the White 1x1 with the new color. // Rest of your drawing code } 

这样,昂贵的new Texture2D()Texture2D.SetData()只能做一次。 你的代码的其余部分看起来应该是相当不错的,因为它现在是你正在做的事情。