名称错误:名称';自我';从类内调用方法时未定义Python
我正在尝试使用Tkinter库用python制作一个类似于砖块分解器的游戏。我有一个运行良好的早期版本的代码,但是由于缩进中的错误,所有函数都在名称错误:名称';自我';从类内调用方法时未定义Python,python,python-3.x,tkinter,Python,Python 3.x,Tkinter,我正在尝试使用Tkinter库用python制作一个类似于砖块分解器的游戏。我有一个运行良好的早期版本的代码,但是由于缩进中的错误,所有函数都在\uuuuu init\uuuu中。当我纠正了这个错误,然后添加了一些功能使它成为一个可玩的游戏时,我的主动画循环停止了工作。我阅读了其他文章,其中显示这是一个间距错误,并验证了这不是使用python-tt。更新:self.moveBall()已移动到\uuuu init\uuuu中,但moveBall()仍不运行 from tkinter import
\uuuuu init\uuuu
中。当我纠正了这个错误,然后添加了一些功能使它成为一个可玩的游戏时,我的主动画循环停止了工作。我阅读了其他文章,其中显示这是一个间距错误,并验证了这不是使用python-tt
。更新:self.moveBall()
已移动到\uuuu init\uuuu
中,但moveBall()
仍不运行
from tkinter import *
class Application(Frame):
def __init__(self):
# Constructing the Screen
root = Tk()
Frame.__init__(self)
self.canvas = Canvas(root, width=800, height=400)
# Label
self.v = StringVar()
self.l = 5
self.label = Label(root, textvariable=self.v, font=('Courier',
20), bg='white', width=50)
self.v.set('Lives: ' + str(self.l))
self.label.grid()
self.canvas.grid()
# Ball
self.canvas.create_oval(
2,
2,
22,
22,
fill='red',
tags='ball',
)
# Paddle
self.canvas.create_rectangle(
360,
380,
440,
400,
fill='black',
tag='paddle',
)
# Keybindings
self.canvas.focus_set()
self.canvas.bind('<Left>', self.paddleLeft)
self.canvas.bind('a', self.paddleLeft)
self.canvas.bind('<Button-1>', self.paddleLeft)
self.canvas.bind('<Right>', self.paddleRight)
self.canvas.bind('d', self.paddleRight)
self.canvas.bind('<Button-3>', self.paddleRight)
# Logic
self.horizontal_direction = 'east'
self.vertical_direcction = 'south'
self.moveBall()
def collide(self):
(x1, y1, x2, y2) = self.canvas.coords('ball')
(px1, py1, px2, py2) = self.canvas.coords('paddle')
if x2 >= 800:
self.horizontal_direction = 'west'
if x1 <= 0:
self.horizontal_direction = 'east'
if y1 <= 0:
self.vertical_direcction = 'south'
if y2 >= 400:
self.l -= 1
self.v.set('Lives: ' + str(self.l))
self.vertical_direcction = 'north'
if y2 >= py1:
if x1 in range(int(px1), int(px2)) or x2 in range(int(px1),
int(px2)):
self.vertical_direcction = 'north'
def moveBall(self):
while True:
if self.horizontal_direction == 'east':
self.canvas.move('ball', 2, 0)
else:
self.canvas.move('ball', -2, 0)
if self.vertical_direcction == 'south':
self.canvas.move('ball', 0, 2)
else:
self.canvas.move('ball', 0, -2)
self.canvas.after(15)
self.collide()
self.canvas.update()
def paddleLeft(self, event):
(px1, py1, px2, py2) = self.canvas.coords('paddle')
if px1 >= 0:
self.canvas.move('paddle', -5, 0)
self.canvas.after(15)
self.canvas.update()
def paddleRight(self, event):
(px1, py1, px2, py2) = self.canvas.coords('paddle')
if px2 <= 800:
self.canvas.move('paddle', 5, 0)
self.canvas.after(15)
self.canvas.update()
def main():
app = Application()
app.mainloop()
main()
从tkinter导入*
课程申请(框架):
定义初始化(自):
#构建屏幕
root=Tk()
帧。\uuuu初始化\uuuuu(自)
self.canvas=canvas(根,宽度=800,高度=400)
#标签
self.v=StringVar()
自升=5
self.label=label(root,textvariable=self.v,font=('Courier',),
20) ,bg='白色',宽度=50)
self.v.set('lifes:'+str(self.l))
self.label.grid()
self.canvas.grid()
#球
self.canvas.create_oval(
2.
2.
22,
22,
填写“红色”,
“球”,
)
#划桨
self.canvas.create_矩形(
360,
380,
440,
400,
填充“黑色”,
标记为“划桨”,
)
#键绑定
self.canvas.focus_set()
self.canvas.bind(“”,self.left)
self.canvas.bind('a',self.left)
self.canvas.bind(“”,self.left)
self.canvas.bind(“”,self.battleright)
self.canvas.bind('d',self.bright)
self.canvas.bind(“”,self.battleright)
#逻辑
自水平方向='east'
自垂直方向='南'
self.moveBall()
def碰撞(自):
(x1,y1,x2,y2)=自画布坐标('球')
(px1,py1,px2,py2)=self.canvas.coords('blade'))
如果x2>=800:
self.horizontal\u方向='west'
如果x1=py1:
如果x1在范围内(int(px1)、int(px2))或x2在范围内(int(px1),
int(px2)):
自垂直方向='north'
def移动球(自身):
尽管如此:
如果self.horizontal_direction=='east':
self.canvas.move('ball',2,0)
其他:
self.canvas.move('ball',-2,0)
如果self.vertical\u direction==“南”:
self.canvas.move('ball',0,2)
其他:
self.canvas.move('ball',0,-2)
self.canvas.after(15)
self.collide()
self.canvas.update()
def左(自身、事件):
(px1,py1,px2,py2)=self.canvas.coords('blade'))
如果px1>=0:
self.canvas.move('blade',-5,0)
self.canvas.after(15)
self.canvas.update()
右(自身、事件):
(px1,py1,px2,py2)=self.canvas.coords('blade'))
如果px2我做了这样的事情:
它使用self.root
,因此我可以在moveBall
中使用self.root.after(15,moveBall)
,它在15毫秒后再次运行moveBall
,我不需要而为True
。我不需要canvas.after(15)
和canvas.update()
我从类应用程序(Frame):
中删除了Frame
,因为您将所有小部件直接添加到root
,而这个Frame
从未使用过。在小部件中,您必须使用self
而不是root
将小部件添加到此Frame
中,而Frame
必须使用master=root
将它们添加到主窗口中
from tkinter import *
class Application():
def __init__(self):
# Constructing the Screen
self.root = Tk()
self.canvas = Canvas(self.root, width=800, height=400)
# Label
self.v = StringVar()
self.l = 5
self.label = Label(self.root, textvariable=self.v, font=('Courier',
20), bg='white', width=50)
self.v.set('Lives: ' + str(self.l))
self.label.grid()
self.canvas.grid()
# Ball
self.canvas.create_oval(
2,
2,
22,
22,
fill='red',
tags='ball',
)
# Paddle
self.canvas.create_rectangle(
360,
380,
440,
400,
fill='black',
tag='paddle',
)
# Keybindings
self.canvas.focus_set()
self.canvas.bind('<Left>', self.paddleLeft)
self.canvas.bind('a', self.paddleLeft)
self.canvas.bind('<Button-1>', self.paddleLeft)
self.canvas.bind('<Right>', self.paddleRight)
self.canvas.bind('d', self.paddleRight)
self.canvas.bind('<Button-3>', self.paddleRight)
# Logic
self.horizontal_direction = 'east'
self.vertical_direcction = 'south'
# run after 250ms so mainloop has time to start
self.root.after(250, self.moveBall)
self.root.mainloop()
def collide(self):
(x1, y1, x2, y2) = self.canvas.coords('ball')
(px1, py1, px2, py2) = self.canvas.coords('paddle')
if x2 >= 800:
self.horizontal_direction = 'west'
if x1 <= 0:
self.horizontal_direction = 'east'
if y1 <= 0:
self.vertical_direcction = 'south'
if y2 >= 400:
self.l -= 1
self.v.set('Lives: ' + str(self.l))
self.vertical_direcction = 'north'
if y2 >= py1:
if x1 in range(int(px1), int(px2)) or x2 in range(int(px1),
int(px2)):
self.vertical_direcction = 'north'
def moveBall(self):
if self.horizontal_direction == 'east':
self.canvas.move('ball', 2, 0)
else:
self.canvas.move('ball', -2, 0)
if self.vertical_direcction == 'south':
self.canvas.move('ball', 0, 2)
else:
self.canvas.move('ball', 0, -2)
self.collide()
# run again after 15ms - so I don't need `while True`
self.root.after(15, self.moveBall)
def paddleLeft(self, event):
(px1, py1, px2, py2) = self.canvas.coords('paddle')
if px1 >= 0:
self.canvas.move('paddle', -5, 0)
def paddleRight(self, event):
(px1, py1, px2, py2) = self.canvas.coords('paddle')
if px2 <= 800:
self.canvas.move('paddle', 5, 0)
# --- start ---
Application()
从tkinter导入*
类应用程序():
定义初始化(自):
#构建屏幕
self.root=Tk()
self.canvas=canvas(self.root,宽度=800,高度=400)
#标签
self.v=StringVar()
自升=5
self.label=label(self.root,textvariable=self.v,font=('Courier',),
20) ,bg='白色',宽度=50)
self.v.set('lifes:'+str(self.l))
self.label.grid()
self.canvas.grid()
#球
self.canvas.create_oval(
2.
2.
22,
22,
填写“红色”,
“球”,
)
#划桨
self.canvas.create_矩形(
360,
380,
440,
400,
填充“黑色”,
标记为“划桨”,
)
#键绑定
self.canvas.focus_set()
self.canvas.bind(“”,self.left)
self.canvas.bind('a',self.left)
self.canvas.bind(“”,self.left)
self.canvas.bind(“”,self.battleright)
self.canvas.bind('d',self.bright)
self.canvas.bind(“”,self.battleright)
#逻辑
自水平方向='east'
自垂直方向='南'
#250毫秒后运行,以便mainloop有时间启动
self.root.after(250,self.moveBall)
self.root.mainloop()
def碰撞(自):
(x1,y1,x2,y2)=自画布坐标('球')
(px1,py1,px2,py2)=self.canvas.coords('blade'))
如果x2>=800:
self.horizontal\u方向='west'
如果x1=py1:
如果x1在范围内(int(px1)、int(px2))或x2在范围内(int(px1),
int(px2)):
自垂直方向='north'
def移动球(自身):
如果self.horizontal_direction=='east':
self.canvas.move('ball',2,0)
其他:
self.canvas.move('ball',-2,0)
如果self.vertical\u direction==“南”:
self.canvas.move('ball',0,2)
其他:
self.canvas.move('ball',0,-2)
self.collide()
#15分钟后再次跑步-因此我不需要“while True”`
self.root.after(15,self.moveBa
from tkinter import *
class Application():
def __init__(self):
# Constructing the Screen
self.root = Tk()
self.canvas = Canvas(self.root, width=800, height=400)
# Label
self.v = StringVar()
self.l = 5
self.label = Label(self.root, textvariable=self.v, font=('Courier',
20), bg='white', width=50)
self.v.set('Lives: ' + str(self.l))
self.label.grid()
self.canvas.grid()
# Ball
self.canvas.create_oval(
2,
2,
22,
22,
fill='red',
tags='ball',
)
# Paddle
self.canvas.create_rectangle(
360,
380,
440,
400,
fill='black',
tag='paddle',
)
# Keybindings
self.canvas.focus_set()
self.canvas.bind('<Left>', self.paddleLeft)
self.canvas.bind('a', self.paddleLeft)
self.canvas.bind('<Button-1>', self.paddleLeft)
self.canvas.bind('<Right>', self.paddleRight)
self.canvas.bind('d', self.paddleRight)
self.canvas.bind('<Button-3>', self.paddleRight)
# Logic
self.horizontal_direction = 'east'
self.vertical_direcction = 'south'
# run after 250ms so mainloop has time to start
self.root.after(250, self.moveBall)
self.root.mainloop()
def collide(self):
(x1, y1, x2, y2) = self.canvas.coords('ball')
(px1, py1, px2, py2) = self.canvas.coords('paddle')
if x2 >= 800:
self.horizontal_direction = 'west'
if x1 <= 0:
self.horizontal_direction = 'east'
if y1 <= 0:
self.vertical_direcction = 'south'
if y2 >= 400:
self.l -= 1
self.v.set('Lives: ' + str(self.l))
self.vertical_direcction = 'north'
if y2 >= py1:
if x1 in range(int(px1), int(px2)) or x2 in range(int(px1),
int(px2)):
self.vertical_direcction = 'north'
def moveBall(self):
if self.horizontal_direction == 'east':
self.canvas.move('ball', 2, 0)
else:
self.canvas.move('ball', -2, 0)
if self.vertical_direcction == 'south':
self.canvas.move('ball', 0, 2)
else:
self.canvas.move('ball', 0, -2)
self.collide()
# run again after 15ms - so I don't need `while True`
self.root.after(15, self.moveBall)
def paddleLeft(self, event):
(px1, py1, px2, py2) = self.canvas.coords('paddle')
if px1 >= 0:
self.canvas.move('paddle', -5, 0)
def paddleRight(self, event):
(px1, py1, px2, py2) = self.canvas.coords('paddle')
if px2 <= 800:
self.canvas.move('paddle', 5, 0)
# --- start ---
Application()