第一人称WASD控件

时间:2019-07-16 20:33:18

标签: javascript 3d html5-canvas controls game-physics

我目前正在开发3D游戏,我想使用 wasd 键实现一种第一人称控制。

我下面的代码段包括速度,位置和旋转,其中旋转代表0 2*Math.PI之间的值。

我的问题是如何更新代码以根据当前旋转使用 w 键“直线”移动, d 键无论在哪里都返回我要面对,依此类推。

我相信您知道我的问题是什么-我需要某种方法来实现加速

任何帮助将不胜感激。

let speed = 0.01,
  maxSpeed = 0.01,
  friction = 0.91

let position = {
    x: 0,
    y: 0,
    z: 0
  },
  velocity = {
    x: 0,
    y: 0,
    z: 0
  },
  rotation = 0;


let update = () => {
  if (keyPressed("w") && velocity.z > -maxSpeed) velocity.z -= speed
  if (keyPressed("s") && velocity.z < maxSpeed) velocity.z += speed
  if (keyPressed("a") && velocity.x > -maxSpeed) velocity.x -= speed
  if (keyPressed("d") && velocity.x < maxSpeed) velocity.x += speed

  velocity.z *= friction
  velocity.x *= friction

  position.z += velocity.z * Math.sin(rotation) // this is
  position.x += velocity.x * Math.sin(rotation) // not working
}

1 个答案:

答案 0 :(得分:1)

这里是固定版本:

position.z += velocity.z * Math.cos(rotation);
position.x += velocity.z * Math.sin(rotation); 
position.z += velocity.x * Math.cos(rotation+Math.PI/2); 
position.x += velocity.x * Math.sin(rotation+Math.PI/2);

点击进入代码片段以转移焦点,然后使用WSAD

enter image description here

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/104/three.min.js">
</script><script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75,innerWidth / innerHeight,0.01,1000);
camera.position.set(0, 3, 0);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
scene.add(new THREE.GridHelper(500, 100, 0x666666, 0x444444));

let speed = 0.1, maxSpeed = 0.1, friction = 0.91, 
    position = { x: 0, y: 0, z: 0 },
    velocity = { x: 0, y: 0, z: 0 },
    rotation = 0, keyPressed = {};

let update = () => {
    if (keyPressed["w"] && velocity.z > -maxSpeed) velocity.z -= speed;
    if (keyPressed["s"] && velocity.z < maxSpeed) velocity.z += speed;
    if (keyPressed["a"] && velocity.x > -maxSpeed) velocity.x -= speed;
    if (keyPressed["d"] && velocity.x < maxSpeed) velocity.x += speed;
    velocity.z *= friction;
    velocity.x *= friction;
    position.z += velocity.z * Math.cos(rotation);
    position.x += velocity.z * Math.sin(rotation); 
    position.z += velocity.x * Math.cos(rotation+Math.PI/2); 
    position.x += velocity.x * Math.sin(rotation+Math.PI/2);
};

setInterval(update, 10);
requestAnimationFrame(render);
addEventListener('keydown', e => keyPressed[e.key] = true)
addEventListener('keyup', e => keyPressed[e.key] = false)
addEventListener('mousemove', e => rotation = e.x*Math.PI*2/innerWidth)
addEventListener('resize', e => renderer.setSize(innerWidth, innerHeight))  

function render() {
    camera.rotation.y = rotation;
    camera.position.x = position.x;
    camera.position.z = position.z;
    requestAnimationFrame(render);
    renderer.render(scene, camera);
}
</script>
<style>body,canvas{overflow:hidden;margin:0;}</style>