
本文介绍在 pygame/pgzero 游戏开发中,如何避免因帧循环导致的重复奖励问题,通过引入里程碑变量(milestone)精准控制“每100分加5条命”逻辑仅执行一次。
本文介绍在 pygame/pgzero 游戏开发中,如何避免因帧循环导致的重复奖励问题,通过引入里程碑变量(milestone)精准控制“每100分加5条命”逻辑仅执行一次。
在基于 PGZero(或类似每帧调用更新函数的框架)的游戏逻辑中,update() 或事件处理函数会被高频反复调用(通常每秒60次)。这意味着像 if score % 100 == 0 这样的条件——一旦玩家分数恰好为100、200、300等整百数——会在连续多帧内持续成立,导致 lives += 5 被重复执行多次,而非预期的“仅加一次”。
根本原因在于:该判断缺乏状态记忆。它只看当前分数是否满足数学条件,却未记录“这个百位里程碑是否已被处理过”。
✅ 正确解法是引入一个里程碑标记变量(如 milestone),用于持久化记录上一次已奖励的分数阈值:
# 声明全局变量(建议在模块顶层初始化)
lives = 3
score = 0
extralives = 0
milestone = 0 # 记录最近一次已触发奖励的分数值
def update():
global lives, score, extralives, milestone
# 条件升级:不仅检查整除,还确保当前分数 ≠ 上次已处理的里程碑
if (score % 100 == 0 and score != 0 and score != milestone) or (keyboard.lctrl and keyboard.ralt):
extralives = 1
milestone = score # 锁定当前分数为新里程碑
if extralives == 1:
lives += 5
extralives = 0 # 注意:用 = 0 更清晰,避免 -= 1 在异常时出错
? 关键要点说明:
- milestone = score 必须在奖励触发后立即赋值,确保后续帧中 score != milestone 不再成立,从而阻断重复触发;
- 使用 extralives = 0 替代 extralives -= 1 更安全,避免因逻辑误触导致负值;
- 若需支持“回退分数”场景(如扣分后再次到达同一整百数),可额外增加 score > milestone 判断,防止倒退触发;
- 所有相关变量(lives, score, extralives, milestone)必须统一声明为 global,并在首次使用前完成初始化。
该模式可泛化应用于各类“达成式成就”系统,例如:首次抵达关卡终点、首次收集全部道具等,核心思想始终是——用状态变量锚定已发生的事件,而非依赖瞬时数值条件。











