So, you've managed to add a timer function to the game - this is always handy - and allowed a mere 20 seconds for game play! Your game also has the win./lose functionality built in!
1. Copy and paste the code below (this is the solution to Challenge 2 and has a working timer, timed element and "win" and "lose" built in to the game)
2. Extend the program to do the following:
>>Add the high scores save and view feature to the game. The first three high scores are stored in a file in the following format (Name: Score). If the user 'wins', they can add their high score to the file (Press S on the Menu). Pressing 'V' would enable the high scores from the file to be viewed (displayed on screen). This is going to involve some file handling. Yep, it's getting harder - but keep going. Incidentally, the game, as it is, with a score of 200 to reach, is very difficult! You may want to change the winning score to something like 10 for testing purposes or you'll go a little crazy!
import pygame import random import math #FILE 2: Timer #Added the variables timeToEnd and timeEllapsed to make a timer #For ending the game. Modified the winning conditions to reflect this SCREEN_WIDTH = 400 SCREEN_HEIGHT = 300 class Ball: def __init__(self, x, y, radius, color, screen): self.x = x self.y = y self.radius = radius self.screen = screen self.color = color def draw(self): pygame.draw.circle(screen, self.color, [self.x, self.y], self.radius) class PlayerBall(Ball): def __init__(self, x, y, radius, color, screen): Ball.__init__(self, x, y, radius, color, screen) self.green_cooldown = 0 self.red_cooldown = 0 def move(self, mv_type): if mv_type == "UP": self.y -= 5 elif mv_type == "DOWN": self.y += 5 elif mv_type == "LEFT": self.x -= 5 elif mv_type == "RIGHT": self.x += 5 if self.x - self.radius < 0: self.x = self.radius elif self.x + self.radius > SCREEN_WIDTH: self.x = SCREEN_WIDTH - self.radius if self.y - self.radius < 0: self.y = self.radius elif self.y + self.radius > SCREEN_HEIGHT: self.y = SCREEN_HEIGHT - self.radius def check_contact(self, greenBall, redBall): to_return = 0 if math.sqrt((self.y - greenBall.y) ** 2 + (self.x - greenBall.x) ** 2) < self.radius + greenBall.radius: if self.green_cooldown == 0: self.green_cooldown = 10 to_return += 10 if math.sqrt((self.y - redBall.y) ** 2 + (self.x - redBall.x) ** 2) < self.radius + redBall.radius: if self.red_cooldown == 0: self.red_cooldown = 10 to_return -= 10 return to_return class GreenBall(Ball): def __init__(self, x, y, radius, color, screen): Ball.__init__(self, x, y, radius, color, screen) self.vy = random.randint(0, 4) - 2 self.vx = random.randint(0, 4) - 2 while self.vy == 0 or self.vx == 0: self.vy = random.randint(0, 4) - 2 self.vx = random.randint(0, 4) - 2 def move(self): self.x += self.vx self.y += self.vy if self.x - self.radius < 0: self.x = self.radius self.vx *= -1 elif self.x + self.radius > SCREEN_WIDTH: self.x = SCREEN_WIDTH - self.radius self.vx *= -1 if self.y - self.radius < 0: self.y = self.radius self.vy *= -1 elif self.y + self.radius > SCREEN_HEIGHT: self.y = SCREEN_HEIGHT - self.radius self.vy *= -1 class RedBall(Ball): def __init__(self, x, y, radius, color, screen): Ball.__init__(self, x, y, radius, color, screen) self.vy = random.randint(0, 6) - 3 self.vx = random.randint(0, 6) - 3 while self.vy == 0 or self.vx == 0: self.vy = random.randint(0, 6) - 3 self.vx = random.randint(0, 6) - 3 def move(self): self.x += self.vx self.y += self.vy if self.x - self.radius < 0: self.x = self.radius self.vx *= -1 elif self.x + self.radius > SCREEN_WIDTH: self.x = SCREEN_WIDTH - self.radius self.vx *= -1 if self.y - self.radius < 0: self.y = self.radius self.vy *= -1 elif self.y + self.radius > SCREEN_HEIGHT: self.y = SCREEN_HEIGHT - self.radius self.vy *= -1 def renderMenu(): myfont = pygame.font.SysFont("monospace", 30) title = myfont.render("Main Menu", 1, (0,0,0)) screen.blit(title, (SCREEN_WIDTH/4,0)) play = myfont.render("P - Play", 1, (0,0,0)) screen.blit(play, (0,50)) quit = myfont.render("Q - Quit", 1, (0,0,0)) screen.blit(quit, (0,100)) save = myfont.render("S - Save Scores", 1, (0,0,0)) screen.blit(save, (0,150)) view = myfont.render("V - View Scores", 1, (0,0,0)) screen.blit(view, (0,200)) res = 0 pressed = pygame.key.get_pressed() if pressed[pygame.K_p]: res = 1 if pressed[pygame.K_q]: res = 2 if pressed[pygame.K_s]: res = 3 if pressed[pygame.K_v]: res = 4 pygame.display.flip() clock.tick(60) return res pygame.init() screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) done = False score = 0 myfont = pygame.font.SysFont("monospace", 15) clock = pygame.time.Clock() ball1 = PlayerBall(100, 100, 20, (0, 0, 0), screen) ball2 = GreenBall(200, 200, 5, (0, 255, 0), screen) ball3 = RedBall(250, 300, 90, (255, 0, 0), screen) menuChoice = 0 #Variables to determine time to end the game (in milliseconds) timeToEnd = 20000 timeEllapsed = 0 while not done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True screen.fill((255, 255, 255)) if menuChoice != 1: menuChoice = renderMenu() if menuChoice == 2: done = True continue #Add a finishing condition for when a certain amount of time passed if score > -100 and score < 100 and timeEllapsed < timeToEnd: pressed = pygame.key.get_pressed() if pressed[pygame.K_UP]: ball1.move("UP") if pressed[pygame.K_DOWN]: ball1.move("DOWN") if pressed[pygame.K_LEFT]: ball1.move("LEFT") if pressed[pygame.K_RIGHT]: ball1.move("RIGHT") label = myfont.render("SCORE: " + str(score), 1, (0,0,0)) screen.blit(label, (10, SCREEN_HEIGHT - 20)) #Set up the label for the timer's value and put it on screen timeLabel = myfont.render("TIME: " + str((timeToEnd - timeEllapsed)/1000 + 1), 1,(0,0,0)) screen.blit(timeLabel,(300, SCREEN_HEIGHT - 20)) ball2.move() ball3.move() score += ball1.check_contact(ball2, ball3) ball2.draw() ball3.draw() ball1.draw() if ball1.green_cooldown > 0: ball1.green_cooldown -= 1 if ball1.red_cooldown > 0: ball1.red_cooldown -= 1 #Update the timer timeEllapsed += clock.get_time() else: myfont = pygame.font.SysFont("monospace", 50) if score < 100: label = myfont.render("YOU LOSE!", 1, (0,0,0)) screen.blit(label, (0,0)) else: label = myfont.render("YOU WIN!", 1, (0,0,0)) screen.blit(label, (0,0)) pygame.display.flip() clock.tick(60) pygame.quit()