c# - 如何只绘制屏幕上可见的图 block ( Sprite )

标签 c# xna 2d monogame side-scroller

我正在尝试创建一个简单的 2d 滚动游戏作为 monogame (XNA) 中的学习练习。目前,我从一个文本文件加载图 block 信息,创建一个数组 (tiles[,]),其中一个图 block 对象存储有关图 block 写入位置的信息以及调用 draw 方法时应使用的纹理。目前我一次绘制数组中的每个图 block ,然后简单地更新图 block 的位置以将其移动到屏幕上。显然,一次绘制所有瓷砖有点麻烦,我认为如果我只绘制屏幕上可见的瓷砖会更好,这样当瓷砖在屏幕上移动时,会绘制更多瓷砖。我不确定如何最好地做到这一点?对于如何判断应该绘制哪些图 block ,我有点迷茫。 任何帮助将不胜感激。 这是关卡类中的绘制和更新方法 - 它只是调用 Tile 类中的方法来绘制/更新位置。

    /// <summary>
    /// Draws each individual tile in the level.
    /// </summary>
    private void DrawTiles(SpriteBatch spriteBatch)
    {
        // For each tile position
        for (int y = 0; y < Height; ++y)
        {
            for (int x = 0; x < Width; ++x)
            {
               tiles[x, y].Draw(spriteBatch);
            }
        }
    }



    public void Update(GameTime gameTime, int scrollSpeed, ScrollDirection direction)
    {
        // Update the positions of each of the Background sprites
        foreach (Tile tile in tiles)
        {
            tile.Update(gameTime, new Vector2(0, scrollSpeed), scrollDirection);
        }
    }
}

提前致谢

我现在尝试使用从图形设备传递的视口(viewport),仅循环遍历屏幕上可见的图 block 进行绘制。我基本上尝试在尝试绘制之前通过将屏幕高度除以瓷砖高度和宽度相同来获得屏幕上可以容纳的瓷砖数量。这工作得很好,它绘制了视点上所有可见的图 block 。

唯一的问题是它不再绘制任何从视口(viewport)外开始的图 block ,因此即使在更新中图 block 被移入视口(viewport)中,它们也不会被绘制,因为循环使用它们的原始位置。不过,我想不出一种无需遍历所有图 block 即可解决此问题的方法 :-(

由于关卡可能很大,因此循环遍历所有图 block 以仅绘制屏幕中的内容会非常低效。

如有任何建议,我们将不胜感激。

这是更新后的抽奖:

    private void DrawTiles(SpriteBatch spriteBatch)
    {
        float tileWidth = 40;
        float tileHeight = 32;


        for (int y = 0; y < (int)Math.Ceiling(mViewport.Height / tileHeight); ++y)
        {

           for (int x = 0; x < (int)Math.Ceiling(mViewport.Width / tileWidth); ++x)
            {
                tiles[x, y].Draw(spriteBatch);
            }
        }
    }

最佳答案

您需要有关相机的信息。如果您知道相机的中心位置以及屏幕尺寸,您可以进行如下绘制调用:

private void DrawTiles(SpriteBatch spriteBatch)
{
    // For each tile position
    for (int y = cameraOffset.Y - screenHeight / 2; y < cameraOffset.Y + (int)Math.Ceiling(screenHeight / 2); ++y)
    {
        for (int x = cameraOffset.X - screenWidth / 2; x < cameraOffset.X + (int)Math.Ceiling(screenWidth / 2); ++x)
        {
           tiles[x, y].Draw(spriteBatch);
        }
    }
}

我使用 Math.Ceiling 的原因是为了覆盖屏幕上的部分瓷砖。另一边的 Math.Floor 是隐含的,因为它是整数除法。

请注意,这假定 cameraOffset、screenWidth 和 screenHeight 以图 block 为单位。如果不是,请适本地转换它们。

关于c# - 如何只绘制屏幕上可见的图 block ( Sprite ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16884509/

相关文章:

c# - 如何修复错误 "Only one usage of each socket address (protocol/network address/port) is normally permitted"?

c# - 以逗号分隔数以千计 asp.net

c# - List<T> 的手写映射器

c# - 无法在 XNA 中隐式转换类型

svg - 将带有滤镜效果的 SVG 渲染为 PNG

c# - 在设计模式下锁定 .NET 自定义控件中的高度调整大小

visual-studio - 如何在 Visual Studio 11 Beta 中使用 XNA 项目?

C#:这里需要什么 `using` 语句?

java - public static int getCoins(int[][] map, int row, int col) 方法

python - Pygame,按轴旋转图像