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代码可用于多种操作系统,也适用于多种机型。使允许直接访问物理地址…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...