• 【threejs教程8】threejs添加3D场景键盘控制


    【完整效果代码位于文章末】     

    目录

    准备工作

    目标

    步骤1:初始化按键状态对象

    步骤2:监听键盘事件

    步骤3:编写事件处理函数

    步骤4:更新相机移动方向

    总结

    完整代码如下

            在3D应用开发中,用户交互是一个关键环节,特别是对于游戏和虚拟现实体验来说,能够通过键盘控制相机移动是提升沉浸感的重要手段。本文将指导你如何利用简单的代码,实现对THREE.js 3D场景中相机的键盘控制功能。

    准备工作

            确保你的项目中已经集成了THREE.js库,这是创建3D场景的基础。本文不涉及THREE.js的安装和基本使用,假设你已有相关基础。查看3D场景创建基础看查看往期文章:

     【threejs教程1】threejs基础开发示例

     【threejs教程2】threejs物体点击交互事件

     【threejs教程3】threejs物体轮廓发光

     【threejs教程4】threejs添加跳动标注

     【threejs教程5】threejs添加文字标注,且始终面向屏幕

     【threejs教程6】threejs加载glb模型文件(小米su7)

     【threejs教程7】threejs聚光灯、摄影机灯和汽车运动效果

    目标

            我们将实现当按下键盘上的W、S、A、D键时,3D场景中的相机分别向前、后、左、右平移。这个过程分为三步:监听键盘事件、管理按键状态、根据按键状态更新相机移动方向。

    步骤1:初始化按键状态对象

            首先,我们需要一个对象来记录键盘按键的状态(按下或抬起)。这将帮助我们判断何时以及如何改变相机的移动方向。

    1. const keyState = {
    2. KeyW: false,
    3. KeyS: false,
    4. KeyA: false,
    5. KeyD: false,
    6. };

    步骤2:监听键盘事件

            接下来,我们需要在文档级别监听键盘的keydown和keyup事件,以便在用户按下或释放特定按键时触发相应的处理函数。

    1. document.addEventListener('keydown', onDocumentKeyDown, false);
    2. document.addEventListener('keyup', onDocumentKeyUp, false);

    步骤3:编写事件处理函数

    • keydown事件处理:当按键被按下时,更新keyState中对应按键的状态为true,并调用updateMoveDirection()更新相机移动方向。
    1. function onDocumentKeyDown(event) {
    2. keyState[event.code] = true;
    3. updateMoveDirection();
    4. }
    • keyup事件处理:当按键被释放时,将其状态设回false,同样调用updateMoveDirection()确保移动状态正确反映按键情况。
    1. function onDocumentKeyUp(event) {
    2. keyState[event.code] = false;
    3. updateMoveDirection();
    4. }

    步骤4:更新相机移动方向

            最后,定义updateMoveDirection()函数,根据当前按键状态计算相机的移动方向,并应用到相机位置上。

    1. // 定义键盘控制速度(可根据需要调整)
    2. const moveSpeed = 0.5
    3. ​​​​​​​function updateMoveDirection() {
    4. const direction = new THREE.Vector3(); // 存储相机前方方向
    5. const moveDirection = new THREE.Vector3(); // 计算移动向量
    6. const upVector = new THREE.Vector3(0, 1, 0); // 作为旋转轴辅助计算
    7. // 获取相机面向的方向
    8. camera.getWorldDirection(direction);
    9.         
    10. // 根据按键状态调整移动向量
    11. if (keyState['KeyW']) moveDirection.add(direction);
    12. if (keyState['KeyS']) moveDirection.sub(direction);
    13. if (keyState['KeyA']) moveDirection.add(upVector.clone().cross(direction)); // 左转
    14. if (keyState['KeyD']) moveDirection.sub(upVector.clone().cross(direction)); // 右转
    15. // 确保移动向量有明确的方向,避免无效移动
    16. moveDirection.normalize();
    17. // 应用移动,乘以速度常量控制速度
    18. camera.position.add(moveDirection.multiplyScalar(moveSpeed));
    19. }

    总结

            至此,你已成功为3D场景中的相机添加了基本的键盘控制功能。通过监听键盘事件、维护按键状态、并据此更新相机的移动方向,你的用户现在可以使用WASD键自由探索你创造的3D世界。记得调整moveSpeed常量以获得理想的移动速度,并根据需要进一步优化和扩展控制逻辑,如添加更多按键控制或平滑移动效果等。

    完整代码如下

    1. // 用于跟踪按键状态的对象
    2. const keyState = {
    3. KeyW: false,
    4. KeyS: false,
    5. KeyA: false,
    6. KeyD: false,
    7. };
    8. // 监听键盘按键按下和抬起事件
    9. document.addEventListener('keydown', onDocumentKeyDown, false);
    10. document.addEventListener('keyup', onDocumentKeyUp, false);
    11. // 按键按下事件处理函数
    12. function onDocumentKeyDown(event) {
    13. // 设置对应按键的状态为按下
    14. keyState[event.code] = true;
    15. updateMoveDirection();
    16. }
    17. // 按键抬起事件处理函数
    18. function onDocumentKeyUp(event) {
    19. // 设置对应按键的状态为抬起
    20. keyState[event.code] = false;
    21. updateMoveDirection();
    22. }
    23. // 定义键盘控制速度(可根据需要调整)
    24. const moveSpeed = 0.5
    25. // 更新移动方向的函数
    26. function updateMoveDirection() {
    27. const direction = new THREE.Vector3(); // 用于存储相机的视线方向
    28. const moveDirection = new THREE.Vector3(); // 用于计算移动向量
    29. // 获取相机的全局前方方向
    30. camera.getWorldDirection(direction);
    31. const upVector = new THREE.Vector3(0, 1, 0); // 用于计算旋转轴
    32. // 根据按键状态调整移动向量
    33. if (keyState['KeyW']) moveDirection.add(direction);
    34. if (keyState['KeyS']) moveDirection.sub(direction);
    35. if (keyState['KeyA']) moveDirection.add(upVector.clone().cross(direction));
    36. if (keyState['KeyD']) moveDirection.sub(upVector.clone().cross(direction));
    37. // 规范化移动向量
    38. moveDirection.normalize();
    39. // 应用移动
    40. camera.position.add(moveDirection.multiplyScalar(moveSpeed));
    41. }
     
    

  • 相关阅读:
    深度学习_2_数据处理
    1230天,百度再见!!!
    【附源码】Python计算机毕业设计面向社区的购物平台系统
    SwiftUI 内功之探索 SwiftUI 中的渲染,了解 SwiftUI 何时重新渲染子视图
    计算机软件分类、编程知识体系、编程工作岗位
    坐标西安 面试中电后端Java岗 被面试官狂问mybatis
    重大发现,AQS加锁机制竟然跟Synchronized有惊人的相似
    暴力求解欲哭无泪之保安问题
    5G+北斗高精度定位系统适用于哪些行业领域?
    Whois查询结果中不同域名状态的含义
  • 原文地址:https://blog.csdn.net/c_wengy/article/details/138121525