Python海龟游戏报错_tkinter.TclError : invalid command name ".!canvas"

标签 python tkinter python-turtle

我已经使用 python turtle 编写了一个小游戏,似乎每当我手动关闭 turtle 窗口时它都会给我一个错误,但如果游戏完成运行然后我关闭它就可以了。我认为它与代码的 ontimer 部分有关,但我不确定如何修复它。

import turtle
from random import randint


wn = turtle.Screen()
circle1 = turtle.Turtle(shape = 'circle')
bullet = turtle.Turtle(shape = "circle")
bullet.ht()
bullet.speed(0)
circle1.speed(-1)
circle1.penup()
circle1.ht()
circle1.sety(-270)
circle1.st()

wn.setup(300, 600)

enemies = []
score = 0
prevscore = 1
speed = 10


for i in range(10):
    p = turtle.Turtle(shape='square',visible=False)
    p.speed(0)
    p.penup()
    p.color('blue')
    x = randint(-240,240)
    y = randint(180,360)
    p.goto(x,y)
    p.showturtle()
    enemies.append(p)

def enemy_move():
    global game_on
    global speed
    global score
    global prevscore

    for p in enemies:

        y = p.ycor()
        p.sety(y-speed)

        if p.ycor() < -300  or p.distance(bullet.pos())<30:
            if p.distance(bullet.pos())<30:
                score += 1
            p.hideturtle()
            y = randint(180,360)
            p.sety(y)
            p.showturtle()

        if circle1.isvisible() and p.distance(circle1.pos())<20:
            p.hideturtle()
            circle1.hideturtle()
            game_on = False
            wn.clear()
            circle1.goto(0, 0)
            circle1.write(f"Your final score is {score}", align ="center", font = ("Arial", 26, "normal"))


    if game_on == True:

        if score%10 == 0:

            if score != prevscore:
                speed += 0.5
            prevscore = score

        wn.ontimer(enemy_move,50)

    else:
        return

game_on = True
enemy_move()

def goright():
    if(circle1.xcor() < 130):
        circle1.seth(0)
        circle1.fd(10)
def goleft():
    if(circle1.xcor() > -130):
        circle1.seth(180)
        circle1.fd(10)

def shoot():
    bullet.penup()
    bullet.goto(circle1.pos())
    bullet.seth(90)
    bullet_move()
    bullet.showturtle()

def bullet_move():
    if bullet.ycor() <= 300:
        bullet.sety(bullet.ycor() + 10)
        wn.ontimer(bullet_move, 50)
    else:
        bullet.hideturtle()


wn.listen()

wn.onkeypress(goright, "Right")
wn.onkeypress(goleft, "Left")
wn.onkeypress(shoot, "Up")

wn.mainloop()

我手动退出代码时得到的错误是这样的:

Traceback (most recent call last):
  File "/Users/luke/PycharmProjects/Class Teaching/Game interface example.py", line 1, in <module>
    import game
  File "/Users/luke/PycharmProjects/Class Teaching/game.py", line 31, in <module>
    p.goto(x,y)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/turtle.py", line 1777, in goto
    self._goto(Vec2D(x, y))
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/turtle.py", line 3159, in _goto
    screen._pointlist(self.currentLineItem),
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/turtle.py", line 756, in _pointlist
    cl = self.cv.coords(item)
  File "<string>", line 1, in coords
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/tkinter/__init__.py", line 2762, in coords
    self.tk.call((self._w, 'coords') + args))]
_tkinter.TclError: invalid command name ".!canvas"

最佳答案

这是由 enemy_move() 中的 for 循环 引起的。如果您尝试通过销毁窗口退出应用程序,则 for 循环可能仍在运行,因此访问已经销毁的 Canvas 会引发异常。

您可以在 for 循环的每次迭代开始时检查 game_on:

def enemy_move():
    ...
    for p in enemies:
        # exit the function is game_on is False
        if not game_on:
            return
        ...
    ...

然后你需要在销毁窗口之前将game_on设置为False。可以使用 tkinter.protocol() 来完成(因为 turtle 是建立在 tkinter 上的):

...
def on_quit():
    global game_on
    game_on = False
    # give some time to stop the for loop before destroying window
    wn._root.after(100, wn._root.destroy)

wn._root.protocol("WM_DELETE_WINDOW", on_quit)

wn.mainloop()

关于Python海龟游戏报错_tkinter.TclError : invalid command name ".!canvas",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68719923/

相关文章:

python - 我如何隐藏 turtle 以前画的东西?

python - 有没有办法让 python 中的海龟运行我创建的随机函数?

python - 如何让 Twisted 使用 Python 日志记录?

python - Python 3 的部分总和

python - 除了 celery 之外,django/wsgi 中的后台 worker 、异步延迟任务队列还有什么选择?

python - 如何在 keras 模型中使用 tensorflow 度量函数?

python - 如何使用 tkinter 创建聊天窗口?

python - 如果鼠标移动,Tkinter After Loop 只运行到时间

python - 覆盖 Python Tkinter 中的默认选项卡行为

python - Turtle Onkey - 输入键