如何让游戏循环等待按钮点击事件触发后再继续执行?
解决游戏循环不等待按钮点击的问题
问题核心原因
你的代码里,for循环是同步执行的,而按钮点击事件是异步触发的。循环会瞬间跑完所有迭代,根本不会等用户点击按钮,所以if(colorsOrder[i] != color)会立即执行(此时color还是undefined),直接触发GameOver。
解决方案:用Promise + async/await实现等待点击
我们需要把按钮点击的异步操作包装成Promise,然后用await让循环暂停,直到用户完成点击。
步骤1:封装等待点击的Promise函数
这个函数会返回一个Promise,当用户点击按钮时,Promise会完成并返回点击的按钮ID:
function waitForButtonClick() { return new Promise(resolve => { // 用.one()代替.on(),确保每次只监听一次点击,避免重复绑定事件 $(".btn").one("click", function() { ButtonClickResponse(this.id); resolve(this.id); // 将点击的ID传递给后续逻辑 }); }); }
步骤2:改造Game函数为async函数
把Game标记为async,然后在循环里await上面的函数,让循环等待用户点击:
async function Game() { while(true) { // *** 这里保留你原来的关卡初始化逻辑(比如显示颜色序列)*** // 用let声明i,避免var的作用域问题(var会让所有循环共享同一个i) for(let i = 0; i < level; i++) { // 等待用户点击按钮,拿到点击的颜色ID const clickedColor = await waitForButtonClick(); // 对比颜色是否正确 if(colorsOrder[i] !== clickedColor) { GameOver(); return; } } // *** 这里保留你原来的关卡完成逻辑(比如升级关卡)*** } }
关键细节说明
.one()的作用:原代码用.on()会每次循环都给按钮绑定新的点击事件,导致点击一次触发多次回调。.one()只会监听一次点击,触发后自动移除监听,避免这个问题。let代替var:var是函数作用域,循环里的所有迭代会共享同一个i值;let是块级作用域,每个迭代的i都是独立的,确保colorsOrder[i]能拿到正确的索引。- async/await的逻辑:
await会暂停当前函数的执行,直到Promise完成。这样循环会在每次迭代时停下来,等用户点击后再继续下一次判断。
内容的提问来源于stack exchange,提问作者3kShoter
相关产品推荐
相关产品推荐

