three.js 鼠标左右拖动改变玩家视角

这里主要用到了 一个方法 obj.getWorldDirection();
obj.getWorldDirection()表示的获取obj对象自身z轴正方向在世界坐标空间中的方向。
按下 W键前进运动;
<template><div><el-container><el-main><div class="box-card-left"><div id="threejs"></div>{{ movementX }}</div></el-main></el-container></div>
</template>s
<script>
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import TWEEN from '@tweenjs/tween.js';
export default {data() {return {scene: null,camera: null,renderer: null,res1: null,res2: null,clock: null,left_mouse_down: false,keyState: {W: false,S: false,A: false,D: false,},left_rotation: true, // 向左旋转的标志right_rotation: true, // 向右旋转的标志VW: new this.$three.Vector3(0, 0, 0),VS: new this.$three.Vector3(0, 0, 0),curr_v: new this.$three.Vector3(0, 0, 0),person: null,movementX: null,deltaTime: 0,a: 60, // 加速度damping: -0.04,};},created() {},mounted() {this.init();},methods: {goBack() {this.$router.go(-1);},init() {// 创建场景对象this.scene = new this.$three.Scene();// 创建坐标轴辅助对象const axesHelper = new this.$three.AxesHelper(100);this.scene.add(axesHelper);// 创建时钟对象this.clock = new this.$three.Clock();// 创建环境光对象const ambientLight = new this.$three.AmbientLight(0xffffff, 6);this.scene.add(ambientLight);// this.createMesh();// 创建相机对象this.camera = new this.$three.PerspectiveCamera(60,1,0.01,2000);// this.camera.position.set(0,5,-5);// this.camera.lookAt(0,0,0);// 创建渲染器对象this.renderer = new this.$three.WebGLRenderer();this.renderer.setSize(1000,800);// 创建gltfLoader加载器对象const gltfLoader = new GLTFLoader();gltfLoader.load("models/gltf/person2/scene.gltf", gltf => {this.person = gltf.scene;// 将相机添加到人物模型上this.person.add(this.camera);// 调整相机位置this.camera.position.add(new this.$three.Vector3(0,5,-6));this.camera.translateZ(-1);let camera_look_position = this.person.position.clone().add(new this.$three.Vector3(0,4,0));// 设置相机指向this.camera.lookAt(camera_look_position);this.scene.add(gltf.scene);this.renderer.render(this.scene, this.camera);window.document.getElementById("threejs").appendChild(this.renderer.domElement);})// 监听事件方法this.addEventListenerFn();this.renderLoop();},createMesh() {const geometry = new this.$three.BoxGeometry(1,1,1);const material = new this.$three.MeshBasicMaterial({color: 0xffaadd});const mesh = new this.$three.Mesh(geometry, material);// mesh.rotateY(Math.PI / 2);const dir = new this.$three.Vector3();mesh.getWorldDirection(dir);this.scene.add(mesh);console.log('dir', dir);},addEventListenerFn() {document.addEventListener("mousemove", e => {// 鼠标左键按下的情况if(this.left_mouse_down) {this.movementX = e.movementX;this.person.rotation.y -= e.movementX / 100;// this.camera.rotateY(e.movementX / 100);const dir = new this.$three.Vector3();this.person.children[0].getWorldDirection(dir);this.renderer.render(this.scene, this.camera);}})document.addEventListener("mousedown", e => {// e.button == 0 左键;e.button == 2 右键;if(e.button == 0) {this.left_mouse_down = true;}})document.addEventListener("mouseup", e => {// e.button == 0 左键;e.button == 2 右键;if(e.button == 0) {this.left_mouse_down = false;}})// 监听键盘按下document.addEventListener("keydown", e => {// 如果按下的是 w键if(e.code == "KeyW") {this.keyState.W = true;}if(e.code == "KeyS") {this.keyState.S = true;}})// 监听键盘弹起document.addEventListener("keyup", e => {// 如果按下的是 w键if(e.code == "KeyW") {this.keyState.W = false;}if(e.code == "KeyS") {this.keyState.S = false;}})},renderLoop() {let deltaTime = this.clock.getDelta();if(this.keyState.W) {const front = new this.$three.Vector3();this.person.getWorldDirection(front);let person_v = this.curr_v.clone().add(front.multiplyScalar(deltaTime * this.a));const pos = person_v.clone().multiplyScalar(deltaTime);this.person.position.add(pos);}if(this.keyState.S) {const front = new this.$three.Vector3();this.person.getWorldDirection(front);let person_v = this.curr_v.clone().add(front.multiplyScalar(deltaTime * (-this.a)));const pos = person_v.clone().multiplyScalar(deltaTime);this.person.position.add(pos);}this.renderer.render(this.scene, this.camera);window.requestAnimationFrame(this.renderLoop);},},
};
</script>
<style lang="less" scoped>
.box-card-left {display: flex;align-items: flex-start;flex-direction: row;width: 100%;.box-right {img {width: 500px;user-select: none;}}
}
</style>
相关文章:
three.js 鼠标左右拖动改变玩家视角
这里主要用到了 一个方法 obj.getWorldDirection(); obj.getWorldDirection()表示的获取obj对象自身z轴正方向在世界坐标空间中的方向。 按下 W键前进运动; <template><div><el-container><el-main><div class"box-card-left…...
Pycharm jupyter server process exited with code 1
Pycharm jupyter server process exited with code 1 1. 问题描述2. 原因和解决方法 1. 问题描述 使用 Pycharm 启动 Jupyter 时,报错如下, jupyter server process exited with code 12. 原因和解决方法 Pycharm 启动 jupyter 时,默认的 …...
ubuntu 20.04 Python pip 配置 pip.conf
1. 状况描述 $ pip install timm WARNING: Retrying (Retry(total4, connectNone, readNone, redirectNone, statusNone)) after connection broken by ProxyError(Cannot connect to proxy., RemoteDisconnected(Remote end closed connection without response)): /simple/t…...
GPT-4.5 Turbo意外曝光,最快明天发布?OpenAI终于要放大招了!
大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,所以创建了“AI信息Gap”这个公众号,专注于分享AI全维度知识…...
Ubuntu 中 desktop-amd64 和 live-server-amd64 的区别
一、Ubuntu的操作系统镜像 Ubuntu的操作系统镜像主要有两种:desktop-amd64和live-server-amd64 这两者的主要区别在于使用场景和安装方式 1. Desktop-amd64: * 这是Ubuntu的桌面版本,用于安装具有图形用户界面的Ubuntu系统。 * 它包含了用于日常使…...
第10集《天台教观纲宗》
请大家打开讲义第十七页。我们讲到己二、结申正义。 己二、结申正义 《法华经》把我们修行人修行的相貌,比喻作一个车乘。车乘就是一种交通工具,它能够让我们从此岸超越到彼岸去。所以修行它是可以超越的,你今天比昨天超越了,就好…...
每日学习笔记:C++ STL 的forward_list
定义 特点 操作函数 元素查找、移除或安插 forward_list::emplace_after arg...指的是元素构造函数的参数(0~N个) #include <iostream> #include <memory> #include <list> #include <forward_list> using namespace std;class…...
【Java,Redis】Redis 数据库存取字符串数据以及类数据
1、 字符串存取数据 Resource private StringRedisTemplate stringRedisTemplate;//从Redis中获取string字符串 stringRedisTemplate.opsForValue().get("cache:shop:"id); //Json -> class Shop shop JSONUtil.toBean(ShopJson,Shop.class); //字符串写入redis…...
OpenCV 图像重映射函数remap()实例详解
OpenCV 图像重映射函数remap()对图像应用通用几何变换。其原型如下: void remap(InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, int borderMode BORDER_CONSTANT, const Scalar & borde…...
Python基础课堂最后一课23——正则对象
文章目录 前言一、正则对象是什么?二、正则表达式基本分类1.普通字符2.元字符 总结 前言 很开心能和你们一些学习进步,在这一个多月的时间中,是你们让我坚持了下来,完成了python基础课堂编写,不管如何,我们…...
【算法训练营】凸包,图(Python实现)
凸包 描述 给定n个二维平面上的点,求他们的凸包。 输入 第一行包含一个正整数n。 接下来n行,每行包含两个整数x,y,表示一个点的坐标。 输出 令所有在凸包极边上的点依次为p1,p2,...,pm(序号),其中m表…...
webpack5零基础入门-6webpack处理图片资源
1.在webpack5中file-loader和url-loader为内置模块 通过在加载器中配置rule即可激活 {test: /\.(png|jpe?g|gif|webp)$/,type: asset} 2.使用webpack进行打包 执行npx webpack 可以看到图片资源打包后都被放到了dist文件目录下 3.使用webpack进行图片格式转换为base64 优势…...
计算机基础知识QA
目录 数据库 --mysql 关联查询 唯一索引如何创建,语句 更新表字段语句 查看字段类型 --redis 使用场景 数据结构 设置超时时间 linux 常用命令 发布版本 安装一个东西,发现一个东西安装的很慢,如何切换ip地的源?-&g…...
微信小程序一次性订阅requestSubscribeMessage授权和操作详解
一次性订阅:用户订阅一次发一次通知 一、授权 — requestSubscribeMessage Taro.requestSubscribeMessage({tmplIds: [], // 需要订阅的消息模板的id的集合success (res) {console.log("同意授权", res)},fail(res) {console.log(拒绝授权, res)}})点击或…...
ARM 汇编指令:(三)运算处理指令
目录 一.add指令 二.sub指令 三.MUL指令 一.add指令 add用于执行实现两个寄存器或寄存机或寄存器与立即数的相加操作。它可以用于整数、浮点数等各种数据类型的加法运算。 ADD{cond}{S} Rd,操作数,操作数 1.不带进位加法指令add add r1, r2, #4 //r1 r2 4 add r1, r2 …...
【C++庖丁解牛】STL简介 | string容器初次见面
🍁你好,我是 RO-BERRY 📗 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 目录 1. 什么是STL2. STL的版本…...
记OnlyOffice的两个大坑
开发版,容器部署,试用许可已安装。 word,ppt,excel均能正常浏览。 自带的下载菜单按钮能用。 但config里自定义的downloadAs方法却不一而足。 word能正常下载,excel和ppt都不行。 仔细比对调试了代码。发现app.js…...
分享几个Google Chrome谷歌浏览器历史版本下载网站
使用selenium模块的时候,从官网下载的谷歌浏览器版本太高,驱动不支持,所以需要使用历史的谷歌浏览器版本 ,这里备份一下以防找不到了。 驱动下载地址:https://registry.npmmirror.com/binary.html?pathchromedriver 文…...
备考2025年AMC8竞赛:吃透2000-2024年600道真题(免费赠送真题)
我们继续来随机看五道AMC8的真题和解析,根据实践经验,对于想了解或者加AMC8美国数学竞赛的孩子来说,吃透AMC8历年真题是备考最科学、最有效的方法之一。 即使不参加AMC8竞赛,吃透了历年真题600道和背后的知识体系,那么…...
考研复试C语言篇
第一章 概述 1.1什么是程序 为了让计算机执行某些操作或解决某个问题而编写的一系列有序指令的合集。 1.4C语言的特点 代码级别的跨平台:由于标准的存在,使得几乎同样的C代码可用于多种操作系统,也适用于多种机型。使允许直接访问物理地址…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
