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

news2025/1/1 22:44:31

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

目录

准备工作

目标

步骤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:初始化按键状态对象

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

const keyState = {
  KeyW: false,
  KeyS: false,
  KeyA: false,
  KeyD: false,
};

步骤2:监听键盘事件

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

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

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

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

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

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

// 定义键盘控制速度(可根据需要调整)
const moveSpeed = 0.5
​​​​​​​function updateMoveDirection() {
  const direction = new THREE.Vector3(); // 存储相机前方方向
  const moveDirection = new THREE.Vector3(); // 计算移动向量
  const upVector = new THREE.Vector3(0, 1, 0); // 作为旋转轴辅助计算

  // 获取相机面向的方向
  camera.getWorldDirection(direction);
        
  // 根据按键状态调整移动向量
  if (keyState['KeyW']) moveDirection.add(direction);
  if (keyState['KeyS']) moveDirection.sub(direction);
  if (keyState['KeyA']) moveDirection.add(upVector.clone().cross(direction)); // 左转
  if (keyState['KeyD']) moveDirection.sub(upVector.clone().cross(direction)); // 右转

  // 确保移动向量有明确的方向,避免无效移动
  moveDirection.normalize();

  // 应用移动,乘以速度常量控制速度
  camera.position.add(moveDirection.multiplyScalar(moveSpeed));
}

总结

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

完整代码如下

// 用于跟踪按键状态的对象
  const keyState = {
    KeyW: false,
    KeyS: false,
    KeyA: false,
    KeyD: false,
  };
   

  // 监听键盘按键按下和抬起事件
  document.addEventListener('keydown', onDocumentKeyDown, false);
  document.addEventListener('keyup', onDocumentKeyUp, false);

  // 按键按下事件处理函数
  function onDocumentKeyDown(event) {
    // 设置对应按键的状态为按下
    keyState[event.code] = true;
    updateMoveDirection();
  }

  // 按键抬起事件处理函数
  function onDocumentKeyUp(event) {
    // 设置对应按键的状态为抬起
    keyState[event.code] = false;
    updateMoveDirection();
  }
  // 定义键盘控制速度(可根据需要调整)
  const moveSpeed = 0.5
  // 更新移动方向的函数
  function updateMoveDirection() {
    const direction = new THREE.Vector3(); // 用于存储相机的视线方向
    const moveDirection = new THREE.Vector3(); // 用于计算移动向量

    // 获取相机的全局前方方向
    camera.getWorldDirection(direction);
    const upVector = new THREE.Vector3(0, 1, 0); // 用于计算旋转轴
    // 根据按键状态调整移动向量
    if (keyState['KeyW']) moveDirection.add(direction);
    if (keyState['KeyS']) moveDirection.sub(direction);
    if (keyState['KeyA']) moveDirection.add(upVector.clone().cross(direction));
    if (keyState['KeyD']) moveDirection.sub(upVector.clone().cross(direction));
    // 规范化移动向量
    moveDirection.normalize();
    // 应用移动
    camera.position.add(moveDirection.multiplyScalar(moveSpeed));
  }
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1624630.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JS实现对用户名、密码进行正则表达式判断,网页跳转

目标&#xff1a;使用JS实现对用户名和密码进行正则表达式判断&#xff0c;用户名和密码正确时&#xff0c;进行网页跳转。 用户名、密码的正则表达式检验 HTML代码&#xff1a; <button type"submit" id"login-btn" /*onclick"login();alidate…

openstack界面简单修改

openstack Ubuntu主题登录界面修改修改登陆界面背景登录框边缘添加透明效果修改登录界面logo更换站点图片更换项目logo图片 本实验基于VMware17&#xff0c;使用Ubuntu2310搭建openstack-B版 Ubuntu主题 以下配置只对Ubuntu主题生效 登录界面修改 原界面 关闭登录界面域名输…

HTTP与HTTPS 对比,区别详解(2024-04-25)

一、简介 HTTP&#xff08;超文本传输协议&#xff0c;Hypertext Transfer Protocol&#xff09;是一种用于从网络传输超文本到本地浏览器的传输协议。它定义了客户端与服务器之间请求和响应的格式。HTTP 工作在 TCP/IP 模型之上&#xff0c;通常使用端口 80。 HTTPS&#xf…

百度沈抖:智能,生成无限可能

4月16日&#xff0c;Create 2024百度AI开发者大会在深圳举行。会上&#xff0c;百度集团执行副总裁、百度智能云事业群总裁沈抖正式发布新一代智能计算操作系统——百度智能云万源。它能管理万卡规模的集群&#xff0c;极致地发挥GPU、CPU的性能&#xff1b;它有强大的大模型作…

【树莓派】yolov5 Lite,目标检测,树莓派4B,推理v5lite-e_end2end.onnx,摄像头实时目标检测

文章目录 YOLOv5 Lite: 在树莓派上轻松运行目标检测1. 环境配置2. 克隆项目3. 安装依赖项4. 下载模型权重5. 理解end2end的含义6. 示例推理7. 文件介绍8. 把文件弄到树莓派4B执行9. 进一步尝试fp16的onnx&#xff08;行不通&#xff09;10. 视频流检测 这里有大概的环境配置&am…

太速科技-多路PCIe的阵列计算全国产化服务器

多路PCIe的阵列计算全国产化服务器 多路PCIe的阵列计算全国产化服务器以国产化处理器&#xff08;海光、飞腾ARM、算能RSIC V&#xff09;为主板&#xff0c;扩展6-8路PCIe3.0X4计算卡&#xff1b; 计算卡为全国产化的AI处理卡&#xff08;瑞星微ARM&#xff0c;算能AI&#x…

【预测】小米汽车电子电气架构的猜想

文章目录 前言 整车EEA 硬件平台 软件平台 总结 参考资料 前言 见《【Review】小米汽车发布会》 整车EEA 小米汽车整车电子电气架构方面的信息&#xff0c;小米官方并没有对外介绍&#xff0c;但是从近日流出的整车BOM和供应商列表中看到&#xff0c;车上各种控制器一个都…

四川易点慧电子商务:抖音小店引领潮流,先进模式打造电商新标杆

在当下数字化浪潮中&#xff0c;电子商务行业如日中天&#xff0c;四川易点慧电子商务有限公司以其独特的视角和前瞻性的战略布局&#xff0c;成功在抖音小店领域崭露头角&#xff0c;成为行业内的佼佼者。本文将深入剖析四川易点慧电子商务的成功秘诀&#xff0c;以及其在抖音…

基于OpenCV的人脸签到系统

效果图 目录文件 camerathread.h 功能实现全写在.h里了 class CameraThread : public QThread {Q_OBJECT public:CameraThread(){//打开序号为0的摄像头m_cap.open(0);if (!m_cap.isOpened()) {qDebug() << "Error: Cannot open camera";}//判断是否有文件,人脸…

OmniPlan Pro for Mac v4.8.0中文激活版 项目流程管理工具

OmniPlan Pro for Mac是一款功能强大的项目管理软件&#xff0c;它以其直观的用户界面和丰富的功能&#xff0c;帮助用户轻松管理各种复杂的项目。 OmniPlan Pro for Mac v4.8.0中文激活版 通过OmniPlan Pro&#xff0c;用户可以轻松创建任务&#xff0c;设置任务的开始和结束时…

【ensp实验】Telnet 协议

目录 Telnet 协议 telnet协议特点 Telnet实验 ​编辑 不使用console口 三种认证模式的区别 Telnet 协议 Telnet 协议是 TCP/IP 协议族中的一员&#xff0c;是 Internet 远程登录服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。在终端使用…

软考-论文写作-论架构风格论文

题目 素材 框架 一、 摘要 2020年12月,我参加了某省政协委员履职系统的开发。该系统为政协机关人员线上开展各项工作以及委员完成各项履职提供了全方位的软件支撑。我在该项目重担任系统架构师一职,负责履职系统的架构设计。本文结合实践,以委员履职系统为例,主要讨论软件…

访问控制列表配置实验

ACL&#xff0c;全称 Access Control List&#xff08;访问控制列表&#xff09;&#xff0c;是一种实现访问控制的机制&#xff0c;用于规定哪些主体&#xff08;如用户、设备、IP地址、进程等&#xff09;可以对哪些资源&#xff08;如网络服务、文件、系统对象等&#xff09…

多组学+机器学习+膀胱癌+分型+建模

这是一个基于多组学机器学习的分型建模文章&#xff0c;这里我们大概介绍一下&#xff0c;这篇文章做了啥 一、研究背景 1、尿路上皮癌是高度恶性的肿瘤&#xff0c;预后差&#xff0c;死亡率高 2、没有明显有效的治疗方法&#xff0c;多数患者在免疫治疗中无法受益&#xf…

STM32H750外设ADC之开始和结束数据转换功能

目录 概述 1 开始转换 1.1 使能ADSTART 1.2 使能JADSTART 1.3 ADSTART 通过硬件清零 2 转换时序 3 停止正在进行的转换&#xff08; ADSTP、 JADSTP&#xff09; 3.1 停止转换功能实现 3.2 停止转换流程图 概述 本文主要讲述了STM32H750外设ADC之开始和结束数据转换…

JavaScript-Vue入门

本文主要测分享Vue的一些基础 Vue简介 Vue.js 是一个构建数据驱动的 web 界面的渐进式框架。它的主要目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。 下是一些 Vue 的主要特点和概念&#xff1a; 1. 响应式数据绑定&#xff1a;Vue 使用基于 HTML 的模板语法…

Android --- SharedPreferences

SharedPreferences 对应sp文件的接口 使用 SharedPreferences API可以保存的相对较小键值对集合。SharedPreferences 对象指向包含键值对的文件&#xff0c;并提供读写这些键值对的简单方法。每个 SharedPreferences 文件均由框架进行管理&#xff0c;可以是私有文件&#xff…

李沐66_使用注意力机制的seq2seq——自学笔记

加入注意力 1.编码器对每次词的输出作为key和value 2.解码器RNN对上一个词的输出是query 3.注意力的输出和下一个词的词嵌入合并进入RNN 一个带有Bahdanau注意力的循环神经网络编码器-解码器模型 总结 1.seq2seq通过隐状态在编码器和解码器中传递信息 2.注意力机制可以根…

stable diffusion 的controlNet 安装和使用

stable diffusion 安装controlNet需要先下载扩展 扩展地址 下载了扩展以后&#xff0c;需要下载相应的模型&#xff0c;每个模型大约1.45G,可以按需下载。 模型地址 如果下载速度太慢&#xff0c;可以考虑去liblib下载&#xff0c;但是是全量模型 liblib 模型下载完后&#…

使用windows端MySQL创建数据库

1.命令行登录数据库 命令&#xff1a;mysql -u用户名 -p密码&#xff1b; 切记命令后面要以分号结尾 2. 查看和创建数据库 查看数据库命令&#xff1a;show database&#xff1b; 创建数据库命令&#xff1a;mysql> create database db_classes; 创建一个名为db_classes的…