HarmonyOS 小游戏《对战五子棋》开发第33篇 - AI异步落子与setTimeout 📅 2026/7/12 1:15:51 让AI思考一下再落子——异步交互的体验设计截图如下AI落子的时序问题如果AI在玩家落子后立即响应用户体验会很奇怪——感觉不像在对战。通过setTimeout添加延迟让AI有思考的时间。玩家落子触发AIprivateonCellClick(row:number,col:number):void{if(this.result!GameResult.PLAYING||this.aiThinking)return;if(this.currentPlayer!BLACK)return;// 只有玩家(黑方)能点击constsuccessthis.engine.placePiece(row,col,BLACK);if(!success)return;this.refreshBoardData();if(this.result!GameResult.PLAYING){this.handleGameEnd();return;}// AI回合this.aiThinkingtrue;this.aiTimerIdsetTimeout((){this.makeAIMove();},400);}aiThinking状态StateaiThinking:booleanfalse;aiThinking有双重作用UI展示显示AI思考中…和LoadingProgress动画交互锁AI思考时禁止玩家点击棋盘// 交互锁if(this.result!GameResult.PLAYING||this.aiThinking)return;// UI展示Text(this.getStatusText())// 返回 AI思考中...if(this.aiThinking){LoadingProgress().width(16).height(16).color(#FA8C16)}// 按钮状态Button(重新开始).enabled(!this.aiThinking)// AI思考时禁用makeAIMove实现privatemakeAIMove():void{this.aiTimerId-1;// 清除定时器IDif(this.result!GameResult.PLAYING){this.aiThinkingfalse;return;}// AI计算最佳落子constmovethis.aiPlayer.getMove(this.engine.board);// 引擎执行落子this.engine.placePiece(move.row,move.col,WHITE);// 解除思考状态this.aiThinkingfalse;// 刷新UIthis.refreshBoardData();// 检查游戏结束if(this.result!GameResult.PLAYING){this.handleGameEnd();}}setTimeout的作用this.aiTimerIdsetTimeout((){this.makeAIMove();},400);400ms延迟的设计考量用户体验给AI思考的感觉避免UI卡顿困难模式的Minimax搜索需要200-500mssetTimeout让搜索在下一个事件循环中执行可取消保存timerId用于清理定时器清理aboutToDisappear():void{if(this.aiTimerId!-1){clearTimeout(this.aiTimerId);this.aiTimerId-1;}}privatebackToLevelSelect():void{if(this.aiTimerId!-1){clearTimeout(this.aiTimerId);this.aiTimerId-1;}this.inGamefalse;// ...}清理时机页面销毁时aboutToDisappear返回选关时backToLevelSelect为什么要清理如果不清理定时器在页面销毁后仍会执行makeAIMove可能访问已销毁的组件状态导致错误。AI落子的完整流程玩家点击落子 ↓ engine.placePiece(玩家黑棋) ↓ 游戏结束? → 是 → handleGameEnd() ↓ 否 aiThinking true ↓ setTimeout(400ms) ↓ makeAIMove() ↓ aiPlayer.getMove(board) → 计算最佳位置 ↓ engine.placePiece(AI白棋) ↓ aiThinking false ↓ refreshBoardData() ↓ 游戏结束? → 是 → handleGameEnd() ↓ 否 等待玩家下一手状态文字的变化privategetStatusText():string{if(this.resultGameResult.BLACK_WIN)return你赢了;if(this.resultGameResult.WHITE_WIN)returnAI获胜;if(this.resultGameResult.DRAW)return平局;if(this.aiThinking)returnAI思考中...;return你的回合;}状态文字随游戏进程动态变化你的回合 → AI思考中... → 你的回合 → ... → 你赢了/AI获胜LoadingProgress组件if(this.aiThinking){LoadingProgress().width(16).height(16).margin({left:8}).color(#FA8C16)// 橙色加载圈}LoadingProgress是ArkUI内置的加载动画组件——一个旋转的圆圈在AI思考时显示。总结AI异步落子的设计要点setTimeout延迟400ms模拟AI思考aiThinking状态UI展示交互锁双重作用LoadingProgress内置加载动画定时器清理页面销毁/返回时清除流程清晰玩家落子→延迟→AI落子→刷新这种异步设计让对战体验自然流畅避免了AI瞬间响应的违和感。