You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js与CANNON.js中射击冷却功能故障排查求助

射击冷却机制问题分析与修复方案

核心问题

lastShotTime的作用域错误是冷却失效的关键:如果这段代码处于**渲染循环(如requestAnimationFrame回调)**或重复执行的函数内部,每次执行都会重新声明let lastShotTime = 0,导致冷却判断条件currentTime - lastShotTime >= shootCooldown永远成立,完全失去冷却限制效果。

修复步骤

  1. 调整变量作用域,持久化射击时间
    将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;
  }
}
  1. 额外优化(提升代码健壮性)
  • 修复子弹数组遍历的索引错位问题:用filter替代原for循环中的splice,避免删除元素后跳过后续子弹更新。
  • 统一变量拼写:将bullit改为标准的bullet,减少维护时的混淆。
  • 验证触发条件:确认testclick和gunn的状态逻辑正确,避免因状态未重置导致重复触发射击。

内容的提问来源于stack exchange,提问作者Blaze Branham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 14:52:18