i具有以下代码,错误是1个位置参数(文本)丢失。据我所知,我包括了所有参数。谁能对此阐明?
错误
TypeError: draw_text() missing 1 required positional argument: 'text'
有问题的代码
while 1:
if ball1.hit_bottom ==False: #this creates a condition - inside the loop it continues to check to see if the ball has hit (or not) the bottom of the screen
tk.update()
ball1.draw()
bat1.draw()
else:
draw1=Game()
draw1.draw_text(300,200,'Goodbye')
time.sleep(0.02)
main()
draw_text定义的类。
class Game:
def game_loop(self,canvas):
if hit_bottom==True:
self.draw_text(300,200,'You Lose')
def draw_text(self,canvas,x,y,text,size='40'):
font=('Helvetica',size)
return self.canvas.create_text(x,y,text=text,font=font)
新的TKINTER,在进行了大量研究之后,我仍然找不到有关使此功能工作的细节。
我也尝试过:
while 1:
if ball1.hit_bottom ==False: #this creates a condition - inside the loop it continues to check to see if the ball has hit (or not) the bottom of the screen
tk.update()
ball1.draw()
bat1.draw()
else:
game_over()
time.sleep(0.02)
main()
...与球类中的以下内容
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos=self.canvas.coords(self.id)
if pos[1] <=0:
self.y=6
#we make a change here as well -alter the if statement to see if the ball has hit the bottom (equal or greater than canvas height), if so hit_bottom =True (as there is no more need to bounce the ball if the game is over!)
if pos[3] >=self.canvas_height:
self.hit_bottom = True
game_over()
这也不起作用:
错误:画布未定义
可运行的示例(整个代码)
from tkinter import *
import random
import time
class Game:
def game_loop(self,canvas):
if hit_bottom==True:
self.draw_text(300,200,'You Lose')
def draw_text(self,canvas,x,y,text,size='40'):
font=('Helvetica',size)
return self.canvas.create_text(x,y,text=text,font=font)
class Ball:
def __init__(self,canvas,bat,color):
self.canvas=canvas
self.bat=bat
self.id=canvas.create_oval(30,30,50,50,fill=color)
self.canvas.move(self.id,100,200)
starting_position=[-3,-2,-1,1,2,3]
random.shuffle(starting_position)
self.x = starting_position[0]
self.y = -3
self.canvas_height=self.canvas.winfo_height()
self.canvas_width=self.canvas.winfo_width()
#Add a hit_bottom object variable here..
self.hit_bottom=False #...note we change the main loop at the bottom to include an if function that utilises this hit_bottom object variable
def hit_bat(self,pos):
bat_pos=self.canvas.coords(self.bat.id)
if pos[2] >=bat_pos[0] and pos[0] <=bat_pos[2]:
if pos[3]>=bat_pos[1] and pos[3] <= bat_pos[3]:
return True
return False
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos=self.canvas.coords(self.id)
if pos[1] <=0:
self.y=6
#we make a change here as well -alter the if statement to see if the ball has hit the bottom (equal or greater than canvas height), if so hit_bottom =True (as there is no more need to bounce the ball if the game is over!)
if pos[3] >=self.canvas_height:
self.hit_bottom = True
if self.hit_bat(pos) ==True:
self.y=-6
if pos[0] <=0:
self.x=6
if pos[2]>=self.canvas_width:
self.x=-6
class Pongbat():
def __init__(self,canvas,color):
self.canvas=canvas
self.id=canvas.create_rectangle(0,0,100,10,fill=color)
self.canvas.move(self.id,200,300)
self.x=0
self.canvas_width=self.canvas.winfo_width()
self.canvas.bind_all('<KeyPress-Left>',self.left_turn)
self.canvas.bind_all('<KeyPress-Right>',self.right_turn)
def draw(self):
self.canvas.move(self.id,self.x,0)
pos=self.canvas.coords(self.id)
if pos[0]<=0:
self.x=0
if pos[2]>=self.canvas_width:
self.x=0
def left_turn(self,evt):
self.x=-10
def right_turn(self,evt):
self.x=10
def main():
tk=Tk()
tk.title("My 21st Century Pong Game")
tk.resizable(0,0)
tk.wm_attributes("-topmost",1)
canvas=Canvas(tk,bg="white",width=500,height=400,bd=0,highlightthickness=0)
canvas.pack()
tk.update()
bat1=Pongbat(canvas,'red')
ball1=Ball(canvas,bat1, 'green')
while 1:
if ball1.hit_bottom ==False: #this creates a condition - inside the loop it continues to check to see if the ball has hit (or not) the bottom of the screen
tk.update()
ball1.draw()
bat1.draw()
else:
draw1=Game()
draw1.draw_text(300,200,'Goodbye')
time.sleep(0.02)
main()
最终更新:
我尝试的最新一件事是添加 init 方法如下:
class Game:
def __init__(self,canvas):
self.canvas=canvas
def game_loop(self,canvas):
if hit_bottom==True:
self.draw_text(300,200,'You Lose')
def draw_text(self,canvas,x,y,text,size='40'):
font=('Helvetica',size)
return self.canvas.create_text(x,y,text=text,font=font)
和
while 1:
if ball1.hit_bottom ==False: #this creates a condition - inside the loop it continues to check to see if the ball has hit (or not) the bottom of the screen
tk.update()
ball1.draw()
bat1.draw()
else:
draw1=Game(canvas)
#def draw_text(self,canvas,x,y,text,size='40'):
draw1.draw_text(canvas,300,200,'Goodbye')
time.sleep(0.02)
main()
现在,第一个错误(大约没有画布或没有位置参数)消失了,但是屏幕只是悬挂。
屏幕在您的最后更新中悬挂,因为while
循环仍在运行,您没有得到/突破。满足病情后,您应该 break
退出时循环。
这是您的代码,还有其他修复程序:
您的right_turn
和left_turn
方法似乎无法正常工作,但我将其保留供您解决。
from tkinter import *
import random
import time
class Game:
def __init__(self, canvas):
self.canvas=canvas
def game_loop(self): ##No need to pass canvas since you are using the same canvas in __init__
if hit_bottom==True:
self.draw_text(300,200,'You Lose')
def draw_text(self, x, y, text, size='40'): ##No need to pass canvas
font=('Helvetica',size)
print "Ok"
return self.canvas.create_text(x,y,text=text,font=font)
class Ball:
def __init__(self,canvas,bat,color):
self.canvas=canvas
self.bat=bat
self.id=self.canvas.create_oval(30,30,50,50,fill=color) ## self.canvas
self.canvas.move(self.id,100,200)
starting_position=[-3,-2,-1,1,2,3]
random.shuffle(starting_position)
self.x = starting_position[0]
self.y = -3
self.canvas_height=self.canvas.winfo_height()
self.canvas_width=self.canvas.winfo_width()
#Add a hit_bottom object variable here..
self.hit_bottom=False #...note we change the main loop at the bottom to include an if function that utilises this hit_bottom object variable
def hit_bat(self,pos):
bat_pos=self.canvas.coords(self.bat.id)
if pos[2] >=bat_pos[0] and pos[0] <=bat_pos[2]:
if pos[3]>=bat_pos[1] and pos[3] <= bat_pos[3]:
return True
return False
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos=self.canvas.coords(self.id)
if pos[1] <=0:
self.y=6
#we make a change here as well -alter the if statement to see if the ball has hit the bottom (equal or greater than canvas height), if so hit_bottom =True (as there is no more need to bounce the ball if the game is over!)
if pos[3] >=self.canvas_height:
self.hit_bottom = True
if self.hit_bat(pos) ==True:
self.y=-6
if pos[0] <=0:
self.x=6
if pos[2]>=self.canvas_width:
self.x=-6
class Pongbat():
def __init__(self,canvas,color):
self.canvas=canvas
self.id=self.canvas.create_rectangle(0,0,100,10,fill=color) ## self.canvas
self.canvas.move(self.id,200,300)
self.x=0
self.canvas_width=self.canvas.winfo_width()
self.canvas.bind_all('<KeyPress-Left>',self.left_turn)
self.canvas.bind_all('<KeyPress-Right>',self.right_turn)
def draw(self):
self.canvas.move(self.id,self.x,0)
pos=self.canvas.coords(self.id)
if pos[0]<=0:
self.x=0
if pos[2]>=self.canvas_width:
self.x=0
def left_turn(self,evt):
self.x =-10
def right_turn(self,evt):
self.x =+10
def main():
tk=Tk()
tk.title("My 21st Century Pong Game")
tk.resizable(0,0)
tk.wm_attributes("-topmost",1)
canvas=Canvas(tk,bg="white",width=500,height=400,bd=0,highlightthickness=0)
canvas.pack()
tk.update()
bat1=Pongbat(canvas,'red')
ball1=Ball(canvas,bat1, 'green')
while 1:
if ball1.hit_bottom ==False: #this creates a condition - inside the loop it continues to check to see if the ball has hit (or not) the bottom of the screen
tk.update()
ball1.draw()
bat1.draw()
else:
draw1=Game(canvas)
#def draw_text(self,canvas,x,y,text,size='40'):
draw1.draw_text(300,200,'Goodbye')
break ## This stops the while loop
time.sleep(0.02)
tk.mainloop() # Keep the main window open
main()
进行了多个更改后,大多数(如果不是全部)都用注释表示,这是您的脚本的可运行版本,它将在游戏结束时显示文本。
from tkinter import *
import random
import time
class Game:
def __init__(self, canvas): # Added method.
self.canvas=canvas
def game_loop(self): # Removed canvas parameter.
if hit_bottom==True:
self.draw_text(self.canvas,300,200,'You Lose') # Added self.canvas arg
def draw_text(self,canvas,x,y,text,size='40'):
font=('Helvetica',size)
return self.canvas.create_text(x,y,text=text,font=font)
class Ball:
def __init__(self,canvas,bat,color):
self.canvas=canvas
self.bat=bat
self.id=canvas.create_oval(30,30,50,50,fill=color)
self.canvas.move(self.id,100,200)
starting_position=[-3,-2,-1,1,2,3]
random.shuffle(starting_position)
self.x = starting_position[0]
self.y = -3
self.canvas_height=self.canvas.winfo_height()
self.canvas_width=self.canvas.winfo_width()
#Add a hit_bottom object variable here..
self.hit_bottom=False #...note we change the main loop at the bottom to include an if function that utilises this hit_bottom object variable
def hit_bat(self,pos):
bat_pos=self.canvas.coords(self.bat.id)
if pos[2] >=bat_pos[0] and pos[0] <=bat_pos[2]:
if pos[3]>=bat_pos[1] and pos[3] <= bat_pos[3]:
return True
return False
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos=self.canvas.coords(self.id)
if pos[1] <=0:
self.y=6
#we make a change here as well -alter the if statement to see if the ball has hit the bottom (equal or greater than canvas height), if so hit_bottom =True (as there is no more need to bounce the ball if the game is over!)
if pos[3] >=self.canvas_height:
self.hit_bottom = True
if self.hit_bat(pos) ==True:
self.y=-6
if pos[0] <=0:
self.x=6
if pos[2]>=self.canvas_width:
self.x=-6
class Pongbat():
def __init__(self,canvas,color):
self.canvas=canvas
self.id=canvas.create_rectangle(0,0,100,10,fill=color)
self.canvas.move(self.id,200,300)
self.x=0
self.canvas_width=self.canvas.winfo_width()
self.canvas.bind_all('<KeyPress-Left>',self.left_turn)
self.canvas.bind_all('<KeyPress-Right>',self.right_turn)
def draw(self):
self.canvas.move(self.id,self.x,0)
pos=self.canvas.coords(self.id)
if pos[0]<=0:
self.x=0
if pos[2]>=self.canvas_width:
self.x=0
def left_turn(self,evt):
self.x=-10
def right_turn(self,evt):
self.x=10
def main():
tk=Tk()
tk.title("My 21st Century Pong Game")
tk.resizable(0,0)
tk.wm_attributes("-topmost",1)
canvas=Canvas(tk,bg="white",width=500,height=400,bd=0,highlightthickness=0)
canvas.pack()
tk.update()
bat1=Pongbat(canvas,'red')
ball1=Ball(canvas,bat1, 'green')
while 1:
if ball1.hit_bottom ==False: #this creates a condition - inside the loop it continues to check to see if the ball has hit (or not) the bottom of the screen
ball1.draw()
bat1.draw()
tk.update() # Allow screen to be updated (moved here after draw calls).
else:
draw1=Game(canvas) # Added argument for new __init__() method.
draw1.draw_text(canvas,300,200,'Goodbye') # Added canvas arg.
tk.update() # Allow screen to be updated.
canvas.after(3000) # Added. Pause for a few seconds.
return # Terminate.
# time.sleep(0.02) # Shouldn't call sleep() in tkinter app.
canvas.after(2) # Use universal 'after()` method instead. Time in millisecs.
main()