为什么 python 海龟图形不断崩溃/停止响应?

Ple*_*r55 5 python turtle-graphics python-turtle

每当我尝试运行我的程序时,它都会绘制两只乌龟,然后窗口停止响应。

我所期待的是,直到其中一个棋子接触到另一棋子(基于我将其拖动到另一棋子附近)为止,我将能够自行拖动它们。但发生的情况是,每当我运行程序时,在绘制两只海龟后,窗口就会停止响应。我没有收到任何错误,它只是在冻结后关闭,直到我单击关闭按钮。我看过其他人的帖子,他们有这个问题,但他们最后没有 screen.mainloop() 而我有。

import turtle

captured_pieces = []

blue = turtle.Turtle()
black = turtle.Turtle()
screen = turtle.Screen()

blue.penup()
black.penup()

blue.shape('square')
black.shape('triangle')

blue.setpos(100,100)
black.setpos(-100,-100)

blue.color('blue')
black.color('black')

def bmove():
    black.ondrag(black.goto)
    if black.distance(blue) < 30:
            captured_pieces.append("BlC")
            print(captured_pieces)
            check()

def blmove():
    blue.ondrag(blue.goto)
    if blue.distance(black) < 30:
            captured_pieces.append("BC")
            print(captured_pieces)
            check()

def check():
      if "BlC" in captured_pieces:
            print("blue captured")

def check():
      if "BC" in captured_pieces:
            print("black captured")

while "BlC" not in captured_pieces and "BC" not in captured_pieces:
      bmove()
      blmove()

screen.mainloop()
Run Code Online (Sandbox Code Playgroud)

ggo*_*len 1

while循环反复执行两件事:添加拖动处理程序并检查距离。该循环不会调用任何导致turtle 的渲染/事件循环运行的turtle 方法(例如,.forward().goto()),因此距离检查不能为true 以打破循环。我们想要mainloop()实现用户交互,但除非允许用户交互,否则我们无法实现这一目标——我们陷入了困境。

避免循环(您通常不想while在实时海龟程序中使用)并检查拖动处理程序内部而不是循环中的碰撞,然后运行mainloop()海龟渲染循环。

这揭示了一个新问题:内部循环的“滑动”速度导致拖动非常不稳定。您可以用来tracer(0)禁用内部循环并turtle.update()在需要时手动触发重绘,从而消除任何滑动行为并让您完全控制重新渲染。

这是一个简单的例子:

import turtle


turtle.tracer(0)
blue = turtle.Turtle()
black = turtle.Turtle()
screen = turtle.Screen()
blue.penup()
black.penup()
blue.shape("square")
black.shape("triangle")
blue.setpos(100, 100)
black.setpos(-100, -100)
blue.color("blue")
black.color("black")


def handle_drag(piece, other, x, y):
    piece.goto(x, y)
    turtle.update()

    if piece.distance(other) < 30:
        print("capture:", piece.color()[0], other.color()[0])


black.ondrag(lambda x, y: handle_drag(black, blue, x, y))
blue.ondrag(lambda x, y: handle_drag(blue, black, x, y))
turtle.update()
screen.mainloop()
Run Code Online (Sandbox Code Playgroud)

不久之后,您可能会需要自定义类(例如类Piece,它可能会由具有不同特征的各种类型的片段进行子类化)和数据结构。上述使用单独变量的方法不可扩展。但为了解决您眼前的问题,我将暂时保留它。