2017-04-27 74 views
0

所以我是新的GUI和Tkinter。我正在使用Tkinter進行一次乒乓球比賽,我需要槳板像槳一樣起作用,並在盤從右側或左側撞擊槳時反彈盤。當前的代碼確實會使x軸上的paddles位置的磁盤反彈,但它不會讓磁盤經過line_x。我正在朝着正確的方向思考?還是我離開?如果有人可以修復我的代碼,它會很棒。對於一直在使用GUI的人來說,這可能是非常容易的,但是我已經被踩踏了。請幫忙。Pong與Python(Tkinter)槳不工作

from tkinter import * 

import random 

class ControlAnimation: 

    def __init__(self): 

     my_window = Tk() # create a window 
     my_window.title("Control Animation Demo") 

     self.width = 400 
     self.height = 200 
     self.line_x = 350 
     self.line_top = 75 
     self.line_bot = 125 
     self.paddle_width = 10 
     self.dy = 5 
     self.sleep_time = 50 
     self.is_stopped = False 

     self.my_canvas = Canvas(my_window, bg = 'white', \ 
      width = self.width, height = self.height) 
     self.my_canvas.pack() 

     frm_control = Frame(my_window) # for comand buttons below canvas 
     frm_control.pack() 
     btn_stop = Button(frm_control, text = 'Stop', \ 
        command = self.stop) 
     btn_stop.pack(side = LEFT) 
     btn_resume = Button(frm_control, text = 'Resume', \ 
         command = self.resume) 
     btn_resume.pack(side = LEFT) 
     btn_faster = Button(frm_control, text = 'Faster', \ 
         command = self.faster) 
     btn_faster.pack(side = LEFT) 
     btn_slower = Button(frm_control, text = 'Slower', \ 
         command = self.slower) 
     btn_slower.pack(side = LEFT) 

     self.radius = 20 
     self.x = self.radius # just to start; y is at canvas center 
     self.y = self.height/2 
     # (x, y) is center of disk for this program, but ... 
     # recall: x1,y1 and x2,y2 form a bounding box for disk 
     self.my_canvas.create_oval(\ 
      self.x - self.radius, self.height/2 + self.radius,\ 
      self.x + self.radius, self.height/2 - self.radius,\ 
          fill = "red", tags = "disk") 
     self.my_canvas.create_line(self.line_x, self.line_top, \ 
           self.line_x, self.line_bot, \ 
      width = self.paddle_width, fill = "blue", tags = "paddle") 
     self.my_canvas.bind("<KeyPress-Up>", self.move_paddle) 
     self.my_canvas.bind("<KeyPress-Down>", self.move_paddle) 
     self.my_canvas.bind("<B1-Motion>", self.left_click_paddle) 
     self.my_canvas.bind("<B3-Motion>", self.right_click_paddle) 

     self.animate() 
     self.my_canvas.focus_set() 
     my_window.mainloop() 

    def stop(self): 
     self.is_stopped = True 

    def resume(self): 
     self.is_stopped = False 
     self.animate() 

    def faster(self): 
     if self.sleep_time > 5: 
      self.sleep_time -= 15 

    def slower(self): 
     self.sleep_time += 15 

    def animate(self): 
     dx = 3 
     dy = 2 
     while not self.is_stopped : 
      self.my_canvas.move("disk", dx, dy) # move right 
      self.my_canvas.after(self.sleep_time) # sleep for a few ms    
      # redraw/update the canvas w/ new oval position 
      self.my_canvas.update() 

      # increment x to set up for next re-draw 
      r = random.randint(-1, 1) 

      self.x += dx # moves the disk 
      if self.x + self.radius > self.width: # hit right boundary 
       dx = -dx + r # add randomness 
      elif self.x - self.radius <= 0: # hit left boundary 
       dx = -dx + r # add randomness 
      elif self.x + self.radius > self.line_x and self.x + self.radius <= self.line_top: 
       dx = -dx + r 
      #elif self.x - self.radius <= self.line_x: 
       #dx = -dx + r 
      # increment y to set up for next re-draw 
      self.y += dy 
      if self.y + self.radius > self.height: # hit bottom boundary 
       dy = -dy 
      elif self.y - self.radius <= 0: # hit top boundary 
       dy = -dy 
    def left_click_paddle(self, event): 
     print(" clicked at =", event.x, event.y) 
     print("-"*30) 
     self.move_paddle(-self.dy) 

    def right_click_paddle(self, event): 
     print(" clicked at =", event.x, event.y) 
     print("-"*30) 
     self.move_paddle(self.dy)   

    def move_paddle(self, increment): 
     self.line_top += increment 
     self.line_bot += increment 
     self.my_canvas.delete("paddle") 
     self.my_canvas.create_line(self.line_x, self.line_top, \ 
           self.line_x, self.line_bot, \ 
       width = 10, fill = "blue", tags = "paddle") 
ControlAnimation() # create instance of the GUI 

回答

0

在你的運動循環中,邏輯,以檢查是否觸發在X方向的變化是不完整的。它應該是這樣的:

# new disk x, y positions 
self.x += dx 
self.y += dy 

# Change "dx" sign if the ball hit something horizontally 
if self.x + self.radius > self.width-1: 
    # ball hit right frame boundary 
    dx = -dx + r 
elif self.x - self.radius <= 1: 
    # ball hit left frame boundary 
    dx = -dx + r 
elif (self.line_x <= self.x+self.radius <= self.line_x + 2*dx 
     and self.line_top <= self.y <= self.line_bot): 
    # ball hit paddle from the left 
    dx = -dx + r 
elif (self.line_x + 2*dx <= self.x-self.radius <= self.line_x 
     and self.line_top <= self.y <= self.line_bot): 
    # ball hit paddle from the right 
    dx = -dx + r