点击器游戏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
相关产品推荐
相关产品推荐

