Python turtle更新屏幕触发raise Terminator错误的解决方法
问题分析
turtle.Terminator错误是Python turtle库做游戏时的常见报错,你的代码里有4处直接触发该错误的逻辑问题:
- 主循环写法冲突:同时使用
while True无限阻塞循环和t.mainloop()事件循环,两个逻辑抢占主线程资源,窗口关闭后无限循环还在调用t.update()操作已销毁的画布,直接触发终止异常 - 蛇身清空逻辑写错:撞到自身身体的重置代码块中,遍历蛇身的临时变量名和蛇身列表重名,最后调用
segment.clear()只清空了最后一节蛇身的绘制内容,没有清空segments列表,后续操作列表里已失效的海龟对象会触发异常 - 方向值大小写不统一:初始化蛇头方向用的是大写开头的
"Stop",撞身体重置时写的是小写开头的"stop",会导致方向判断逻辑失效,蛇重置后可能直接反向移动撞自己触发异常 - 帧率控制方式不兼容:用
time.sleep()做全局阻塞会打断turtle的按键事件监听,长时间阻塞后画布刷新失效也会抛Terminator错误
修复步骤
- 移除
while True无限循环,把游戏主逻辑封装为独立函数,用turtle内置的ontimer()方法做定时调度,和主事件循环兼容 - 修正蛇身重置时的变量名错误,把
segment.clear()改为segments.clear() - 统一所有方向值的大小写,全部用大写开头的
"Stop" - 移除冗余的
time.sleep()调用,通过ontimer的时间参数控制游戏延迟 - 给画布刷新操作加简单异常捕获,避免手动关窗口时抛出报错
修复后可运行的完整代码
import turtle import random delay = 0.1 score = 0 high_score = 0 # 初始化窗口 t = turtle.Screen() t.title("Snake Xenzia") t.bgcolor("skyblue") t.setup(width=600, height=600) t.tracer(0) # 初始化蛇头 head = turtle.Turtle() head.shape("square") head.color("white") head.penup() head.goto(0, 0) head.direction = "Stop" # 初始化食物 food = turtle.Turtle() colors = random.choice(['red', 'green', 'blue']) shapes = random.choice(['square', 'triangle', 'circle']) food.speed(0) food.shape(shapes) food.color(colors) food.penup() food.goto(0, 100) # 初始化计分板 pen = turtle.Turtle() pen.speed(0) pen.shape("square") pen.color("white") pen.penup() pen.hideturtle() pen.goto(0, 250) pen.write("Score : 0 High Score : 0", align="center", font=("candara", 24, "bold")) # 方向控制函数 def wkey(): if head.direction != "down": head.direction = "up" def skey(): if head.direction != "up": head.direction = "down" def akey(): if head.direction != "right": head.direction = "left" def dkey(): if head.direction != "left": head.direction = "right" def move(): if head.direction == "up": y = head.ycor() head.sety(y+20) if head.direction == "down": y = head.ycor() head.sety(y-20) if head.direction == "left": x = head.xcor() head.setx(x-20) if head.direction == "right": x = head.xcor() head.setx(x+20) # 绑定按键 t.listen() t.onkeypress(wkey, "w") t.onkeypress(skey, "s") t.onkeypress(akey, "a") t.onkeypress(dkey, "d") segments = [] # 游戏主逻辑 def game_loop(): global delay, score, high_score try: t.update() except turtle.Terminator: return # 撞墙判定 if head.xcor() > 290 or head.xcor() < -290 or head.ycor() > 290 or head.ycor() < -290: head.goto(0, 0) head.direction = "Stop" random.choice(['red', 'blue', 'green']) random.choice(['square', 'circle']) for segment in segments: segment.goto(1000, 1000) segments.clear() score = 0 delay = 0.1 pen.clear() pen.write("Score : {} High Score : {} ".format(score, high_score), align="center", font=("candara", 24, "bold")) # 吃食物判定 if head.distance(food) < 20: x = random.randint(-270, 270) y = random.randint(-270, 270) food.goto(x, y) # 新增蛇身 new_segment = turtle.Turtle() new_segment.speed(0) new_segment.shape("square") new_segment.color("orange") new_segment.penup() segments.append(new_segment) delay -= 0.001 score += 10 if score > high_score: high_score = score pen.clear() pen.write("Score : {} High Score : {} ".format(score, high_score), align="center", font=("candara", 24, "bold")) # 蛇身跟随移动 for index in range(len(segments)-1, 0, -1): x = segments[index-1].xcor() y = segments[index-1].ycor() segments[index].goto(x, y) if len(segments) > 0: x = head.xcor() y = head.ycor() segments[0].goto(x, y) move() # 撞自身判定 for segment in segments: if segment.distance(head) < 20: head.goto(0, 0) head.direction = "Stop" random.choice(['red', 'blue', 'green']) random.choice(['square', 'circle']) for segment in segments: segment.goto(1000, 1000) segments.clear() score = 0 delay = 0.1 pen.clear() pen.write("Score : {} High Score : {} ".format(score, high_score), align="center", font=("candara", 24, "bold")) # 定时调度下一次循环,替代time.sleep t.ontimer(game_loop, int(delay * 1000)) # 启动游戏 game_loop() t.mainloop()
内容的提问来源于stack exchange,提问作者Shriroop
相关产品推荐
相关产品推荐

