我在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
我可以移动相机位置并更改缩放级别(为了简洁,我还没有粘贴其他代码)。相机总是围绕屏幕中心放大,但我希望能够缩放任意缩放点(在这种情况下是光标),就像独立游戏中的运动员http://www.youtube.com/watch?v=YiwjjCMqnpg&feature=player_detailpage#t=144s
我已经尝试了所有对我有意义的组合,但我完全陷入困境。
答案 0 :(得分:4)
我已经完成了,这是代码和解释:
在相机空间中获取鼠标:
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;
答案 1 :(得分:2)
实际上你不会在光标周围缩放。您将放大在前一个缩放中心和光标之间的线上定义的点。当您进一步放大时,该点将接近光标位置。如果变焦幅度增大,它也应该更快地移动到光标。你应该将zoom_center
定义为类似的东西(注意:我引入了新变量并添加了一行,你将pos重新分配给zoom_center)。
zoom_center = pos = cursor + (scale_prior_to_zoom/scale) * (pos - cursor);
希望这可行,因为我只在纸上试过,所以你可能需要稍微改变一下......但它应该让你至少指向正确的方向。这是我用X维度做的支持数学。
cursor =(1,1)
pos =(5,5)
放大 位置应该更靠近光标
scale = 2 scale_prior_to_zoom = 1
posX = 1 +(1/2)(5 - 1)
posX = 1 + 0.5 * 4
posX = 1 + 2
posX = 3
缩小 位置应远离光标
scale = 1 scale_prior_to_zoom = 2
posX = 1 +(2/1)(5 - 1)
posX = 1 + 2 * 4
posX = 1 + 8
posX = 9