event.movement返回奇数值

时间:2018-01-10 03:34:00

标签: javascript events pointerlock

我一直在玩webGL,我已经达到了一个点,我可以用非常可怜的图形制作小型三维游戏(它更像是现在的概念/功能证明)。对于三维体验,可以无限地无缝地向任何方向移动鼠标以旋转第一人称相机。 Pointerlock允许我锁定和隐藏光标位置,这是非常有帮助的,但是我需要找到另一种跟踪鼠标移动的方法。在我的研究中,event.movementXevent.movementY似乎是标准,但我经常在鼠标移动的相反方向上获得大的移动(通常在500和583之间)。我用大量鼠标和触控板测试了这一点并遇到了同样的现象。

以下是我的相关事件监听器:

document.addEventListener("mousemove", function(event) {
   xMovement += event.movementX; 
   yMovement += event.movementY; 
   console.log(event.movementX)
}, false);

document.addEventListener("pointerlockchange", function(event) {
   if(pointerLockEnabled) pointerLockEnabled = false; 
   else pointerLockEnabled = true; 
   xMovement = 0; yMovement = 0; 
} , false);

相关的渲染循环代码:

function render() {
   if(pointerLockEnabled) {
       camera.rotation.y = -xMovement / 1000;
       camera.rotation.x = -yMovement / 1000;
       if(rightKey && !leftKey) {
          camera.position.x += 10 * Math.cos(camera.rotation.y);
          camera.position.z -= 10 * Math.sin(camera.rotation.y);
       }
       else if(leftKey && !rightKey) {
          camera.position.x -= 10 * Math.cos(camera.rotation.y);
          camera.position.z += 10 * Math.sin(camera.rotation.y);
       }
       if(upKey&& !downKey) {
          camera.position.z -= 10 * Math.cos(camera.rotation.y);
          camera.position.x -= 10 * Math.sin(camera.rotation.y);
       }
       else if(downKey && !upKey) {
          camera.position.z += 10 * Math.cos(camera.rotation.y);
          camera.position.x += 10 * Math.sin(camera.rotation.y);
       }
   }
}

但我的控制台出现如下:

console capture

我添加条件来改变xMovement以防止相机角度大幅度转动,但我仍然留下非常讨厌的动作。有没有想法修补或替换更无缝的界面运动?

2 个答案:

答案 0 :(得分:1)

如果你以某种方式限制你的mousemove事件可能会有所帮助。例如lodash throttle版本:

function handleMouseMove(event) {
   xMovement += event.movementX; 
   yMovement += event.movementY; 
   console.log(event.movementX)
}
var throttledHandleMouseMove = _.throttle(handleMouseMove, 75);
document.addEventListener("mousemove", throttledHandleMouseMove, false);

使用这种方法handleMouseMove每75ms不会执行1次以上。

答案 1 :(得分:0)

我遇到了同样的问题,但对我而言,不良价值始终与运动方向相同。我发现,如果我用上一个值替换大于50的任何值,则将获得非常好的准确性。唯一的问题是当错误值在30-49范围内时,但是我不想取消这些错误值,以防用户实际上以太快的速度移动鼠标或鼠标的轮询速度很差。可以使用一些趋势线比较来平滑它们,但是如果您不需要太多的精度,那就很好了:

const movement = {X: 0, Y: 0};
const lastMovement = {X: 0, Y: 0};
function onMouseMove(evt) {
  if (checkPointerLock()) {
    ['X', 'Y'].forEach(axis => {
      const checkValue = evt['movement' + axis] || evt['mozMovement' + axis]|| 0;
      //ignore >=50. probably erroneous. smooth to last value
      if (Math.abs(checkValue) < 50) {
        lastMovement[axis] = checkValue;
      }
      movement[axis] = lastMovement[axis];
    });

    yaw += movement.X * -0.001 * data.sensitivityX;
    pitch += movement.Y * (data.invertY ? .001 : -.001) * data.sensitivityY;
    pitch = Math.max(-Math.PI/2, Math.min(Math.PI/2, pitch));
  }
}