WebGL中基于Cannon.js的跳跃逻辑实现技术问询
跳跃逻辑实现与代码优化建议
需求回顾
正常状态下玩家碰撞体跟随相机与手部位置;当virtualJumpActive == true时反转逻辑:场景对象与相机在短时间内跟随Cannon.js物理体位置,仅Y轴(对应Cannon.js的Z轴)由物理系统控制,XY轴保留WASD用户控制,同时Y轴始终依赖物理数据以实现跳上其他物体的效果,当前相机Y轴为固定值。
优化后代码
var playerUpdater = { UPDATE: () => { const cameraEvents = matrixEngine.Events.camera; const playerCollider = App.scene.playerCollisonBox.physics.currentBody; const playerObj = App.scene[objName]; // 统一处理Y轴旋转 playerObj.rotation.rotateY(cameraEvents.yaw + 180); // 简化Pitch角度限制计算 const limit = 2; let detPitch = cameraEvents.pitch * 2; if (cameraEvents.pitch > limit) { detPitch = limit * 2; } else if (cameraEvents.pitch < -(limit + 2)) { detPitch = -(limit + 2) * 2; } // 统一处理Pitch位置限制 let detPitchPos = cameraEvents.pitch; detPitchPos = Math.min(detPitchPos, 4); if (cameraEvents.virtualJumpActive) { // 跳跃状态:物理体驱动相机与场景对象 playerObj.rotation.rotateX(-detPitch); // 明确坐标映射:Cannon的X/Y/Z对应场景的X/Z/Y const physX = playerCollider.position.x; const physY = playerCollider.position.y; const physZ = playerCollider.position.z; playerObj.position.setPosition(physX, physZ, physY); cameraEvents.xPos = physX; cameraEvents.zPos = physY; cameraEvents.yPos = physZ; // 让相机Y轴跟随物理Z轴,不再固定 // 锁定物理体旋转,避免倾斜 playerCollider.angularVelocity.set(0, 0, 0); // 避免重复触发定时器:仅在跳跃激活时初始化一次 if (!cameraEvents.jumpTimer) { cameraEvents.jumpTimer = setTimeout(() => { cameraEvents.virtualJumpActive = false; cameraEvents.virtualJumpY = 2; delete cameraEvents.jumpTimer; // 清除定时器标记 }, 350); } } else { // 正常状态:相机驱动物理体与场景对象 playerObj.rotation.rotateX(-detPitch); playerObj.position.setPosition( cameraEvents.xPos, cameraEvents.yPos - 0.3 + detPitchPos / 50, cameraEvents.zPos ); // 坐标映射:场景X/Y/Z对应Cannon的X/Z/Y playerCollider.position.set( cameraEvents.xPos, cameraEvents.zPos, cameraEvents.yPos ); // 锁定物理体速度与旋转,避免漂移 playerCollider.velocity.set(0, 0, 0); playerCollider.angularVelocity.set(0, 0, 0); } } };
核心优化点
- 避免重复定时器触发:原代码在每一帧都会调用
setTimeout,导致跳跃结束逻辑被多次触发。新增jumpTimer标记,确保定时器仅初始化一次。 - 简化变量与重复逻辑:提取重复使用的
cameraEvents、playerCollider、playerObj变量,减少重复访问场景对象的开销;统一detPitchPos的限制逻辑,消除代码冗余。 - 修复相机Y轴固定问题:跳跃状态下让相机
yPos直接跟随物理体的Z轴位置,实现Y轴依赖物理数据的需求,解决原固定值无法跳上物体的问题。 - 明确坐标映射关系:通过变量命名清晰区分Cannon.js与场景的坐标对应关系,避免混淆出错。
- 优化物理体控制:正常状态下始终锁定物理体速度,避免因物理引擎微小误差导致的位置漂移;跳跃状态下仅锁定旋转,保留Y轴(物理Z轴)的物理运动。
内容的提问来源于stack exchange,提问作者Nikola Lukic
相关产品推荐
相关产品推荐

