2017-09-23 91 views
-1

我有以下代碼,錯誤是1位置參數(文本)丟失。據我所知,我已經包含了所有的論點。任何人都可以對此有所瞭解嗎?文字不顯示在Tkinter

錯誤

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() 

這不起作用或者:

錯誤: 帆布未定義

Runnable的例子(完整的代碼)

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() 

最後更新:

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) 

和:

我嘗試了最新的東西是如下添加INIT方法

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() 

現在,第一個錯誤(關於無畫布或無位置參數)消失了,但屏幕只是掛起。

+0

我試過了:game_over(canvas)..和def game_over(canvas):..但它仍然不起作用。你可以發佈作爲答案 – MissComputing

+0

'canvas'作爲'draw_text'中的一個參數,然後決不傳遞它。這意味着300 - > canvas,200 - > x,'Goodbye' - > y,所以你不會將任何東西傳遞給'text',並接收這個錯誤。 – SneakyTurtle

+0

謝謝SneakyTurtle和abccd - 只是發佈整個代碼 – MissComputing

回答

1

由於while循環仍在運行,因此屏幕在最後一次更新時會掛起,因此您沒有得到/解決問題。一旦條件滿足,您應該在while循環中使用break

這裏是你的代碼與其他一些修正:似乎

right_turnleft_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() 
0

做了一些改變,大部分如果不是全部的經過與評論指出,這是你的腳本的可運行版本將顯示在遊戲結束的文本。

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()