最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Three.js project, keeping camera centered on object in top down view - Stack Overflow

programmeradmin1浏览0评论

I'm writing a top down game with Three.js with single square movement like Frogger or other classic arcade games. I'm struggling with keeping the camera centered on the main character when it moves. Right now I'm using MapControls.js for key controls, but panning moves the camera by a certain number of pixels, and the character moves by setting it's position +-10 in z or x directions, and they don't always match up, so by the time you reach the end of the board in one direction, the character is almost off of the screen and the camera has moved too far. Can I attach the camera looking down the y-axis somehow while still keeping the pan effect on move?

I'm writing a top down game with Three.js with single square movement like Frogger or other classic arcade games. I'm struggling with keeping the camera centered on the main character when it moves. Right now I'm using MapControls.js for key controls, but panning moves the camera by a certain number of pixels, and the character moves by setting it's position +-10 in z or x directions, and they don't always match up, so by the time you reach the end of the board in one direction, the character is almost off of the screen and the camera has moved too far. Can I attach the camera looking down the y-axis somehow while still keeping the pan effect on move?

Share Improve this question edited Nov 26, 2018 at 2:36 enamoria 9162 gold badges11 silver badges29 bronze badges asked Nov 26, 2018 at 0:54 J. AustinJ. Austin 211 silver badge2 bronze badges 1
  • Not an answer: consider keeping the character and camera stationary, and pan the board, instead. You will not be using MapControls in that case. – WestLangley Commented Nov 26, 2018 at 3:15
Add a ment  | 

1 Answer 1

Reset to default 7

Why not just copy the player's x and z to the camera's? Or, copy a portion every frame.

 camera.position.lerp(player.position, 0.03);

Example. Run it, click on it, then use the arrow keys

'use strict';

/* global THREE */

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({canvas: canvas});

  const fov = 45;
  const aspect = 2;  // the canvas default
  const near = 0.1;
  const far = 100;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  // make the camera look down
  camera.position.set(0, 10, 0);
  camera.up.set(0, 0, -1);
  camera.lookAt(0, 0, 0);
  
  const scene = new THREE.Scene();
  scene.background = new THREE.Color('black');

  scene.add(new THREE.GridHelper(40, 40));
     
  let player;
  {
    const cubeSize = 1;
    const cubeGeo = new THREE.BoxBufferGeometry(cubeSize, cubeSize, cubeSize);
    const cubeMat = new THREE.MeshBasicMaterial({color: 'red'});
    player = new THREE.Mesh(cubeGeo, cubeMat);
    player.position.set(.5, .5, .5);
    scene.add(player);
  }

  function resizeRendererToDisplaySize(renderer) {
    const canvas = renderer.domElement;
    const width = canvas.clientWidth;
    const height = canvas.clientHeight;
    const needResize = canvas.width !== width || canvas.height !== height;
    if (needResize) {
      renderer.setSize(width, height, false);
    }
    return needResize;
  }

  function render() {

    if (resizeRendererToDisplaySize(renderer)) {
      const canvas = renderer.domElement;
      camera.aspect = canvas.clientWidth / canvas.clientHeight;
      camera.updateProjectionMatrix();
    }
    
    camera.position.lerp(player.position, 0.03);
    camera.position.y = 10; // keep the elevation;

    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }

  requestAnimationFrame(render);
  
  window.addEventListener('keydown', (e) => {
    e.preventDefault();
    switch (e.keyCode) {
      case 38: // up
        player.position.z -= 1;
        break;
      case 40: // down
        player.position.z += 1;
        break;
      case 37: // left
        player.position.x -= 1;
        break;
      case 39: // right
        player.position.x += 1;
        break;
    }
  });
}

main();
html, body {
  margin: 0;
  height: 100%;
}
#c {
  width: 100%;
  height: 100%;
  display: block;
}
<canvas id="c"></canvas>
<script src="https://threejsfundamentals/threejs/resources/threejs/r98/three.min.js"></script>

Increase the 0.03 to a large number to make the camera catch up faster.

发布评论

评论列表(0)

  1. 暂无评论