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

点击器游戏Upgrade按钮仅生效一次的问题修复及代码优化请求

问题修复与代码优化建议

一、Upgrade按钮报错修复

报错原因

upgrade函数中使用了未声明的变量upgrade,第一次点击后该变量会覆盖同名的upgrade函数,导致后续点击时upgrade不再是可执行的函数,触发错误。

修复后的完整代码

<html>

<head>
  <link rel="icon" href="bottle1.png">
  <title>Bottle empire</title>
  <style>
    p.cash {
      font-family: "Comic Sans MS", "Comic Sans", cursive;
      position: relative;
      left: -5px;
    }

    p.cookie {
      font-family: "Comic Sans MS", "Comic Sans", cursive;
      position: relative;
      top: -300px;
    }
  </style>
</head>

<body>
  <center>
    <p class="cash">Cash: <span id="score">0</span></p>
  </center>
  <center><img src="bottle1.png" height="256px" width="256px" onclick="addToScore(1)"></center>

  <Center><button onclick="upgrade()">Upgrade bottle [<span id="upgradecost">1000</span>] </button></Center>

  <button onclick="buybottler()">Bottler [<span id="bottlercost">10</span>] -- <span id="bottlers">0</span></button>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/js-cookie/3.0.0/js.cookie.min.js"></script>
  <script>
    let score = 1000000;
    let bottlercost = 10;
    let bottlers = 0;
    let upgradecost = 1000;
    // 新增升级等级变量,避免和函数名冲突
    let upgradeLevel = 0;

    function buybottler() {
      if (score >= bottlercost) {
        score -= bottlercost;
        bottlers += 1;
        bottlercost = Math.round(bottlercost * 1.15);
        updateUI();
      }
    }

    function upgrade() {
      if (score >= upgradecost) {
        score -= upgradecost;
        upgradeLevel += 1;
        upgradecost *= 5;
        updateUI();
      }
    }

    function addToScore(amount) {
      score += amount;
      document.getElementById("score").textContent = score;
    }

    // 封装UI更新逻辑,避免重复代码
    function updateUI() {
      document.getElementById("score").textContent = score;
      document.getElementById("bottlercost").textContent = bottlercost;
      document.getElementById("bottlers").textContent = bottlers;
      document.getElementById("upgradecost").textContent = upgradecost;
    }

    setInterval(function () {
      score += bottlers;
      document.getElementById("score").textContent = score;
    }, 2000);
  </script>
</body>

</html>

二、代码优化建议

1. 提前缓存DOM元素

避免多次调用document.getElementById,提前获取所有需要操作的元素,提升性能且代码更简洁:

// 脚本开头添加
const scoreEl = document.getElementById('score');
const bottlerCostEl = document.getElementById('bottlercost');
const bottlersEl = document.getElementById('bottlers');
const upgradeCostEl = document.getElementById('upgradecost');

后续直接使用这些变量更新内容即可。

2. 用const/let替代var

var存在变量提升和全局作用域污染问题,改用ES6的const(常量)和let(变量)更安全,比如:

let score = 1000000;
const BASE_BOTTLER_COST = 10; // 固定初始值用const

3. 整合游戏状态

把所有游戏数据放到一个对象里,便于管理和扩展:

const gameState = {
  score: 1000000,
  bottlercost: 10,
  bottlers: 0,
  upgradecost: 1000,
  upgradeLevel: 0
};

后续操作直接修改gameState的属性即可。

4. 优化布局样式

用CSS Flex布局替代<center>标签和内联定位,代码更规范:

body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
  font-family: "Comic Sans MS", "Comic Sans", cursive;
}

.cash {
  margin: 0;
}

同时移除HTML中的<center>标签,让结构更简洁。

5. 格式化数值显示

给大数值添加千分位分隔符,提升可读性:

function formatNumber(num) {
  return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
// 使用示例:scoreEl.textContent = formatNumber(gameState.score);

6. 减少全局污染

用立即执行函数表达式(IIFE)封装所有逻辑,避免全局变量和函数过多:

(function() {
  // 所有变量、函数都在这里定义
})();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 15:10:23