我有一张地图,其中包含5000 * 5000区域内的许多物体。 我的屏幕尺寸是800 * 600。
如何滚动我的地图,我不想左右移动所有物体,我希望“相机”移动,但不幸的是我没有找到任何移动它的方法。
由于
答案 0 :(得分: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();
如您所见,我们推导出视口的X
和Y
位置,以便将对象的世界位置置于视口中的Screen Coordinates
。这意味着,400, 800
中World Coordinates
处的小方块将在屏幕上100, 100
呈现给定我们此处的视口。
修改强>
虽然我同意“正确答案”的更改,但请记住,我在此处发布的内容在决定要处理哪些动画,哪些AI要更新等等时仍然非常有用...让相机和GPU制作单独的工作会阻止你知道哪些对象实际上在屏幕上!
答案 1 :(得分:7)
我认为您正在寻找transformMatrix
(this overload}的SpriteBatch.Begin
参数。
您说您不希望对象移动,但您希望相机移动。但是,在最低级别,在2D和3D渲染中,没有“相机”的概念。渲染始终发生在同一区域 - 您必须使用变换将顶点/精灵放入该区域。
如果您想要相机的效果,则必须通过向相反方向移动整个世界来实现它。
当然,您实际上存储移动的数据。您只需在渲染数据时应用偏移量。 Emartel的答案是你为每个精灵做的。但是使用矩阵更简洁,因为您不必为每个Draw
复制代码 - 您只需让GPU执行此操作。
完成一个示例:假设您希望将相机放置在(100,200)。为此,请将Matrix.CreateTranslation(-100, -200, 0)
传递给SpriteBatch.Begin
。
(根据emartel的回答,自己进行视锥体剔除可能是浪费时间,除非你的世界真的巨大。请参阅this answer以获得性能考虑的解释。 )