#! /usr/bin/env python # PyPong - an arcade Pong game programmed in Python # Copyright (C) 2008 PyMike # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import sys, os import random import pygame from pygame.locals import * HUMAN = 1 COM = 2 class Player(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self, self.containers) self.image = pygame.Surface((16, 64)) self.image.fill((255, 255, 255), (2, 0, 12, 64)) self.image.fill((255, 255, 255), (0, 2, 16, 60)) self.rect = self.image.get_rect(midleft = (16, 240)) self._rect = Rect(self.rect) def update(self): self._rect = Rect(self.rect) key = pygame.key.get_pressed() if key[K_UP]: self.rect.move_ip(0, -5) if key[K_DOWN]: self.rect.move_ip(0, 5) if self.rect.bottom > 480: self.rect.bottom = 480 if self.rect.top < 0: self.rect.top = 0 class Computer(pygame.sprite.Sprite): def __init__(self, ball): pygame.sprite.Sprite.__init__(self, self.containers) self.image = pygame.Surface((16, 64)) self.image.fill((255, 255, 255), (2, 0, 12, 64)) self.image.fill((255, 255, 255), (0, 2, 16, 60)) self.rect = self.image.get_rect(midleft = (640-32, 240)) self._rect = Rect(self.rect) self.ball = ball self.speed = 4 self.max_speed = self.speed def update(self): self._rect = Rect(self.rect) if abs(self.ball.vy) < self.max_speed: self.speed = abs(self.ball.vy) else: self.speed = self.max_speed if self.ball.rect.centery > self.rect.centery: self.rect.move_ip(0, self.speed) if self.ball.rect.centery < self.rect.centery: self.rect.move_ip(0, -self.speed) if self.rect.bottom > 480: self.rect.bottom = 480 if self.rect.top < 0: self.rect.top = 0 def set_ball(self, ball): self.ball = ball class Ball(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self, self.containers) self.image = pygame.Surface((12, 12)) self.image.fill((255, 255, 255), (2, 0, 8, 12)) self.image.fill((255, 255, 255), (0, 2, 12, 8)) self.rect = self.image.get_rect(midleft = (320, 240)) self._rect = Rect(self.rect) self.vx = random.choice([5, -5]) self.vy = random.choice([-2, -1, 1, 2]) self.scored = 0 def update(self): self._rect = Rect(self.rect) self.rect.move_ip(self.vx, self.vy) if self.rect.bottom > 480: self.rect.bottom = 480 self.vy = -self.vy if self.rect.top < 0: self.rect.top = 0 self.vy = -self.vy if self.rect.left < 0: self.kill() self.scored = COM if self.rect.right > 640: self.kill() self.scored = HUMAN def collide(self, bat): if self.rect.colliderect(bat.rect) and not self._rect.colliderect(bat._rect): if self._rect.right <= bat._rect.left and self.rect.right > bat.rect.left: self.rect.right = bat.rect.left self.vx = -self.vx if self._rect.left >= bat._rect.right and self.rect.left < bat.rect.right: self.rect.left = bat.rect.right self.vx = -self.vx self.vx += 1 if self.rect.centery < bat.rect.centery: self.vy = ((self.rect.centery-bat.rect.centery)/(bat.rect.height/2))*4.5 if self.vy >= -1: self.vy = -1 if self.rect.centery > bat.rect.centery: self.vy = ((self.rect.centery-bat.rect.centery)/(bat.rect.height/2))*4.5 if self.vy <= 1: self.vy = 1 if self._rect.bottom <= bat._rect.top and self.rect.bottom > bat.rect.top: self.rect.bottom = bat.rect.top self.vy = -self.vy if self._rect.top >= bat._rect.bottom and self.rect.top < bat.rect.bottom: self.rect.top = bat.rect.bottom self.vy = -self.vy class Menu: def __init__(self, screen): self.screen = screen self.font = pygame.font.SysFont("Comic Sans MS", 100) self.font2 = pygame.font.SysFont("Comic Sans MS", 50) self.font3 = pygame.font.SysFont("Comic Sans MS", 25) self.all = pygame.sprite.RenderUpdates() Computer.containers = self.all Ball.containers = self.all self.ball = Ball() self.com1 = Computer(self.ball) self.com2 = Computer(self.ball) self.com1.rect.left = 16 self.clock = pygame.time.Clock() self.timer = 0 def Run(self): self.__mainLoop() def __mainLoop(self): while 1: self.clock.tick(60) self.all.update() self.timer += 1 if self.timer >= 50: self.timer = 0 for e in pygame.event.get(): if e.type == QUIT: pygame.quit() sys.exit() if e.type == KEYDOWN: if e.key == K_ESCAPE: pygame.quit() sys.exit() if e.key == K_SPACE: game = Game(self.screen) game.Run() self.screen.fill((0, 0, 0)) self.ball.collide(self.com1) self.ball.collide(self.com2) self.all.draw(self.screen) ren = self.font.render("PyPong", 1, (255, 255, 255)) self.screen.blit(ren, (320-ren.get_width()/2, 20)) ren = self.font3.render("Copyright (C) 2008", 1, (255, 255, 255)) self.screen.blit(ren, (320-ren.get_width()/2, 220)) ren = self.font3.render("by PyMike", 1, (255, 255, 255)) self.screen.blit(ren, (320-ren.get_width()/2, 250)) ren = self.font2.render("Press Space", 1, (255, 255, 255)) if self.timer <= 25: self.screen.blit(ren, (320-ren.get_width()/2, 350)) pygame.display.flip() class Game: def __init__(self, screen): self.screen = screen self.all = pygame.sprite.RenderUpdates() Player.containers = self.all Computer.containers = self.all Ball.containers = self.all self.ball = Ball() self.player = Player() self.com = Computer(self.ball) self.clock = pygame.time.Clock() self.p1score = 0 self.p2score = 0 self.win_score = 21 self.font = pygame.font.SysFont("Comic Sans MS", 50) self.font2 = pygame.font.SysFont("Comic Sans MS", 30) self.won = False self.served = False self.done = False def Run(self): self.__gameLoop() def __quit(self): pygame.quit() sys.exit() def __done(self): self.done = True def __gameInput(self): for e in pygame.event.get(): if e.type == QUIT: self.__quit() if e.type == KEYDOWN: if e.key == K_ESCAPE: self.__done() if e.key == K_SPACE: self.served = True self.ball = Ball() self.com.set_ball(self.ball) def __drawScene(self): self.screen.fill((0, 0, 0)) self.all.draw(self.screen) ren = self.font.render("%s:%s" % (self.p1score, self.p2score), 1, (255, 255, 255)) self.screen.blit(ren, (320-ren.get_width()/2, 10)) if self.won == HUMAN: ren = self.font.render("Player 1 won!", 1, (255, 255, 255)) self.screen.blit(ren, (320-ren.get_width()/2, 240-ren.get_height()/2)) if self.won == COM: ren = self.font.render("Com won!", 1, (255, 255, 255)) self.screen.blit(ren, (320-ren.get_width()/2, 240-ren.get_height()/2)) if not self.served and not self.won: ren = self.font2.render("Press Space to Serve", 1, (255, 255, 255)) self.screen.blit(ren, (320-ren.get_width()/2, 240-ren.get_height()/2)) pygame.display.flip() def __updateGame(self): self.clock.tick(60) if not self.won and self.served: self.all.update() self.ball.collide(self.player) self.ball.collide(self.com) if self.p1score >= self.win_score: self.won = HUMAN if self.p2score >= self.win_score: self.won = COM if not self.ball.alive() and not self.won: if self.ball.scored == HUMAN: self.p1score += 1 if self.ball.scored == COM: self.p2score += 1 self.ball = Ball() self.com.set_ball(self.ball) self.served = False if self.won or not self.served: self.ball.kill() def __gameLoop(self): while not self.done: self.__updateGame() self.__gameInput() self.__drawScene() def Main(): pygame.init() if sys.platform in ("win32", "win64"): os.environ["SDL_VIDEO_CENTERED"] = "1" pygame.display.set_caption("PyPong - PyMike 2008") screen = pygame.display.set_mode((640, 480)) menu = Menu(screen) menu.Run() if __name__ == "__main__": Main()