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

游戏开发问题:game loop中调用blowBalloon致动画无法显示

气球充气问题修复方案

问题根源

  1. 原逻辑中点击泵会立即创建新气球,且游戏循环只要isGrowing为true就每帧调用blowBalloon(),导致单次点击后气球在几十帧内瞬间完成充气,直接跳过动画。
  2. 移出循环后生成大量气球,是因为点击泵时没有判断是否已有待充气的气球,每次点击都新建一个。

修复步骤

1. 调整气球对象结构,添加充气计数

给每个气球新增充气次数相关属性,去掉冗余的isBlowing标记:

const newBalloon = {
  x: pump.x + 100,
  y: pump.y + 200,
  speedX: Math.random() * 4 + 0.3,
  speedY: Math.random() * 1 + 0.3,
  width: 30,
  height: 30,
  isGrowing: true,
  blowCount: 0, // 记录已点击充气的次数
  maxBlows: 5, // 完成充气需要的总点击次数
  alphabetImg: alphabetImages[alphabetIndex],
  balloonImage: balloonArray[Math.floor(Math.random() * balloonArray.length)],
  balloonString: balloonString,
};

2. 重写blowBalloon()函数

改为根据充气计数控制气球大小,每次点击仅执行一次充气逻辑:

function blowBalloon(balloon) {
  if (!balloon.isGrowing) return;
  if (balloon.blowCount >= balloon.maxBlows) {
    balloon.isGrowing = false;
    console.log("气球充气完成");
    return;
  }
  // 单次点击的尺寸增量(可根据视觉效果微调)
  balloon.width += 24;
  balloon.height += 24;
  balloon.x -= 12;
  balloon.y -= 20;
  balloon.blowCount++;
  console.log(`已充气${balloon.blowCount}/${balloon.maxBlows}次`);
}

3. 修改点击泵的交互逻辑

点击泵时优先给最后一个未完成充气的气球充气,无待充气气球时再创建新气球:

canvas.addEventListener("click", function (event) {
  const rect = canvas.getBoundingClientRect();
  const x = event.clientX - rect.left;
  const y = event.clientY - rect.top;

  // 戳破气球逻辑保留不变
  for (let i = balloons.length - 1; i >= 0; i--) {
    const balloon = balloons[i];
    if (x >= balloon.x && x <= balloon.x + balloon.width && y >= balloon.y && y <= balloon.y + balloon.height) {
      const burstAnimation = document.querySelector(".burst-animation");
      burstAnimation.style.display = "block";
      burstAnimation.style.left = `${balloon.x}px`;
      burstAnimation.style.top = `${balloon.y}px`;
      balloons.splice(i, 1);
      return;
    }
  }

  const pumpX = pump.x;
  const pumpY = pump.y;
  if (x >= pumpX && x <= pumpX + 400 && y >= pumpY && y <= pumpY + 400) {
    // 启动泵动画(缩短超时时间,匹配手柄移动时长)
    connectorShaking = true;
    symbolShaking = true;
    handleMoving = true;
    setTimeout(() => {
      connectorShaking = false;
      symbolShaking = false;
    }, 500); // 改为0.5秒,和手柄上下动画同步

    // 检查是否有未完成充气的气球
    const lastBalloon = balloons[balloons.length - 1];
    if (lastBalloon && lastBalloon.isGrowing) {
      // 给最后一个气球充气
      blowBalloon(lastBalloon);
      return;
    }

    // 无待充气气球且还有字母可用时,创建新气球
    if (alphabetIndex >= alphabetImages.length) return;
    const newBalloon = {
      x: pump.x + 100,
      y: pump.y + 200,
      speedX: Math.random() * 4 + 0.3,
      speedY: Math.random() * 1 + 0.3,
      width: 30,
      height: 30,
      isGrowing: true,
      blowCount: 0,
      maxBlows: 5,
      alphabetImg: alphabetImages[alphabetIndex],
      balloonImage: balloonArray[Math.floor(Math.random() * balloonArray.length)],
      balloonString: balloonString,
    };
    balloons.push(newBalloon);
    alphabetIndex++;
  }
});

4. 修正游戏循环逻辑

移除循环中自动调用blowBalloon()的代码,统一处理泵动画更新:

function gameLoop() {
  drawBackground();
  assemblePump();
  applyPumpAnimations(); // 移到此处,确保泵动画每帧更新
  drawBalloons();
  updateBalloonPositions();
  requestAnimationFrame(gameLoop);
}

最终效果

  • 点击泵时,若已有未完成充气的气球,仅会给它充一次气,5次点击后完成充气,动画过程清晰可见
  • 只有当没有待充气气球时,才会创建新气球,避免大量生成
  • 泵动画与充气操作同步,交互体验更自然

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 21:59:51