每当我尝试运行我的程序时,它都会绘制两只乌龟,然后窗口停止响应。
我所期待的是,直到其中一块接触到另一块基于我将它拖动到另一块附近时,我将能够自己拖动它们。但发生的事情是,每当我运行程序时,在绘制完两只海龟后,窗口就会停止响应。我没有收到任何错误,它只是在冻结后关闭,直到我单击关闭按钮。我看过其他人的帖子,他们遇到了这个问题,但他们最后没有 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()
while
循环一遍又一遍地做两件事:添加拖动处理程序,并检查距离。该循环不会调用任何导致海龟的渲染/事件循环运行的海龟方法(例如,.forward()
或 .goto()
),因此距离检查始终为假。我们想要到达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()
不久之后,您可能需要自定义类(例如
Piece
类,它可能被具有不同特征的各种类型的片段子类化)和数据结构。上面使用单独变量的方法不可扩展。但我暂时保留它,以便将它限制在您眼前的问题范围内。