【问题标题】:First person WASD controls第一人称 WASD 控制
【发布时间】:2019-07-16 20:33:18
【问题描述】:

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

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

我的问题是如何更新我的代码以使用 w-key 根据当前轮换“直行”,无论在哪里都使用 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
}

【问题讨论】:

  • 你如何更新rotation

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


【解决方案1】:

这里是固定版本:

position.z += velocity.z * Math.cos(rotation);
position.x += velocity.z * Math.sin(rotation); 
position.z -= velocity.x * Math.sin(rotation); 
position.x += velocity.x * Math.cos(rotation);

点击进入sn-p转移焦点然后使用WSAD

<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.sin(rotation); 
    position.x += velocity.x * Math.cos(rotation);
};

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>

【讨论】:

  • 谢谢,但你的答案并不真正匹配,因为我得到了一个单一的 rotationY 值 - 而不是 theta、phi 等。崩溃会很棒!
  • @Stranger 在 Q 很好的答案!
猜你喜欢
  • 2012-09-12
  • 1970-01-01
  • 2014-03-16
  • 1970-01-01
  • 1970-01-01
  • 2016-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多