具有任意变焦中心的 XNA 2d 相机

发布于 2025-01-07 13:31:17 字数 936 浏览 1 评论 0原文

我在 XNA 中有一个工作 2D 相机,具有以下功能:

ms = Mouse.GetState();
msv = new Vector2(ms.X, ms.Y);  //screenspace mouse vecor
pos = new Vector2(0, 0); //camera center of view
zoom_center = cursor; //I would like to be able to define the zoom center in world coords
offset = new Vector2(scrnwidth / 2, scrnheight / 2);
transmatrix = Matrix.CreateTranslation(-pos.X, -pos.Y, 0)
    * Matrix.CreateScale(scale, scale, 1)
    * Matrix.CreateTranslation(offset.X, offset.Y, 0);
inverse = Matrix.Invert(transmatrix);
cursor = Vector2.Transform(msv, inverse);  //the mouse position in world coords      

我可以移动相机位置并更改缩放级别(为了简洁起见,我没有在此处粘贴其他代码)。相机始终围绕屏幕中心进行缩放,但我希望能够围绕任意缩放点(本例中为光标)进行缩放,例如独立游戏 Dyson http://www.youtube.com/watch?v=YiwjjCMqnpg&feature=player_detailpage#t=144s

我已经尝试了所有对我有意义的组合,但我完全卡住了。

I have a working 2D camera in XNA with these guts:

ms = Mouse.GetState();
msv = new Vector2(ms.X, ms.Y);  //screenspace mouse vecor
pos = new Vector2(0, 0); //camera center of view
zoom_center = cursor; //I would like to be able to define the zoom center in world coords
offset = new Vector2(scrnwidth / 2, scrnheight / 2);
transmatrix = Matrix.CreateTranslation(-pos.X, -pos.Y, 0)
    * Matrix.CreateScale(scale, scale, 1)
    * Matrix.CreateTranslation(offset.X, offset.Y, 0);
inverse = Matrix.Invert(transmatrix);
cursor = Vector2.Transform(msv, inverse);  //the mouse position in world coords      

I can move the camera position around and change the zoom level (with other code that I have not pasted here for brevity). The camera always zooms around the center of the screen, but I would like to be able to zoom about an arbitrary zoom point (the cursor in this case), like the indie game dyson http://www.youtube.com/watch?v=YiwjjCMqnpg&feature=player_detailpage#t=144s

I have tried all the combinations that make sense to me, but am completely stuck.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

任谁 2025-01-14 13:31:17

我已经完成了,这是代码和解释:

获取相机空间中的鼠标坐标:

 msx = Mouse.X - Viewport.Width/2;
 msy = Mouse.Y - Viewport.Height/2;

获取相机空间中相机到鼠标的距离

 var width = CameraTranslation.X - msX;
 var height = CameraTranslaton.Y + msY;

获取新缩放产生的偏移,然后将其减去相机位置

 CameraTranslation.X -= width * (1-newZoom/_zoom);
 CameraTranslation.Y -= height * (1-newZoom/_zoom);

 _zoom = newZoom;

I have done it, this is the code and the explanations:

Get the mouse coods in camera space:

 msx = Mouse.X - Viewport.Width/2;
 msy = Mouse.Y - Viewport.Height/2;

Get distances from camera to mouse in camera space

 var width = CameraTranslation.X - msX;
 var height = CameraTranslaton.Y + msY;

Get the offset produced by the new zoom and then substract it to camera position

 CameraTranslation.X -= width * (1-newZoom/_zoom);
 CameraTranslation.Y -= height * (1-newZoom/_zoom);

 _zoom = newZoom;
起风了 2025-01-14 13:31:17

实际上,您不会围绕光标进行缩放。您将缩放在先前缩放中心和光标之间的线上定义的点。当您放大得越来越远时,该点将接近光标位置。此外,如果缩放增量更大,它应该更快地移动到光标。您的 zoom_center 应该定义为类似这样的内容(注意:我引入了新变量并添加了一行,您可以在其中将 pos 重新分配给 Zoom_center)。

zoom_center = pos = cursor + (scale_prior_to_zoom/scale) * (pos - cursor);

希望这有效,因为我只在纸上尝试过,所以你可能需要稍微改变一下......但它至少应该让你指向正确的方向。这是我仅使用 X 维度所做的支持数学计算。

光标=(1,1)

位置=(5,5)

放大
位置应该更靠近光标

比例 = 2scale_prior_to_zoom=1

posX = 1 + (1/2)(5 - 1)

posX = 1 + 0.5 * 4

posX = 1 + 2

posX = 3

缩小
位置应该离光标更远

缩放 = 1scale_prior_to_zoom = 2

posX = 1 + (2/1)(5 - 1)

posX = 1 + 2 * 4

posX = 1 + 8

posX = 9

You actually won't be zooming around the cursor. You'll be zooming on a point defined on the line between your previous zoom center and the cursor. As you zoom in further and further that point will approach the cursor position. Also it should move to the cursor faster if it's a larger zoom increase. You're zoom_center should be defined as something like this (Note: I introduced new variables and added a line where you reassign pos to zoom_center).

zoom_center = pos = cursor + (scale_prior_to_zoom/scale) * (pos - cursor);

Hopefully this works as I only tried on paper, so you may need to change this a bit... but it should get you at least pointed in the right direction. Here's the backing math that I did with just the X dimension.

cursor = (1,1)

pos = (5,5)

Zooming in
Position should be closer to cursor

scale = 2 scale_prior_to_zoom= 1

posX = 1 + (1/2)(5 - 1)

posX = 1 + 0.5 * 4

posX = 1 + 2

posX = 3

Zooming Out
Position should be farther from the cursor

scale = 1 scale_prior_to_zoom = 2

posX = 1 + (2/1)(5 - 1)

posX = 1 + 2 * 4

posX = 1 + 8

posX = 9

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文