Python Turtle贪吃蛇游戏超级食物计时功能实现求助
问题:贪吃蛇超级食物5秒自动消失逻辑失效
已用Python Turtle库完成贪吃蛇游戏,现需添加超级食物功能:
- 当玩家得分达到
BONUS_SCORE_OCCUR(当前设为3)的倍数时,生成超级食物 - 超级食物可提供5倍积分,仅存在5秒
最初将计时逻辑封装到SuperFood类中导致游戏卡顿,移到main.py的主循环后调试一整天,仍无法实现自动消失效果。目前猜测线程可能解决问题,但希望不用线程实现。
当前main.py代码
from turtle import Screen from snake import Snake from food import Food from super_food import SuperFood from scoreboard import Scoreboard import time SPEED_IN_TIME = 0.1 ACCURACY = 45 # 判定吃到食物的距离阈值 ACCURACY_COLLISION = 10 BONUS_SCORE_OCCUR = 3 SUPER_FOOD_DURATION = 5 super_food_exists = False # 标记超级食物是否存在 start_time = 0 # 超级食物生成的起始时间 screen = Screen() screen.setup(width=600, height=600) Y_EDGE = screen.window_height() // 2 X_EDGE = screen.window_height() // 2 screen.bgcolor("black") screen.title("My Snake Game with super food Gemini Version") screen.tracer(0) # 关闭自动动画,避免移动卡顿 snake = Snake() food = Food() super_food = SuperFood() scoreboard = Scoreboard() screen.listen() screen.onkey(snake.up, "Up") screen.onkey(snake.down, "Down") screen.onkey(snake.left, "Left") screen.onkey(snake.right, "Right") game_is_on = True while game_is_on: screen.update() time.sleep(SPEED_IN_TIME) snake.move() # 检测普通食物碰撞 if snake.head.distance(food) < ACCURACY: food.refresh() scoreboard.increase_score() snake.extend() # 检测边界碰撞 if snake.head.xcor() > X_EDGE or snake.head.xcor() < -X_EDGE or snake.head.ycor() > Y_EDGE or snake.head.ycor() < -Y_EDGE: game_is_on = False scoreboard.game_over() # 检测蛇身自碰撞 for segment in snake.turtle_segments[1:]: if snake.head.distance(segment) < ACCURACY_COLLISION: game_is_on = False scoreboard.game_over() # 超级食物逻辑 if scoreboard.score != 0: if scoreboard.score % BONUS_SCORE_OCCUR == 0: super_food_exists = True start_time = time.time() # 每次满足条件都重置计时,导致永远不会超时 if super_food_exists: if time.time() - start_time < SUPER_FOOD_DURATION: print(f"Time check: {time.time() - start_time < SUPER_FOOD_DURATION}") print(f"Time check: {int(time.time() - start_time)}") super_food.unhide() else: super_food.hide() super_food_exists = False screen.exitonclick()
问题根源
当前代码的核心问题是:只要得分保持为BONUS_SCORE_OCCUR的倍数,主循环每次都会重置start_time为当前时间,导致time.time() - start_time永远小于5秒,超级食物永远不会消失。比如得分到3后,只要玩家没继续吃食物,每次循环都会执行start_time = time.time(),计时永远无法走到5秒。
无线程解决方案
添加一个变量标记当前分数是否已经生成过超级食物,避免重复重置计时:
修改后的超级食物逻辑代码
# 新增变量:标记当前分数是否已生成过超级食物 super_food_spawned_for_score = -1 while game_is_on: # ... 保留原有循环内的其他代码 ... # 超级食物逻辑 if scoreboard.score != 0: current_score = scoreboard.score # 仅当得分是指定倍数,且当前分数未生成过超级食物时,才生成 if current_score % BONUS_SCORE_OCCUR == 0 and super_food_spawned_for_score != current_score: super_food_exists = True start_time = time.time() super_food.refresh() # 假设SuperFood类有refresh方法,生成新位置 super_food.unhide() super_food_spawned_for_score = current_score # 标记当前分数已生成过 if super_food_exists: # 检测超级食物碰撞 if snake.head.distance(super_food) < ACCURACY: super_food.hide() super_food_exists = False scoreboard.increase_score(5) # 增加5倍积分 snake.extend() super_food_spawned_for_score = -1 # 重置标记 elif time.time() - start_time >= SUPER_FOOD_DURATION: super_food.hide() super_food_exists = False super_food_spawned_for_score = -1 # 重置标记,允许下一个倍数分数生成 screen.exitonclick()
额外优化点
- 给
SuperFood类添加refresh()方法,生成超级食物时随机切换位置,避免和普通食物重叠 - 移除调试用的
print语句,减少性能消耗 - 调整碰撞检测的顺序,优先处理吃到超级食物的逻辑,避免计时到了才处理碰撞
内容的提问来源于stack exchange,提问作者MotionX
相关产品推荐
相关产品推荐

