在 Javascript 中处理相机式鼠标移动(启用连续鼠标移动)
想法: 我正在创建一个简单的 WebGL 脚本(使用 mrdoob 的精彩 Three.js),允许用户在对象世界中控制相机。该相机应该模拟传统的第一人称射击相机(例如,参考《军团要塞 2》)。也就是说,只有鼠标移动时相机才会移动。
问题:在 Javascript 中,检测鼠标移动的唯一方法是光标本身是否移动。相比之下,FPS 游戏不显示光标——它们仅根据鼠标本身的移动方式来移动摄像机。因此,您可以在鼠标垫上向任何方向移动鼠标,并且它始终有效。
但在浏览器上,由于相机移动是基于光标的,因此您只能移动那么远。当光标碰到屏幕边缘时,用户无法再朝该方向看(例如,将鼠标移动到屏幕的左边缘,就无法再向左看)。
解决方案:我想到了两种解决方案,但我都不知道如何实施。
- 鼠标移动后,JavaScript 将其重置到屏幕中央。这样,每次鼠标移动后,玩家都可以自由地再次向任何方向移动。 ,根据我所做的研究,Javascript 无法控制用户鼠标的位置(这是可以理解的,因为这在恶意网站上会造成无与伦比的麻烦)。
或者,鼠标“环绕”屏幕。这意味着,当用户到达屏幕的一个边缘时,鼠标将继续移动到屏幕的另一侧。 (请参阅:http://www.digicowsoftware.com/detail?_app=Wraparound)但是,似乎这也不是 javascript 的固有功能,而只是第三方程序可以解决的问题。
那么,这个问题有意义吗?如果是这样,有什么方法可以实现上述解决方案,或者我还缺少另一种解决方案吗?
The idea: I'm creating a simple WebGL script (using mrdoob's wonderful three.js) that allows the user to control a camera in a world of objects. The camera is supposed to simulate traditional first person shooter cameras (reference Team Fortress 2, for example). That is, the camera moves only when the mouse moves.
The issue: in Javascript, the only way to detect mouse movement is if the cursor itself moves. By comparison, FPS games don't show the cursor -- they only base the movement of the camera off of how the mouse itself moves. So, you can move your mouse all over the mousepad in any direction and it always works.
On a browser though, since camera movement is based on the cursor, you can't move but so far. When the cursor hits the edge of the screen, the user is unable to look any further in that direction (e.g. you move your mouse to the left edge of the screen, you can't look left any more).
The solution: I've thought of two solutions, but neither of which I know how to implement. Either
After the mouse is moved, the javascript resets it to the center of the screen. That way, after every mouse movement the player is free to again move in any direction. The issue with this is that, based on the research I've done, Javascript is unable to control the position of the user's mouse (understandably, as it would be an incomparable nuisance on malignant sites).
Or, the mouse "wraps" around the screen. Meaning, when the user reaches one edge of the screen, the mouse would simply continue on to the other side of the screen. (see: http://www.digicowsoftware.com/detail?_app=Wraparound) However, it appears that this too is not an inherent capability of javascript, but instead is only something a third party program could solve.
So, does the problem make sense? If so, is there any way I can implement the above solutions, or is there another one I'm missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对于任何仍然有兴趣实现这一目标的人来说,现在已经可以实现了。
使用:
参见示例 http://www.html5rocks.com/en/tutorials/pointerlock/intro/
For anybody that still interested in achieving this, it is now somewhat available.
Using:
see example http://www.html5rocks.com/en/tutorials/pointerlock/intro/
全球社区目前正在制定一份规范草案来解决这个问题。你所说的就是“鼠标锁定”。我在该标准的第一阶段做了一些工作,以帮助列出所需的内容。请对这些问题进行投票并订阅指定的邮件列表,以便我们所有人尽快纠正此问题。
但是,仍然有一种方法可以实现你的目标(这是我发现的另一种方式):一个控制鼠标的本机插件。
(我也在制作一款FPS游戏,但由于这个限制目前不会发布)
The worldwide community is currently working on a draft spec to solve this issue. What you're stating is called "mouse-locking". I've worked a little on the first phase of this standard to help lay out what's needed. Please, vote for these issues and subscribe to the indicated mail lists in order for all of us to get this issue corrected ASAP.
However, there's still a way you can achieve your objective (which is the other way i found): A native plugin that takes control of the mouse.
(I'm making a game too which is a FPS but currently won't be released due to this limitation)
你对这一切都是对的。基于标准的网络技术不会为您提供您想要的鼠标捕获功能。
也就是说:您也许能够制作(或找到)一个特殊的 SWF,它可以收集鼠标移动数据并将其传递给 JavaScript。尽管您可以在鼠标捕获处于活动状态时使用 CSS 隐藏光标,但它不会限制光标移动。但是,即使光标已到达屏幕的左边缘,它也可能能够继续触发“向左移动鼠标”事件。
当光标位于视口之外(即浏览器镶边上方)时,任何此类 SWF 都可能无法捕获移动。
You're right about all of this. Standards-based web tech isn't going to give you mouse capturing like you want.
That said: you might be able to craft (or find) a special SWF that can collect mouse movement data and pass that to javascript. It won't constrain cursor movement, although you can use CSS to conceal the cursor while mouse capturing is active. But it might be able to e.g. continue firing "move mouse left" events even when the cursor has reached the left edge of the screen.
Any such SWF will probably fail to capture movement when the cursor is outside the viewport i.e. over the browser chrome.
鉴于在 HTML5/Javascript 中显然不可能做到这一点,那么这个变体怎么样:将鼠标位置(而不是鼠标移动)视为代表转动速率。
因此,如果鼠标距离中心左侧超过一定阈值,则相机向左转;鼠标越左,相机转动得越快。要停止转动,玩家将鼠标移回中心。
对我来说,这是一个烦人的用户界面,至少在最初是这样,但也许玩家会习惯它。由于我们没有任何完美的解决方案,因此可能值得尝试。您可以通过允许箭头键像许多 FPS 中的方式工作来缓解这个问题,按下箭头键时旋转相机。
Given that it's apparently not possible to do this as such in HTML5/Javascript, what about this variant: treat the mouse position (not mouse movement) as representing the rate of turning.
So if the mouse is more than a certain threshold left of the center, the camera turns left; the farther left the mouse is, the faster the camera turns. To stop turning, the player moves the mouse back toward the center.
To me this is an annoying UI, at least initially, but maybe the player would get used to it. Since we don't have any perfect solutions, it may be worth trying. You can mitigate the problem by allowing the arrow keys to work the way they do in many FPSes, rotating the camera when they are pressed down.