缩放到鼠标位置(例如Google地图)

12

我写了一个自制的view_port类,用于2D策略游戏。使用箭头键进行平移和鼠标滚轮进行缩放都能正常工作,但是我希望视图也能像Google Maps 或Supreme Commander一样,根据光标位置回到初始位置。

我会省略掉缩放实现的具体细节以及我使用的编程语言:这些都不重要。重要的是缩放函数,它修改代表视图的矩形结构(x,y,w,h)。目前代码看起来是这样的:

void zoom(float delta, float mouse_x, float mouse_y)
{
    zoom += delta;
    view.w = window.w/zoom;
    view.h = window.h/zoom;  
    // view.x = ???
    // view.y = ???
}

在有人建议之前,以下方法不会奏效:

view.x = mouse_x - view.w/2;
view.y = mouse_y - view.h/2;

这张图片说明了,当我试图放大笑脸时的原因:

http://oi43.tinypic.com/16m21au.jpg

你可以看到,当鼠标下方的对象位于屏幕中心时,它就不再在鼠标下方,因此我们停止向其缩放!

如果你对数学有一定的了解(你需要),欢迎提供任何帮助!

2个回答

7

我通过长时间的思考,终于找到了解决方案,这里分享一下算法以便其他需要的人可以使用。

Vect2f mouse_true(mouse_position.x/zoom + view.x, mouse_position.y/zoom + view.y);
Vect2f mouse_relative(window_size.x/mouse_pos.x, window_size.y/mouse_pos.y);   
view.x = mouse_true.x - view.w/mouse_relative.x;
view.y = mouse_true.y - view.h/mouse_relative.y;

这确保了鼠标下方的对象会一直处于鼠标下方。你可以在github上查看代码,我还为youtube制作了一个展示演示。


4
请您详细说明这些变量代表什么意思? - WebF0x
这对我没有用。只有当鼠标的x和y坐标为零时才有效。 - Derk Jan Speelman

1
在我的概念中,有一个相机和一个屏幕。 相机是移动的部分,屏幕是可伸缩的部分。
我制作了一个包括实时演示的示例脚本。 为了保持简单,问题被简化为只有一个维度。 https://www.khanacademy.org/cs/cam-positioning/4772921545326592
var a = (mouse.x + camera.x) / zoom;

// now increase the zoom e.g.: like that:
zoom = zoom + 1;

var newPosition = a * zoom - mouse.x;

camera.setX(newPosition);
screen.setWidth(originalWidth * zoom);

如果您需要一个 2D 示例,您可以简单地为高度和 y 坐标添加相同的代码。


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