如何在XNA(2D)中制作滚动地图?

Oop*_*ser 4 c# xna

我有一张地图,包含5000*5000区域内的许多物体.我的屏幕尺寸是800*600.

我怎么能滚动我的地图,我不想左右移动我的所有物体,我希望"相机"移动,但不幸的是我没有找到任何移动它的方法.

谢谢

ema*_*tel 7

视口

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

Rectangle viewportRect = new Rectangle(viewportX, viewportY, screenWidth, screenHeight);
Run Code Online (Sandbox Code Playgroud)

这是一个例子,说明如果相机被偏移,你的相机会是什么样子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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是图形上看起来的样子,绿色的精灵是添加的objectsToBeRendered.将对象添加到单独的列表可以轻松BackFront在渲染它们之前对它们进行排序!

可见

渲染

现在我们发现了哪些物体相交,我们需要弄清楚屏幕上的最终位置.

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();
Run Code Online (Sandbox Code Playgroud)

如您所见,我们推导出视口的位置XY位置,以将对象的世界位置Screen Coordinates置于视口中.这意味着,这可能是在小方400, 800World Coordinates将在呈现100, 100给我们这里有视在屏幕上.

编辑:

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


And*_*ell 7

我认为你正在寻找transformMatrix参数SpriteBatch.Begin(这个重载).

你说你不希望物体移动,但你想让相机移动.但是,在最低级别,在2D和3D渲染中,没有"相机"的概念.渲染始终在同一区域中进行 - 您必须使用变换将顶点/精灵放置到该区域中.

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

当然,您实际上并不存储移动的数据.您只需在渲染数据时应用偏移量.Emartel的答案是你为每个精灵做的.但是使用矩阵更简洁,因为您不必为每个单元复制代码Draw- 您只需让GPU执行此操作即可.

以示例结束:假设您希望将相机放置在(100,200).要实现这一目标,请Matrix.CreateTranslation(-100, -200, 0)转到SpriteBatch.Begin.

(根据emartel的回答,自己进行截头剔除可能是浪费时间,除非你的世界非常庞大.请参阅这个答案以获得性能考虑的解释.)