javascript - 第一人称 WASD 控制

标签 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
}

最佳答案

这里是固定版本:

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);

点击进入片段转移焦点然后使用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.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>

关于javascript - 第一人称 WASD 控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57065027/

相关文章:

css - 使 <li> 在悬停时改变颜色

javascript - 正则表达式检查特定字符串

javascript - 为什么我的 D3 SVG 图上的轴不会更新?

javascript - RegExp 测试函数奇怪的行为

java - 多边形顶点作为 UV 坐标

ios - 适用于 iPad 的交互式 3D 模型

c++ - opengl 3D变换需要旋转矩阵

javascript - 需要使用 HTML Canvas 将鼠标事件转换为移动设备的触摸事件

javascript - 定义按 Enter 键时的默认按钮

javascript - Canvas 绘制图像被下面的代码遮挡