Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

First person shooter controls with three.js

I'm completely new to three.js and 3D. I'm trying to make a really simple first person shooter. I found heaps of examples but they all look really complicated. I want to understand the code before I use it. What I am having trouble with is the camera rotation. Everything else is fine. My approach doesn't quite work. It seems to be rotating on the z axis even though I'm setting that to 0. Here's all my code (125 lines)

var width    = window.innerWidth, height = window.innerHeight,
    scene    = new THREE.Scene(),
    camera   = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000),
    renderer = new THREE.WebGLRenderer(),
    mouse = {
      x: 0,
      y: 0,
      movedThisFrame: false
    };
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);

var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({
  color: 0x00ff00
});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
var floorgeometry = new THREE.BoxGeometry(100,0.1,100);
var floormaterial = new THREE.MeshBasicMaterial({
  color: 0xff0000
});
var floor = new THREE.Mesh(floorgeometry, floormaterial);
floor.position.y = -1;
scene.add(floor);

var keys = {
  w: false,
  a: false,
  s: false,
  d: false
};

camera.position.z = 5;

function radDeg(radians) {
  return radians * 180 / Math.PI;
}

function degRad(degrees) {
  return degrees * Math.PI / 180;
}

function rotateCam() {
  if (!mouse.movedThisFrame) {
    mouse.x = 0;
    mouse.y = 0;
  }
  /*

  What am I doing wrong here?

  */
  camera.rotation.x -= mouse.y * 0.001;
  camera.rotation.y -= mouse.x * 0.001;
  camera.rotation.z = 0;

  mouse.movedThisFrame = false;
}

function moveCam() {
  var rotation = camera.rotation.y % (Math.PI * 2), motion = [0,0];
  if (keys.w) {
    motion[0] += 0.1 * Math.cos(rotation);
    motion[1] += 0.1 * Math.sin(rotation);
  }
  if (keys.a) {
    motion[0] += 0.1 * Math.cos(rotation + degRad(90));
    motion[1] += 0.1 * Math.sin(rotation + degRad(90));
  }
  if (keys.s) {
    motion[0] += 0.1 * Math.cos(rotation - degRad(180));
    motion[1] += 0.1 * Math.sin(rotation - degRad(180));
  }
  if (keys.d) {
    motion[0] += 0.1 * Math.cos(rotation - degRad(90));
    motion[1] += 0.1 * Math.sin(rotation - degRad(90));
  }

  camera.position.z -= motion[0];
  camera.position.x -= motion[1];
}

window.onload = function() {
  renderer.domElement.onclick = function() {
    console.log('requested pointer lock');
    renderer.domElement.requestPointerLock();
  };

  renderer.domElement.onmousemove = function(e) {
    if (!mouse.movedThisFrame) {
      mouse.x = e.movementX;
      mouse.y = e.movementY;
      mouse.movedThisFrame = true;
    }
  };

  document.onkeydown = function(e) {
    var char = String.fromCharCode(e.keyCode);
    if (char == 'W')
      keys.w = true;
    else if (char == 'A')
      keys.a = true;
    else if (char == 'S')
      keys.s = true;
    else if (char == 'D')
      keys.d = true;
  };

  document.onkeyup = function(e) {
    var char = String.fromCharCode(e.keyCode);
    if (char == 'W')
      keys.w = false;
    else if (char == 'A')
      keys.a = false;
    else if (char == 'S')
      keys.s = false;
    else if (char == 'D')
      keys.d = false;
  };

  function animate() {
    requestAnimationFrame(animate);
    rotateCam();
    moveCam();
    renderer.render(scene, camera);
  }
  animate();
};

The problem is in the rotateCam function. It doesn't quite work and I don't really know why.

I also tried using the code on this question but it didn't work.

like image 827
Sneaky Turtle Avatar asked Apr 10 '16 01:04

Sneaky Turtle


1 Answers

First person controls are more complicated than you may think. Even if you figure out your angle math, when the pointer is not locked, the mouse hits the window edge and turning stops.

I suggest you start with the pointer lock example (http://threejs.org/examples/#misc_controls_pointerlock) which is an example of first person controls for 3js.

like image 109
fluffybunny Avatar answered Sep 23 '22 16:09

fluffybunny