joken-前端工程师

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::
  404 随笔 :: 39 文章 :: 8 评论 :: 20万 阅读

在 Three.js 中,可以通过监听键盘事件(上下左右键)来控制一个 Mesh 的移动。以下是一个完整的示例,展示如何实现通过方向盘(上下左右键)控制一个人的 Mesh 在场景中走动。


结论

通过监听键盘事件(keydownkeyup),记录按键状态,并结合时间差更新 Mesh 的位置,可以实现平滑的移动效果。


详细展开

1. 核心思路

  • 使用 THREE.Clock 获取时间差(delta time),确保移动速度与帧率无关。
  • 监听键盘事件,记录按键状态(如按下或释放)。
  • 根据按键状态和时间差更新 Mesh 的位置。

2. 完整示例代码

import * as THREE from 'three';

// 创建场景、相机和渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer);

// 添加背景颜色
scene.background = new THREE.Color(0x87ceeb); // 天空蓝

// 创建一个简单的立方体作为“人”
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const person = new THREE.Mesh(geometry, material);
scene.add(person);

// 设置相机位置
camera.position.z = 5;

// 创建时钟
const clock = new THREE.Clock();

// 定义移动速度
const speed = 2; // 单位:每秒移动的距离

// 记录按键状态
const keys = {
    ArrowUp: false,
    ArrowDown: false,
    ArrowLeft: false,
    ArrowRight: false
};

// 监听键盘按下事件
window.addEventListener('keydown', (event) => {
    if (keys.hasOwnProperty(event.key)) {
        keys[event.key] = true;
    }
});

// 监听键盘释放事件
window.addEventListener('keyup', (event) => {
    if (keys.hasOwnProperty(event.key)) {
        keys[event.key] = false;
    }
});

// 渲染循环
function animate() {
    requestAnimationFrame(animate);

    // 获取时间差
    const delta = clock.getDelta();

    // 根据按键状态更新位置
    if (keys.ArrowUp) person.position.z -= speed * delta; // 向前
    if (keys.ArrowDown) person.position.z += speed * delta; // 向后
    if (keys.ArrowLeft) person.position.x -= speed * delta; // 向左
    if (keys.ArrowRight) person.position.x += speed * delta; // 向右

    // 渲染场景
    renderer.render(scene, camera);
}
animate();

关键点解析

1. 键盘事件监听

  • 使用 keydown 事件记录按键按下状态。
  • 使用 keyup 事件记录按键释放状态。
  • 将按键状态存储在一个对象中(如 keys),便于后续逻辑判断。

2. 基于时间的移动

  • 使用 THREE.Clock 获取时间差(delta time),确保移动速度与帧率无关。
  • 移动距离计算公式:distance = speed * delta

3. 坐标系方向

  • 在 Three.js 的默认坐标系中:
    • X 轴:水平方向,正向为右,负向为左。
    • Z 轴:深度方向,正向为远离屏幕,负向为靠近屏幕。
    • Y 轴:垂直方向,正向为上,负向为下。

因此:

  • 上键(ArrowUp)控制向前移动(z--)。
  • 下键(ArrowDown)控制向后移动(z++)。
  • 左键(ArrowLeft)控制向左移动(x--)。
  • 右键(ArrowRight)控制向右移动(x++)。

4. 平滑移动

通过时间差更新位置,而不是直接修改坐标值,可以实现平滑的移动效果。


扩展功能

1. 添加边界限制

为了避免 Mesh 移出场景范围,可以添加边界限制:

const bounds = { minX: -5, maxX: 5, minZ: -5, maxZ: 5 };

if (keys.ArrowUp && person.position.z > bounds.minZ) person.position.z -= speed * delta;
if (keys.ArrowDown && person.position.z < bounds.maxZ) person.position.z += speed * delta;
if (keys.ArrowLeft && person.position.x > bounds.minX) person.position.x -= speed * delta;
if (keys.ArrowRight && person.position.x < bounds.maxX) person.position.x += speed * delta;

2. 添加旋转效果

为了让 “人” 面向移动方向,可以添加旋转逻辑:

if (keys.ArrowUp || keys.ArrowDown) {
    person.rotation.y = Math.PI; // 面向 Z 轴方向
} else if (keys.ArrowLeft || keys.ArrowRight) {
    person.rotation.y = 0; // 面向 X 轴方向
}

总结

通过监听键盘事件并结合时间差更新 Mesh 的位置,可以实现通过方向盘(上下左右键)控制人物在场景中走动的效果。此方法简单易用,适用于大多数基于键盘输入的交互场景。如果需要更复杂的功能(如斜向移动或加速度),可以进一步扩展逻辑。

posted on   joken1310  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2018-03-04 vi 使用小结
点击右上角即可分享
微信分享提示