Kivy气球收集游戏循环中单次收集气球计分多次增加如何修复
无人机收集气球游戏计分问题修复方案
问题根因分析
- 最初计分暴增的原因
游戏update函数刷新率为1/600秒,也就是每秒调用600次。最开始仅调用remove_widget把气球从界面移除,没有同步把气球从self.balloons列表删除,导致后续几百帧的碰撞检测都会判定无人机仍在碰撞气球,每帧加1分,分数直接暴增到几十上百。 - 修改后每次加2分的原因
两个问题叠加导致:
- 全局复用
self.balloon_coordinates变量,get_balloon_coordinates遍历所有气球时会反复覆盖这个变量的坐标值,判断逻辑本身存在偏差 - 遍历
self.balloons列表的同时直接删除元素,会导致遍历逻辑异常,加上600hz的超高刷新率,碰撞判定会连续触发2次才完成气球的移除操作
修复方案
直接重构check_drone_collect_balloon函数即可,不需要全局的气球坐标变量,逐个判断每个气球的碰撞,先收集待移除的气球再统一处理:
def check_drone_collect_balloon(self): self.get_drone_coordinates() drone_xmax, drone_ymax = self.drone_coordinates[1][0], self.drone_coordinates[1][1] drone_center_x = drone_xmax - self.drone.width/2 drone_center_y = drone_ymax - self.drone.height/2 # 先收集所有要删除的气球,不要边遍历边删 to_remove = [] for balloon in self.balloons: # 每个气球单独计算坐标,不用全局变量避免覆盖 x1, y1 = balloon.pos x2 = x1 + balloon.width y2 = y1 + balloon.height # 单独判断当前气球是否碰撞 if x2 >= drone_center_x >= x1 and y2 >= drone_center_y >= y1: to_remove.append(balloon) # 统一处理移除和计分 for balloon in to_remove: self.balloons.remove(balloon) self.remove_widget(balloon) self.SCORE += 1 if to_remove: print(self.SCORE)
可以同步优化move_balloons函数的移出屏幕逻辑,避免无效气球残留:
def move_balloons(self): out_balloon_list = [] # 直接遍历balloons列表即可,原写法self.children and self.balloons存在逻辑问题 for child in self.balloons: if child.pos[0] < -50 or child.pos[1] > self.height-50: out_balloon_list.append(child) else: child.pos[0] -= 2 child.pos[1] += 3 for balloon in out_balloon_list: self.balloons.remove(balloon) self.remove_widget(balloon)
修改完成后每收集一个气球只会加1分,不会再出现分数异常的问题。
内容的提问来源于stack exchange,提问作者Pyr0
相关产品推荐
相关产品推荐

