如何在模拟游戏中根据选项切换更新进度条与变量?
实现模拟游戏变量更新与月份推进的方案
嘿,这个需求刚好是模拟经营类游戏的核心逻辑之一,我来给你一步步拆解怎么实现,保证清晰好上手!
1. 先搞定统一的变量管理
首先别把五个变量零散着放,搞个游戏状态对象来统一管理,后期修改、维护都方便:
// 核心游戏状态,所有变量都存在这里 let gameState = { month: 1, // 当前月份 money: 1000, // 当前金钱 stress: 0, // 压力值(建议0-100范围,方便做进度条) job: "自由职业", // 当前工作状态 happiness: 80 // 幸福感(同样0-100范围) };
2. 给每个选项绑定变量变化规则
你需要把每个选项对应的变量变化提前定义好,用一个配置数组存起来——这样后期加新选项不用改逻辑,直接加配置就行:
// 选项配置:每个选项对应要修改的变量及变化量 const gameOptions = [ { id: "high-intensity-work", text: "高强度工作", changes: { money: +500, // 赚500块 stress: +20, // 压力涨20 happiness: -15 // 幸福感降15 } }, { id: "relax-at-home", text: "居家放松", changes: { money: -50, // 花50块 stress: -15, // 压力降15 happiness: +10 // 幸福感涨10 } }, { id: "part-time-job", text: "兼职", changes: { money: +200, stress: +10, happiness: -5 } } ];
3. 处理选项选择的交互
先让用户能选中选项,给每个选项元素加点击事件,记录当前选中的选项ID:
let selectedOptionId = null; // 存当前选中的选项ID // 给所有选项绑定点击事件 document.querySelectorAll('.game-option').forEach(optionEl => { optionEl.addEventListener('click', () => { // 先移除所有选项的选中状态 document.querySelectorAll('.game-option').forEach(el => el.classList.remove('selected')); // 给当前点击的选项加选中样式 optionEl.classList.add('selected'); // 记录选中的选项ID(对应配置里的id) selectedOptionId = optionEl.dataset.optionId; }); });
对应的HTML选项要加data-option-id属性,和配置里的id对应:
<div class="game-option" data-option-id="high-intensity-work">高强度工作</div> <div class="game-option" data-option-id="relax-at-home">居家放松</div> <div class="game-option" data-option-id="part-time-job">兼职</div>
4. 「下一步」按钮的核心逻辑
这是最关键的一步:点击按钮后,更新变量、推进月份、刷新UI:
document.getElementById('next-step-btn').addEventListener('click', () => { // 先检查用户有没有选选项 if (!selectedOptionId) { alert('请先选择一个选项哦!'); return; } // 找到选中选项对应的变化规则 const targetOption = gameOptions.find(opt => opt.id === selectedOptionId); // 更新游戏状态变量(记得做边界限制,比如压力不能超过100,不能低于0) Object.keys(targetOption.changes).forEach(key => { gameState[key] += targetOption.changes[key]; // 给压力、幸福感做0-100的边界限制 if (key === 'stress' || key === 'happiness') { gameState[key] = Math.max(0, Math.min(100, gameState[key])); } // 如果不允许金钱负数,也加限制 if (key === 'money') { gameState[key] = Math.max(0, gameState[key]); } }); // 推进月份:每次点击下一步,月份+1 gameState.month += 1; // 如果需要循环月份(比如12月后回到1月),加这个判断 // if (gameState.month > 12) gameState.month = 1; // 刷新页面UI(进度条、数值显示) updateGameUI(); // 重置选中状态,方便下一轮选择 selectedOptionId = null; document.querySelectorAll('.game-option').forEach(el => el.classList.remove('selected')); });
5. 写个UI更新函数,同步进度条和数值
专门写一个函数来更新页面上的所有显示元素,包括进度条:
function updateGameUI() { // 更新文字数值 document.getElementById('month-text').textContent = `第${gameState.month}月`; document.getElementById('money-text').textContent = `¥${gameState.money}`; document.getElementById('job-text').textContent = gameState.job; // 更新压力进度条 document.getElementById('stress-bar').style.width = `${gameState.stress}%`; document.getElementById('stress-value').textContent = `${gameState.stress}%`; // 更新幸福感进度条 document.getElementById('happiness-bar').style.width = `${gameState.happiness}%`; document.getElementById('happiness-value').textContent = `${gameState.happiness}%`; }
对应的HTML进度条结构可以这样写:
<!-- 压力进度条 --> <div class="progress-group"> <p>压力:<span id="stress-value">0%</span></p> <div class="progress-bg"> <div id="stress-bar" class="progress-fill"></div> </div> </div> <!-- 幸福感进度条 --> <div class="progress-group"> <p>幸福感:<span id="happiness-value">80%</span></p> <div class="progress-bg"> <div id="happiness-bar" class="progress-fill"></div> </div> </div>
加一点CSS让进度条好看点,还能加过渡动画:
.progress-bg { width: 250px; height: 22px; background-color: #f0f0f0; border-radius: 11px; overflow: hidden; } .progress-fill { height: 100%; transition: width 0.3s ease; /* 平滑过渡动画 */ } #stress-bar { background-color: #ff6b6b; /* 红色代表压力 */ } #happiness-bar { background-color: #4ecdc4; /* 青绿色代表幸福感 */ } .game-option.selected { background-color: #e3f2fd; /* 选中选项的高亮样式 */ border-radius: 4px; }
6. 额外优化小建议
- 如果工作状态会随选项变化(比如选兼职后工作变成「主业+兼职」),直接在选项的
changes里加job: "主业+兼职"就行 - 可以给变量变化加随机波动,比如
money: +500 + Math.floor(Math.random()*100),让游戏更有随机性 - 用
localStorage保存gameState,刷新页面不会丢失进度:localStorage.setItem('gameState', JSON.stringify(gameState)),加载时再读回来
内容的提问来源于stack exchange,提问作者Phenix Tang
相关产品推荐
相关产品推荐

