Pong with Python(Tkinter)paddle无法正常工作

时间:2017-04-27 03:21:43

标签: python user-interface tkinter pong

所以我是GUI和Tkinter的新手。我正在使用Tkinter进行一个桨式乒乓球游戏,我需要桨状物像桨一样,当磁盘从右侧或左侧撞击桨时,将磁盘弹回。我当前的代码确实反弹了x轴上的桨位置的磁盘,但它不会让磁盘超过line_x。我在想正确的方向吗?还是我离开了?如果有人可以修复我的代码以便它可以工作,那将是非常棒的。对于那些一直在使用GUI的人来说,这可能非常容易,但是我被踩了。请帮忙。

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

1 个答案:

答案 0 :(得分: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