html5 pointer lock api 实现fps游戏的核心是通过 canvas.requestpointerlock() 锁定鼠标,利用 mousemove 的 movementx/y 获取无边界视角偏移,结合 three.js 更新相机 yaw/pitch 角度、基于视线方向的 wasd 移动、重力与 aabb 碰撞检测,以及 raycaster 射线射击逻辑。

使用 HTML5 的 Pointer Lock API 开发网页端 3D 第一人称射击(FPS)游戏,核心在于让鼠标持续控制视角朝向,且不被屏幕边界限制。它不是“让鼠标消失”,而是把鼠标输入转化为连续的、无边界的 Δx/Δy 偏移量,配合 WebGL(如 Three.js)渲染 3D 场景,实现沉浸式视角旋转和移动。
启用 Pointer Lock 并监听鼠标偏移
用户点击画面后请求锁定鼠标指针,之后所有 mousemove 事件的 movementX 和 movementY 属性将返回相对上一帧的像素位移(即使鼠标已到达屏幕边缘)。
- 调用
canvas.requestPointerLock()触发锁定(需用户手势,如 click/mousedown) - 监听
document.addEventListener('pointerlockchange', ...)判断是否成功锁定 - 在
mousemove中累加event.movementX和event.movementY,用于更新相机 yaw(水平)和 pitch(垂直)角度 - 注意:pitch 要做上下限限制(如 -85° ~ 85°),避免翻转
用 Three.js 构建可旋转的 FPS 相机
Three.js 的 PerspectiveCamera 本身不自带 yaw/pitch 控制,需手动维护欧拉角或四元数。
- 创建相机时设好初始位置和朝向(如面向 Z 轴正方向)
- 定义两个变量:
yaw(绕 Y 轴,控制左右转头)、pitch(绕 X 轴,控制抬头低头) - 每次收到 mousemove 偏移后: yaw -= movementX * sensitivitypitch -= movementY * sensitivity (注意符号,通常 X 正向右,应使 yaw 减小才向右看)
- 用
camera.rotation.order = 'YXZ'或更稳妥地用camera.quaternion.setFromEuler(new THREE.Euler(pitch, yaw, 0))更新朝向
实现 WASD 移动 + 重力与碰撞(基础物理)
视角锁定后,键盘控制角色在世界中平移,需区分“世界坐标系”和“相机本地坐标系”。
- WASD 应基于相机朝向移动:例如 W = camera.getWorldDirection(),再投影到 XZ 平面归一化后乘以速度
- 添加简单重力:每帧给 y 方向速度减去重力加速度,再更新 y 位置;落地时清空 y 速度并设 y 为地面高度
- 碰撞检测可用 AABB(轴对齐包围盒):把玩家简化为一个立方体,遍历场景中静态障碍物盒子,检测是否相交;相交则沿侵入最小的方向弹回
- 推荐用
raycaster检测地面高度或墙面阻挡,比纯数学更鲁棒
添加射击逻辑与射线检测
FPS 的“开火”本质是:从相机位置沿当前视线方向发射一条射线,检测是否击中可交互物体(敌人、门、道具等)。
- 用
new THREE.Raycaster(camera.position, camera.getWorldDirection()) - 设置射程(如 100 单位),调用
raycaster.intersectObjects(targets) - 取第一个命中结果(
intersects[0]),获取 hit point、object、face 等信息 - 可据此播放音效、显示弹孔贴图(用 Sprite 或平面 Mesh)、扣血、触发事件
- 为模拟后坐力,开火后可临时扰动 pitch/yaw(如加个微小随机抖动并随时间衰减)
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











