Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling Camera-Style Mouse Movement in Javascript (enabling continuous mouse movement)

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

  1. 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).

  2. 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?

like image 410
Will Avatar asked Jul 26 '11 22:07

Will


3 Answers

For anybody that still interested in achieving this, it is now somewhat available.

Using:

document.addEventListener('pointerlockchange', changeCallback, false);

see example http://www.html5rocks.com/en/tutorials/pointerlock/intro/

like image 164
AlexMorley-Finch Avatar answered Oct 17 '22 07:10

AlexMorley-Finch


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.

  • Chromium Bug: http://code.google.com/p/chromium/issues/detail?id=72754
  • Firefox Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=633602
  • W3C Mail list: http://www.w3.org/Bugs/Public/show_bug.cgi?id=9557
  • Draft proposal: https://docs.google.com/document/d/1uV4uDVIe9-8XdVndW8nNGWBfqn9ieeop-5TRfScOG_o/edit?hl=es&authkey=CM-dw7QG

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)

like image 31
Chiguireitor Avatar answered Oct 17 '22 09:10

Chiguireitor


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.

like image 1
Tom Avatar answered Oct 17 '22 08:10

Tom