""" pong.py An implementation of pong[1] using Zelle's graphics library[2]. [1] https://en.wikipedia.org/wiki/Pong [2] https://mcsp.wartburg.edu/zelle/python/ Jim Mahoney | cs.marlboro.college | MIT License | Nov 2019 """ from graphics import GraphWin, Rectangle, Circle, Point from time import sleep # global constants (using the CONSTANTS_IN_CAPITALS convention) # Sizes and positions are in pixels. # Coords have x=0 at left, y=0 at top. WIDTH = 1000 HEIGHT = 800 BORDER = 100 BALL_RADIUS = 50 BALL_BORDER_WIDTH = 5 BALL_X_INIT = WIDTH // 2 BALL_Y_INIT = HEIGHT // 2 BALL_COLOR = 'blue' BALL_BORDER_COLOR = 'black' TICK = 0.01 # time per event loop, in seconds BALL_V_X_INIT = 4.0 # initial velocity in pixels per tick BALL_V_Y_INIT = 3.0 class Ball: """ A ball is a circle in a window """ def __init__(self, window): self.window = window self.v_x = BALL_V_X_INIT self.v_y = BALL_V_Y_INIT # -- ball -- self.circle = Circle(Point(WIDTH//2, HEIGHT//2), BALL_RADIUS) self.circle.setFill(BALL_COLOR) self.circle.setWidth(BALL_BORDER_WIDTH) self.circle.setOutline(BALL_BORDER_COLOR) # -- display -- self.draw() def draw(self): """ Draw the ball in its window """ self.circle.draw(self.window) def bounce_walls(self): """ Reverse the x or y velocity if the ball hits a wall """ # circle bounds - not quite in Zelle's API; # found by using dir() to look at circle object left = self.circle.p1.x top = self.circle.p1.y right = self.circle.p2.x bottom = self.circle.p2.y # collision with top or bottom? if top <= BORDER or bottom >= HEIGHT - BORDER: self.v_y = - self.v_y # collision with left or right? if left <= BORDER or right >= WIDTH - BORDER: self.v_x = - self.v_x def update(self): """ Change ball's velocity if it hits something and move it forward one time tick """ self.bounce_walls() self.circle.move(int(self.v_x), int(self.v_y)) class Paddle: pass class Screen: """ The pong game screen and its components """ def __init__(self): self.window = GraphWin('Pong!', WIDTH, HEIGHT) self.box = Rectangle(Point(BORDER, BORDER), Point(WIDTH - BORDER, HEIGHT - BORDER)) self.box.setFill('grey') self.box.draw(self.window) self.ball = Ball(self.window) def run(self): """ The pong event loop """ while True: sleep(TICK) self.ball.update() def main(): Screen().run() if __name__ == '__main__': import doctest doctest.testmod() main()