无需用户交互刷新Morph:如何展示桌游机器人玩家的每一步操作?
在Squeak Morph中实现机器人对局的实时落子动画
核心问题出在机器人走棋逻辑是同步一次性执行完的,导致UI线程被阻塞,根本没时间刷新中间状态,直接跳到了最终棋盘。下面是几种可行的解决方法:
方法1:用延迟UI消息拆分每一步走棋
把机器人的连续走棋拆成单步,让UI每次刷新后再执行下一步。用WorldState>>addDeferredUIMessage:来调度任务,这个方法会把代码放到UI队列里,等当前界面更新完成后再执行。
示例代码:
RobotPlayer>>playNextTurn game isOver ifTrue: [^ self]. "执行一步落子,这里要确保已经处理了Morph的更新:比如添加棋子Morph、调用changed方法" self makeMove. "调度下一步走棋" WorldState addDeferredUIMessage: [self playNextTurn].
启动机器人对局时,直接调用robotPlayer playNextTurn,而不是用循环一次性跑完所有步骤。
方法2:控制走棋速度(可选)
如果觉得机器人走棋太快,想加个间隔,直接在单步逻辑里加Delay即可:
RobotPlayer>>playNextTurn game isOver ifTrue: [^ self]. self makeMove. "等待500毫秒,调整数值可以改变速度" (Delay forMilliseconds: 500) wait. WorldState addDeferredUIMessage: [self playNextTurn].
方法3:用step方法配合状态标记
如果一定要用step机制,需要给机器人加个状态变量,让step每次只执行一步走棋,而不是提前跑完所有步骤:
RobotPlayer>>initialize super initialize. isPlaying := false. self startStepping. "启动step循环" self stepTime: 500. "设置每步间隔,单位毫秒" RobotPlayer>>startAutoPlay isPlaying := true. RobotPlayer>>step isPlaying ifFalse: [^ self]. game isOver ifTrue: [isPlaying := false] ifFalse: [self makeMove]. self changed. "强制触发界面更新"
启动时调用robotPlayer startAutoPlay,这样每到设定的间隔就会执行一步走棋,界面也能实时刷新。
为什么之前的step方法没用?
你之前的问题在于,机器人的走棋循环是同步执行的——在step第一次被调用前,所有落子已经跑完了,游戏直接结束。所以必须把走棋逻辑拆解到step的每次调用中,或者用延迟消息让UI有时间刷新中间状态。
内容的提问来源于stack exchange,提问作者Sander de Jong
相关产品推荐
相关产品推荐

