在Spyder上不断出现错误,请告知
问题描述
这是我收到的错误:
invalid command name "1771926755840move"
while executing
"1771926755840move"
("after" script)
invalid command name "1771922102464move"
while executing
"1771922102464move"
("after" script)
invalid command name "1771947147520move"
while executing
"1771947147520move"
("after" script)
Tcl_AsyncDelete: async handler deleted by the wrong thread
以下是我的代码:
from turtle import *
from random import *
from freegames import vector
from playsound import playsound
import winsound
from tkinter import *
from timeit import default_timer as timer
from datetime import timedelta
from threading import Event
"""
def paused():
Event.wait()
def unpaused():
Event.release()
"""
root = Tk()
root.title("OPTIONS")
def stop():
bye()
winsound.PlaySound(None, winsound.SND_PURGE)
def gamingarea():
bird = vector(0, 0)
balls = []
winsound.PlaySound('C:/Users/SONY/Desktop/cs.wav', winsound.SND_LOOP + winsound.SND_ASYNC)
start = timer()
def tap(x, y):
lift = vector(0, 30)
bird.move(lift)
def inside(point):
return -200 < point.x < 200 and -200 < point.y < 200
def draw(alive):
clear()
goto(bird.x, bird.y)
if alive:
dot(20, "green")
else:
dot(20, "red")
winsound.PlaySound(None, winsound.SND_PURGE)#when bird is red, music stops
end = timer()
color("orange")
write(str(timedelta(seconds=end-start)), align = "center", font=("Comic Sans MS", 20, "normal", "bold"))
for ball in balls:
goto(ball.x, ball.y)
dot(20, "black")
update()
def move():
bird.y -= 5
for ball in balls:
ball.x -= 3
if randrange(10) == 0:
y = randrange(-199, 199)
ball = vector(199, y)
balls.append(ball)
while len(balls) > 0 and not inside(balls[0]):
balls.pop(0)
if not inside(bird):
draw(False)
return
for ball in balls:
if abs(ball - bird) < 15:
draw(False)
return
draw(True)
ontimer(move, 50)
title("Dodgy Ball")
setup(420, 420)
hideturtle()#turtle is hidden
up()
tracer(False)#Used to turn off animations. When false, animations are turned off. It also turns off automatic updates
onscreenclick(tap)#calling the tap function when touchpad is touched
move()
bgcolor("blue")
done()
startbutton = Button(root, text = "START", padx=100,pady=100, command=gamingarea)
endbutton = Button(root, text = "KILL!", padx=100,pady=100, command=stop)
#pausebutton = Button(root, text = "PAUSE!", padx = 100, pady = 100, command=paused)
#unpausebutton = Button(root, text = "UNPAUSE", padx = 100, pady = 100, command = unpaused)
startbutton.pack()
endbutton.pack()
#pausebutton.pack()
#unpausebutton.pack()
root.mainloop()
PS:这是我和朋友一起设计的游戏
谢谢
解决方案
问题仅在游戏正在运行(鸟是活的)并且您试图杀死游戏时才会出现。
当您按kill it
时,它会运行turtle.bye()
,这将删除所有对象并移除窗口,但它不会停止仍要运行move()
并绘制对象的ontimer()
(但它们不再存在,这会给出消息invalid command name "1771926755840move"
)。
当您按kill it
时,它应该设置变量ie。running = False
def stop():
global running
running = False
应签入move
以停止循环并关闭窗口
if running:
# repeate loop and run `move` again
turtle.ontimer(move, 50)
else:
# stop loop and close window
turtle.bye()
#winsound.PlaySound(None, winsound.SND_PURGE)
我的减少了模块的版本。
我创建了自己的类vector
,所以我不需要freegames
,因为我不知道。
我使用datetime
而不是timeit
是因为end-start
可以直接提供timedelta
。
我注释了winsound
,因为它只适用于Windows
,但我使用的是Linux
。
我为paused
、unpased
添加了代码,它不需要Threading
。
#from turtle import * # PEP8: `import *` is not preferred
#from random import * # PEP8: `import *` is not preferred
#from tkinter import * # PEP8: `import *` is not preferred
import turtle
import tkinter as tk
import random
import datetime
#import winsound
# --- classes ---
class vector():
def __init__(self, x, y):
self.x = x
self.y = y
def move(self, other):
self.x += other.x
self.y += other.y
def __sub__(self, other):
return vector(self.x - other.x, self.y - other.y)
def __abs__(self):
return (self.x**2 + self.y**2)**0.5
# --- functions ---
def paused():
global pause
pause = True
def unpaused():
global pause
pause = False
def stop():
global running
if running:
# stop loop `ontimer(move, 50)`
running = False
else:
# exit when bird is dead
turtle.bye()
#winsound.PlaySound(None, winsound.SND_PURGE)
def gamingarea():
global running
global pause
running = True
pause = False
bird = vector(0, 0)
balls = []
#winsound.PlaySound('C:/Users/SONY/Desktop/cs.wav', winsound.SND_LOOP + winsound.SND_ASYNC)
start = datetime.datetime.now()
def tap(x, y):
lift = vector(0, 30)
bird.move(lift)
def inside(point):
return -200 < point.x < 200 and -200 < point.y < 200
def draw(alive):
global running
turtle.clear()
turtle.goto(bird.x, bird.y)
if alive:
turtle.dot(20, "green")
else:
turtle.dot(20, "red")
#winsound.PlaySound(None, winsound.SND_PURGE)#when bird is red, music stops
turtle.color("orange")
end = datetime.datetime.now()
diff = end-start
turtle.write(str(diff.seconds), align = "center", font=("Comic Sans MS", 20, "normal", "bold"))
running = False
for ball in balls:
turtle.goto(ball.x, ball.y)
turtle.dot(20, "black")
turtle.update()
def move():
if not pause:
bird.y -= 5
for ball in balls:
ball.x -= 3
if random.randrange(10) == 0:
y = random.randrange(-199, 199)
ball = vector(199, y)
balls.append(ball)
while len(balls) > 0 and not inside(balls[0]):
balls.pop(0)
if not inside(bird):
draw(False)
return
for ball in balls:
if abs(ball - bird) < 15:
draw(False)
return
draw(True)
if running:
# repeate loop `ontimer(move, 50)`
turtle.ontimer(move, 50)
else:
# stop loop `ontimer(move, 50)` and exit
turtle.bye()
#winsound.PlaySound(None, winsound.SND_PURGE)
turtle.title("Dodgy Ball")
turtle.setup(420, 420)
turtle.hideturtle() # turtle is hidden
turtle.up()
turtle.tracer(False) # Used to turn off animations. When false, animations are turned off. It also turns off automatic updates
turtle.onscreenclick(tap) # calling the tap function when touchpad is touched
move()
turtle.bgcolor("blue")
turtle.done()
# --- main ---
root = tk.Tk()
root.title("OPTIONS")
start_button = tk.Button(root, text="START", padx=100,pady=100, command=gamingarea)
end_button = tk.Button(root, text="KILL!", padx=100,pady=100, command=stop)
pause_button = tk.Button(root, text="PAUSE!", padx=100, pady=100, command=paused)
unpause_button = tk.Button(root, text="UNPAUSE", padx=100, pady=100, command=unpaused)
start_button.pack(fill='both')
end_button.pack(fill='both')
pause_button.pack(fill='both')
unpause_button.pack(fill='both')
root.mainloop()
坦率地说,如果您使用
tkinter to display buttons then you could use
tkinter.Canvasto draw objects, and
tkinter.bind()to run
tap, and
root.after()instead of
ontimer()to run loop - and then you don't need
turtle`
相关文章