我有一张地图,其中包含许多物体,该区域的大小为5000*5000。 我的屏幕大小为800*600。
如何滚动我的地图,我不想将所有对象向左和向右移动,我希望“相机”移动,但不幸的是我没有找到任何移动它的方法。
谢谢
视口
首先,您需要创建相机的视口。对于2D游戏来说,您可以定义要开始渲染的左下位置,并使用您的屏幕分辨率来扩展它,在这种情况下为800x600
。
Rectangle viewportRect = new Rectangle(viewportX, viewportY, screenWidth, screenHeight);
300,700
时的外观示例(图仅供参考,仅用于让您更好地了解)。
可见性检查
现在,您想要找到与红色正方形
相交的每个精灵(可以理解为您的视口
)。这可以使用类似以下内容的代码完成(此代码未经测试,只是演示其可能的样式)。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();
X
和Y
位置,以便将对象的世界坐标带入视口内的屏幕坐标
中。 这意味着在此处给定的视口中,可能在400, 800
的世界坐标
中的小正方形将在屏幕上呈现为100, 100
。
编辑:
虽然我同意“正确答案”的更改,但请记住,在决定要处理哪些动画、更新哪些AI等方面,我在这里发布的内容仍然非常有用...让相机和GPU独自完成工作会阻止您知道实际上在屏幕上的是哪些对象!我认为你正在寻找SpriteBatch.Begin
的transformMatrix
参数(这个重载)。
你说你不想让对象移动,但是你希望相机移动。但是,在2D和3D渲染中,最底层都没有“相机”的概念。渲染总是发生在同一区域 - 你必须使用转换将你的顶点/精灵放置到该区域。
如果你想要相机的效果,你必须通过将整个世界向相反方向移动来实现它。
当然,你不需要实际存储移动后的数据。在渲染数据时,只需应用一个偏移量即可。Emartel的回答让你为每个精灵都这样做。然而,使用矩阵更加简洁,因为你不必为每个单独的Draw
复制代码 - 你可以让GPU来完成它。
最后举个例子:假设你想把相机放在(100, 200)处。为了实现这个效果,传递Matrix.CreateTranslation(-100, -200, 0)
到SpriteBatch.Begin
。
(自己执行视锥体裁剪,如Emartel的回答中所述,可能是浪费时间的,除非你的世界真的很大。请参见这个回答以了解性能方面的考虑。)