世界坐标是什么?为什么要把世界坐标转换为屏幕坐标?
说得非常好!这是游戏开发中非常核心的概念,理解它们对你后续开发至关重要。
什么是世界坐标 (World Coordinates)
想象一下你有一张巨大的世界地图铺在桌子上。
- 绝对位置:世界坐标就是这个巨大地图上的绝对坐标。比如,北京在这个地图上的某个固定位置 (X₁, Y₁),上海在另一个固定位置 (X₂, Y₂)。无论你怎么移动摄像机,北京和上海在世界地图上的坐标是永远不会变的。
- 全局系统:在你的游戏中,整个游戏世界(地图上的每一棵草、每一块砖、玩家、敌人)都有一个属于自己的、固定的世界坐标。
Vector2(500, 500)就是你为玩家设定的在这个世界中的绝对地址。 - 类比:就像地球上的经纬度。珠穆朗玛峰的经纬度是固定的,不会因为你人在北京还是纽约而改变。
什么是屏幕坐标 (Screen Coordinates)
现在,你拿一个照相机的取景框去看这张大地图。
- 相对位置:屏幕坐标是指在你的相机取景框(即游戏窗口)这个矩形区域内,某个物体的显示位置。
- 原点:屏幕坐标的原点
(0, 0)永远是你的屏幕左上角。 - 局部系统:它表示像素位置。比如
(100, 50)表示在屏幕上,距离左边界100像素,距离上边界50像素的点。 - 类比:你用手机拍照。故宫在你的手机照片里可能出现在中间偏左的位置,这个“中间偏左”就是屏幕坐标。但故宫在地球上的真实地理位置(世界坐标)并没有改变。
为什么需要转换?
因为你的游戏世界(地图)通常远大于你的屏幕窗口。你的屏幕只是一个“观察世界的窗口”。
核心目标:我们想让玩家这个“世界坐标点”始终出现在“屏幕坐标的中心点”上。
如何实现? 通过移动“摄像机”(也就是改变摄像机的世界坐标),并重新计算 everything 的屏幕位置。
转换公式:
屏幕坐标 = 世界坐标 - 摄像机坐标
举个例子:
-
初始状态:
- 玩家世界坐标:
(500, 500) - 摄像机世界坐标:我们想让玩家在屏幕中心,假设屏幕是 800x600,那么摄像机初始位置应设为:
cameraPosition = new Vector2(500 - 400, 500 - 300) = (100, 200) - 此时玩家的屏幕坐标 =
(500, 500) - (100, 200) = (400, 300)。正好在屏幕(800x600)的中心!
- 玩家世界坐标:
-
玩家向右移动了10像素:
- 玩家世界坐标变为:
(510, 500) - 我们希望玩家依然在屏幕中心,所以需要更新摄像机坐标:
cameraPosition.X = 510 - 400 = 110(摄像机也跟着向右移动了10) - 现在所有物体的屏幕坐标都需要重新计算:
- 玩家的屏幕坐标 =
(510, 500) - (110, 200) = (400, 300)(仍然在屏幕中心!) - 原本在世界坐标
(100, 200)的一棵树,它的屏幕坐标 =(100, 200) - (110, 200) = (-10, 0)。它的X坐标变成了负数,意味着它已经向左移动,离开了屏幕左侧边缘。
- 玩家的屏幕坐标 =
- 玩家世界坐标变为:
结论:为什么你的人物在左上角?
因为你很可能在绘制玩家时,直接使用了它的世界坐标 (500, 500),而没有减去摄像机的坐标。
-
错误做法:
spriteBatch.Draw(playerTexture,playerWorldPosition, Color.White);- 这相当于告诉电脑:“请把玩家图片永远画在世界的(500,500)位置”。因为屏幕原点(0,0)对应世界坐标的摄像机位置(比如(100,200)),世界坐标(500,500)这个点换算到屏幕上,就是一个很大的正数,很可能就把玩家画到右下角甚至屏幕外面去了。
-
正确做法:
spriteBatch.Draw(playerTexture,playerWorldPosition - cameraPosition, Color.White);- 这才是说:“请根据当前摄像机的位置,计算出玩家应该出现在屏幕的哪个地方,然后画在那里”。
检查你的绘制代码,确保在绘制玩家和绘制地图瓦片时,都进行了 世界坐标 - 摄像机坐标 这一步转换。一旦正确转换,你的玩家就会乖乖地待在屏幕中央了!
浙公网安备 33010602011771号