Three.js与CANNON.js中射击冷却功能故障排查求助
射击冷却机制问题分析与修复方案
核心问题
lastShotTime的作用域错误是冷却失效的关键:如果这段代码处于**渲染循环(如requestAnimationFrame回调)**或重复执行的函数内部,每次执行都会重新声明let lastShotTime = 0,导致冷却判断条件currentTime - lastShotTime >= shootCooldown永远成立,完全失去冷却限制效果。
修复步骤
- 调整变量作用域,持久化射击时间
将lastShotTime移到重复执行的代码块外部,确保变量能保留上次射击的时间值:
// 移到渲染循环/函数外部,作为全局变量或闭包内的持久化变量 let lastShotTime = 0; const shootCooldown = 1000; // 冷却时间(毫秒) function yourRenderLoop() { if (testclick && gunn) { const currentTime = Date.now(); // 检查是否已过冷却时间 if (currentTime - lastShotTime >= shootCooldown) { // 创建子弹(原逻辑保留,仅修正变量拼写) let bullet = new THREE.Mesh( new THREE.SphereGeometry(0.05, 8, 8), new THREE.MeshBasicMaterial({ color: 0xffffff }) ); bullet.position.copy(swordPosi); bullet.alive = true; // 设置子弹速度并缩放以降低移动速度 bullet.velocity = new THREE.Vector3(0, 0, -1); bullet.velocity.applyQuaternion(camera.quaternion); bullet.velocity.multiplyScalar(0.2); // 降低速度 // 设置计时器标记子弹为已失效 setTimeout(function() { bullet.alive = false; scene.remove(bullet); }, 1000); // 将子弹添加到数组和场景中 bulits.push(bullet); scene.add(bullet); // 更新上次射击时间 lastShotTime = currentTime; } } // 更新子弹位置(修复索引错位问题) bulits = bulits.filter(bullet => { if (!bullet || !bullet.alive) { scene.remove(bullet); return false; } bullet.position.add(bullet.velocity); return true; }); if (clock.elapsedTime - lastResetTime >= resetInterval) { lastResetTime = clock.elapsedTime; } }
- 额外优化(提升代码健壮性)
- 修复子弹数组遍历的索引错位问题:用
filter替代原for循环中的splice,避免删除元素后跳过后续子弹更新。 - 统一变量拼写:将
bullit改为标准的bullet,减少维护时的混淆。 - 验证触发条件:确认
testclick和gunn的状态逻辑正确,避免因状态未重置导致重复触发射击。
内容的提问来源于stack exchange,提问作者Blaze Branham
相关产品推荐
相关产品推荐

