需要解包的值超过0(使用tkinter时python坐标变量错误)
我正在用tkinter制作一个太空入侵者的克隆游戏...
问题是,当我的“子弹”因为到达画布边界而被删除时,出现了一个错误,提示ValueError: Need more than 0 values to unpack on a variable assignment(请继续阅读)。这个错误是为了防止“子弹”一直飞出可见区域...
我在这里发布的代码只是我目前整个游戏代码的一小部分,但这段代码和我在实际项目中用的“子弹”行为代码是完全一样的...
我知道这段代码是可以工作的,而且“子弹”确实会消失,换句话说... 它是有效的,但我在控制台上不断收到这个错误。当我把这个函数和其他9个函数(那些让入侵者发射子弹的)一起使用时,程序开始变得卡顿和出错,过了一会儿就停止工作了...
所以我有点怀疑,导致我的程序崩溃的原因就是这个错误,但我不知道该怎么办。
希望你能帮我解决这个问题。谢谢!
附:请原谅我糟糕的英语水平。
from Tkinter import *
import os
def LoadImage(name):
rute = os.path.join('Imagenes',name)
image = PhotoImage(file=rute)
return image
root=Tk()
DxShot= 0 #Globals of Directions on x and y
DyShot= -3
def PlayWindow():
root.withdraw()
VentanaPlay= Toplevel()
VentanaPlay.title("Kill'em all!'")
VentanaPlay.resizable(width=NO, height=NO)
VentanaPlay.geometry("540x540")
def Shot():
x,y= CanvPlay.coords(Ship) #This reads the place from where the shot will have to be created
ShotImage=LoadImage("Shot.gif")
Shot1=CanvPlay.create_image(x, y-22, image=ShotImage)
CanvPlay.img=ShotImage
def ShotMove():
global DxShot, DyShot
x1,y1= CanvPlay.coords(Shot1) #here's where I'm getting the error...
if y1+DyShot<=0:
CanvPlay.delete(Shot1) #Also, if I use destroy instead of delete it says "destroy() takes exactly 1 argument (2 given)"
print("Shot deleted")
CanvPlay.coords(Shot1, x1+DxShot, y1+DyShot)
CanvPlay.after(3,ShotMove)
ShotMove()
VentanaPlay.after(0,ShotMove)
def Fire(event):
Shot()
CanvPlay= Canvas(VentanaPlay, width=540, height=540, bg="white")
CanvPlay.config(cursor="dotbox")
CanvPlay.place(x=-1,y=-1)
CanvPlay.bind("<space>", Fire)
CanvPlay.focus_set()
ShipImage= LoadImage("Ship.gif")
Ship= CanvPlay.create_image(260, 520, image=ShipImage)
VentanaPlay.mainloop()
Buttun= Button(root, text= "click me", command=PlayWindow)
Buttun.pack()
root.mainloop()
这是我收到的完整错误追踪信息:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1470, in __call__
return self.func(*args)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 531, in callit
func(*args)
File "C:/Users/Bryan/Desktop/crap shot", line 28, in ShotMove
x1,y1= CanvPlay.coords(Shot1)
ValueError: need more than 0 values to unpack
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1470, in __call__
return self.func(*args)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 531, in callit
func(*args)
File "C:/Users/Bryan/Desktop/crap shot", line 28, in ShotMove
x1,y1= CanvPlay.coords(Shot1)
ValueError: need more than 0 values to unpack
2 个回答
你需要以某种方式存储一个 Shots(Shot1s)的列表,像你现在这样使用嵌套函数是行不通的。
嵌套函数可能会导致一些混乱的结果,因为 Python 并不会在定义函数时就评估每个变量并存储它,而是在使用时才去访问。所以当你第一次在 Shot() 函数里面调用 ShotMove() 时,解释器会去找一个叫 Shot1 的东西,并且找到了。然而,当你试图把 ShotMove 函数放到 Shot 函数外面去调用时,解释器就找不到任何 Shot1 了(因为它已经不存在了)。我猜那个奇怪的错误(而不是 NameError 或其他错误)可能是因为 Python 在函数最初定义时检查 NameErrors,而不是在每次运行时都检查。
根本问题在于,CanvPlay.coords(Shot1)
返回的是一个空列表或者是 None,而你的代码没有准备好处理这种情况。这种情况可能发生在你删除了你想获取坐标的那个项目时。
实际上,你的 ShotMove
函数里有代码会删除这个射击,然后又试图再次移动这个射击。如果你已经删除了这个射击,可能就不需要再用 after
来移动它了。一个简单的解决办法是把你的 ShotMove 函数改成这样:
def ShotMove():
global DxShot, DyShot
x1,y1= CanvPlay.coords(Shot1) #here's where I'm getting the error...
if y1+DyShot<=0:
CanvPlay.delete(Shot1)
print("Shot deleted")
else:
CanvPlay.coords(Shot1, x1+DxShot, y1+DyShot)
CanvPlay.after(3,ShotMove)
你的代码还有另一个问题,就是你调用了 mainloop
多次。一般来说,你应该只调用一次 mainloop
。这可能是导致你的程序在几秒钟后变得卡顿和出错的原因之一。