Python Turtle开发战舰游戏时窗口崩溃与函数执行异常求助
解决Python Turtle战舰游戏的窗口崩溃与函数执行问题
首先,我们先梳理你遇到的核心问题:
- 调用
speelveld()绘制棋盘后,不加turtle.done()窗口会崩溃;加了之后,后续的veldkleuren()函数无法执行。 - 另外你的代码存在缩进错误,函数内部的代码没有正确缩进,这会导致函数逻辑无法正常执行,也是引发问题的原因之一。
问题原因解析
- 缩进错误:Python是缩进敏感语言,
def定义函数后,函数体所有代码必须缩进(通常4个空格),否则只有第一行属于函数,其余代码会在全局作用域执行,导致逻辑混乱。 turtle.done()的作用:这个函数会启动Turtle的主事件循环,它会一直阻塞程序直到用户关闭窗口,所以后面的代码(比如veldkleuren())永远不会被执行。- 无事件循环导致窗口崩溃:如果不加
turtle.done(),程序执行到input()时会阻塞主线程,而Turtle窗口需要事件循环来处理刷新、交互等操作,主线程被阻塞后窗口无法响应,就会出现“崩溃”或无响应的情况。
修复后的完整代码
我们会做以下调整:
- 修正函数内部的缩进问题
- 用Turtle内置的
turtle.textinput()替代命令行的input(),这样可以在图形窗口中弹出输入框,不会阻塞事件循环 - 最后在所有操作完成后调用
turtle.done()维持窗口
import turtle def speelveld(): turtle.ht() x = 200 y = 200 turtle.tracer(10, 0) # 绘制棋盘格子 for _ in range(10): y -= 40 turtle.penup() turtle.goto(0, y) turtle.pendown() x = 200 for _ in range(10): x -= 40 turtle.goto(x, y) # 绘制单个正方形 for _ in range(4): turtle.forward(40) turtle.left(90) # 绘制数字坐标(左侧) y = 170 coordsN = ['1','2','3','4','5','6','7','8','9','10'] for i in range(10): turtle.penup() turtle.goto(-220, y) turtle.pendown() turtle.write(coordsN[i], font=("Calibri", 14, "normal")) y -= 40 # 绘制字母坐标(顶部) x = -180 coordsL = ['A','B','C','D','E','F','G','H','I','J'] for i in range(10): turtle.penup() turtle.goto(x, 205) turtle.pendown() turtle.write(coordsL[i], font=("Calibri", 14, "normal")) x += 40 def veldkleuren(): # 使用Turtle的文本输入框替代命令行input gok = turtle.textinput("战舰游戏", "Typ een coördinaat in: ") if not gok: return # 用户取消输入时退出 x = 0 y = 0 valid = True # 解析纵坐标(数字) num_part = ''.join([c for c in gok if c.isdigit()]) if num_part == '1': y = 150 elif num_part == '2': y = 110 elif num_part == '3': y = 70 elif num_part == '4': y = 30 elif num_part == '5': y = -10 elif num_part == '6': y = -50 elif num_part == '7': y = -90 elif num_part == '8': y = -130 elif num_part == '9': y = -170 elif num_part == '10': y = -210 else: turtle.textinput("错误", "Ongeldige invoer (ongeldig nummer)") valid = False # 解析横坐标(字母) letter_part = ''.join([c.upper() for c in gok if c.isalpha()]) if letter_part == 'A': x = -190 elif letter_part == 'B': x = -150 elif letter_part == 'C': x = -110 elif letter_part == 'D': x = -70 elif letter_part == 'E': x = -30 elif letter_part == 'F': x = 10 elif letter_part == 'G': x = 50 elif letter_part == 'H': x = 90 elif letter_part == 'I': x = 130 elif letter_part == 'J': x = 170 else: turtle.textinput("错误", "Ongeldige invoer (ongeldige letter)") valid = False if valid: turtle.penup() turtle.goto(x, y) turtle.pendown() turtle.write('X', font=("Calibri", 39, "normal")) # 执行流程 speelveld() veldkleuren() turtle.done() # 最后启动事件循环维持窗口
额外优化说明
- 替换了
input()为turtle.textinput():这样用户在图形窗口中输入坐标,不会阻塞Turtle的事件循环,避免窗口无响应。 - 优化了坐标解析:分离输入中的字母和数字部分,避免用户输入格式(如"A1"或"1A")导致的错误。
- 移除了不必要的全局变量:函数内部使用局部变量,避免全局变量污染。
- 增加了输入验证反馈:当输入无效时,弹出提示框告知用户。
内容的提问来源于stack exchange,提问作者Bart S.




