XNA 2D相机带任意缩放中心

5

我在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 我已尝试了所有对我有意义的组合,但完全卡住了。
2个回答

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;

帮了很大的忙!但是“CameraTranslaton.Y + msY”应该改成加号而不是减号 ;)另外,我将msX和msY更改为半个视口大小,以便在屏幕中心进行缩放。 - Jeremi Stadler
+/- 取决于投影矩阵.. ;) - Blau

3

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

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

希望这个方案可行,我只是在纸上尝试过,所以你可能需要稍微调整一下...但它应该至少能让你朝着正确的方向前进。以下是我只用X维度进行的支持数学计算。
光标=(1,1) 位置=(5,5) 放大: 位置应更接近光标 比例=2 放大前比例=1 位置X = 1 +(1/2)(5-1) 位置X = 1 + 0.5 * 4 位置X = 1 + 2 位置X = 3 缩小: 位置应远离光标 比例=1 缩小前比例=2 位置X = 1 +(2/1)(5-1) 位置X = 1 + 2 * 4 位置X = 1 + 8 位置X = 9

我只是想知道这是否是一个可行的解决方案。我目前有一个中心缩放实现,其中心是视口中心。我正在处理鼠标光标缩放。 - arc1880
在上面提到的代码示例中,您会在哪里定义zoom_center? zoom_center在哪里使用?我假设transmatrix在spriteBatch.Begin中使用? - arc1880
嗯,我忘记了确切的细节。我认为zoom_center不需要/没有被使用,因为它与pos的值完全相同。 - scottheckel
就 Vector2 pos 而言,它代表什么值?我有一个中心缩放,但我只能使用以下内容使其工作:transmatrix = Matrix.CreateTranslation(-offset.X, -offset.Y, 0) * Matrix.CreateScale(scale, scale, 1) * Matrix.CreateTranslation(offset.X, offset.Y, 0); - arc1880
我相信pos是当前相机位置。 - scottheckel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接