我已经用Python编写了自己的2048游戏版本。当我从它的主类执行它时,它工作得很好:
class _2048:
def __init__(self):
...
...
...
test = _2048()
该类还具有Tkinter和Tkinter.Canvas对象,还有另一个名为Tile的类,在该类中,我具有相对于每个单个tile的所有功能。
现在,我正在尝试编写一个自动控制游戏的类。让我解释一下:在2048类中,我绑定了上,下,右和左箭头键。它们共享相同的回调函数,在这里我使用event.keycode值来决定要做什么。为了模拟此事件,我创建了一个名为Kevent的类,如下所示:
class Kevent:
def __init__(self, mov):
if(mov=="n"):
self.keycode = 38
elif(mov=="s"):
self.keycode = 40
elif(mov=="e"):
self.keycode = 39
elif(mov=="w"):
self.keycode = 37
(我知道那不是很漂亮)。最后,我有Test类,其中有_2048类的实例和Kevent类的实例:
class Test:
joc: _2048
event: Kevent
def __init__(self):
self.joc = _2048()
self.event = Kevent("s")
sleep(1)
self.joc.tecla(self.event)
test = Test()
当我运行上面的代码时,它什么也没有发生,但是当我关闭2048窗口时,出现以下错误:
self.tk.call((self._w, 'move') + args)
_tkinter.TclError: invalid command name ".!canvas"
它在此函数内部(在Tile类内部)失败,在其中我将2048的Canvas中的元素移动到该位置:
def mou_canvas(self, canvas):
# moviment is a class where I control the moves of the "self" tile
moviment = self.moviment
# quadrat is the Canvas id for the square of the tile
quadrat = self.getQuadrat()
# text is the Canvas id for the text inside the tile
text = self.getText()
(dx,dy) = moviment.getMov()
score = 0
# If the tile can move
if(moviment.getPot_moure()):
canvas.move(quadrat, 100*dx, 100*dy) # <---- The error occurs in this line
canvas.move(text, 100*dx, 100*dy)
canvas.update_idletasks()
# If there is a collision
if(moviment.getColisiona()):
mult = moviment.getMult_colisio()
if(mult == 0):
canvas.delete(quadrat)
canvas.delete(text)
else:
score = self.getNum()*2
self.setNum(score)
canvas.tag_raise(quadrat)
canvas.tag_raise(text)
fontsize = 30 if(score<1024) else 20 if(score<100000) else 15
canvas.itemconfig(text, text=str(self.getNum()), font=("Arial Black", fontsize))
self.moviment.reset()
return score
我想解决方案必须非常简单,但是我花了几个小时解决了这个问题,但是还没有发现。
编辑:我通过在新线程中执行_2048类来解决问题:
class _2048(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.start()
def run(self):
# Everything I had in old __init__ method
...
...
...
我通过在新线程中执行_2048类解决了这个问题:
class _2048(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.start()
def run(self):
# Everything I had in old __init__ method
...
...
...