4

I have a map, containing many objects in an area sized 5000*5000. my screen size is 800*600.

how can i scroll my map, i don't want to move all my objects left and right, i want the "camera" to move, But unfortunately i didn't found any way to move it.

Thanks

4

2 回答 2

7

我认为您正在寻找(此重载)的transformMatrix参数。SpriteBatch.Begin

你说你不希望物体移动,但你希望相机移动。但是,在最低级别,无论是 2D 还是 3D 渲染,都没有“相机”的概念。渲染总是发生在同一个区域 - 你必须使用转换将你的顶点/精灵放置到那个区域。

如果你想要一个相机的效果,你必须通过将整个世界向相反的方向移动来实现它。

当然,您实际上并没有存储移动的数据。您只需在渲染数据时应用偏移量。Emartel 的回答让你为每个精灵都这样做。但是使用矩阵更简洁,因为您不必为每个单独的代码复制代码Draw- 您只需让 GPU 完成即可。

以一个例子结束:假设您希望将相机放置在 (100, 200)。为此,请传递Matrix.CreateTranslation(-100, -200, 0)SpriteBatch.Begin.

(根据 emartel 的回答,自己执行截锥剔除可能是浪费时间,除非您的世界真的很大。请参阅此答案以了解性能注意事项的解释。)

于 2012-12-10T08:03:36.870 回答
7

视口

您首先创建相机视口。在 2D 游戏的情况下,它可以像定义要开始渲染的左下角位置一样简单,并在您的情况下使用屏幕分辨率扩展它800x600

Rectangle viewportRect = new Rectangle(viewportX, viewportY, screenWidth, screenHeight);

这是一个示例,如果您的相机被偏移,它会是什么样子300,700(该图非常近似,只是为了给您一个更好的主意)

视口

能见度检查

现在,您要查找与 相交的每个精灵,red square可以理解为您的Viewport. 这可以用类似的东西来完成(这是未经测试的代码,只是它可能看起来的示例)

List<GameObject> objectsToBeRendered = new List<GameObject>();
foreach(GameObject obj in allGameObjects)
{
    Rectangle objectBounds = new Rectangle(obj.X, obj.Y, obj.Width, obj.Height);
    if(viewportRect.IntersectsWith(objectBounds))
    {
        objectsToBeRendered.Add(obj);
    }
}

这是它在图形上的样子,绿色精灵是添加到objectsToBeRendered. 如果您想在渲染它们之前对它们Back进行排序,将对象添加到单独的列表中会很容易!Front

可见的

渲染

现在我们已经找到了哪些对象相交,我们需要弄清楚屏幕上的哪个位置会结束。

spriteBatch.Begin();
foreach(GameObject obj in objectsToBeRendered)
{
    Vector2 pos = new Vector2(obj.X - viewportX, obj.Y - viewportY);
    spriteBatch.Draw(obj.GetTexture(), pos, Color.White);
}
spriteBatch.End();

如您所见,我们推导出视口的XY位置以将对象的世界位置带入Screen Coordinates视口内。这意味着在给定我们这里的视口的情况下,可能位于的小方块将在屏幕上400, 800呈现World Coordinates100, 100

编辑:

虽然我同意“正确答案”的更改,但请记住,我在此处发布的内容在决定要处理哪些动画、要更新哪些 AI 等时仍然非常有用……让相机和 GPU 单独工作阻止您知道哪些对象实际上在屏幕上!

于 2012-12-08T21:56:15.420 回答