Welcome back to my journey of my Programming 1 Final. After finding out what I was going to do for the base, I had to completely learn how to use Pygame and now you can get a look at just how my program is set up before presenting the final project and all of the glory that it brings.
My final program does not use any outside files in which I have written nor does it include any text files or sound files. This ReadMe file will help explain how to download and what to import in order to run the program.
Source Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# # Adrianna Rodencal # # Final Project for Programming 1 # Simon Memory Game # # Started: 12/3/19 # Last Updated: 12/21/19 # import random, sys, time, pygame from pygame.locals import * FPS = 30 WINDOWWIDTH = 640 WINDOWLENGTH = 480 FLASHSPEED = 500 FLASHDELAY = 200 FPSCLOCK = pygame.time.Clock() BUTTONSIZE = 200 BUTTONGAPSIZE = 20 DISPLAYSURF = pygame.display.set_mode((WINDOWLENGTH, WINDOWWIDTH)) TIMEOUT = 5 BLACK = (0, 0, 0) WHITE = (255, 255, 255) BRIGHTRED = (255, 0, 0) RED = (155, 0, 0) BRIGHTGREEN = (0, 255, 0) GREEN = (0, 155, 0) BRIGHTBLUE = (0, 0, 255) BLUE = (0, 0, 155) BRIGHTYELLOW = (255, 255, 0) YELLOW = (155, 155, 0) bgColor = BLACK XMARGIN = int((WINDOWWIDTH - (2 * BUTTONSIZE) - BUTTONGAPSIZE) /2) YMARGIN = int((WINDOWLENGTH - (2 * BUTTONSIZE) - BUTTONGAPSIZE) /2) YELLOWRECT = pygame.Rect(XMARGIN, YMARGIN, BUTTONSIZE, BUTTONSIZE) BLUERECT = pygame.Rect(XMARGIN + BUTTONSIZE + BUTTONGAPSIZE, YMARGIN, BUTTONSIZE, BUTTONSIZE) REDRECT = pygame.Rect(XMARGIN, YMARGIN + BUTTONSIZE + BUTTONGAPSIZE, BUTTONSIZE, BUTTONSIZE) GREENRECT = pygame.Rect(XMARGIN + BUTTONSIZE + BUTTONGAPSIZE, YMARGIN + BUTTONSIZE + BUTTONGAPSIZE, BUTTONSIZE, BUTTONSIZE) |
This is the first section of my program. Here I am labeling all of the things that I will need before I even start main(). We call these universals and they are often noted by being in all CAPITAL letters. It’s not recommended to use these every time that you do a program but for something like this where I am constantly updating my game board and using colors in many of my procedures I have made the colors and rectangle size universal to make things a little easier.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
def main(): global FPSCLOCK, DISPLAYSURF, BASICFONT pygame.init() pygame.font.init() basicFont = pygame.font.SysFont('Times New Romans', 20, False, False) size = (WINDOWWIDTH, WINDOWLENGTH) screen = pygame.display.set_mode(size) pygame.display.set_caption('Memory') infoSurf = basicFont.render('Click on the buttons that flash, in the order that they flash to level up.', 1, WHITE) infoLocation = (10, WINDOWLENGTH - 25) screen.blit(infoSurf, infoLocation) pygame.display.update() clock = pygame.time.Clock() print_instructions() gameData = init_game_data() computerPattern = [] currentButton = 0 score = 0 inputWait = False while True: clickedButton = None DISPLAYSURF.fill(bgColor) drawButtons() scoreSurf = basicFont.render('Score: ' +str(score), 1, WHITE) scoreLocation = (WINDOWWIDTH - 100, 10) DISPLAYSURF.blit(scoreSurf, scoreLocation) DISPLAYSURF.blit(infoSurf, infoLocation) clickedButton = event_handler(pygame, clickedButton) if inputWait == False: pygame.display.update() pygame.time.wait(1000) computerPattern.append(random.choice((YELLOW, BLUE, RED, GREEN))) for button in computerPattern: buttonFlash(button) pygame.time.wait(FLASHDELAY) inputWait = True else: if clickedButton and clickedButton == computerPattern[currentButton]: buttonFlash(clickedButton) currentButton += 1 lastClickTime = time.time() if currentButton == len(computerPattern): score += 1 inputWait = False currentButton = 0 elif (clickedButton and clickedButton != computerPattern[currentButton]) or (currentButton!= 0 and time.time() - TIMEOUT > lastClickTime): gameOver() #newRound = new_game('Would you like to play again?', basicFont) computerPattern = [] currentButton = 0 inputWait = False score = 0 pygame.time.wait(1000) pygame.display.update() FPSCLOCK.tick(FPS) def print_instructions(): print(''' Welcome to the wonderful game of Memory!! (I know, very creative title). The game will start in a few short moments. Watch carefully and try to remember the pattern of the flashing buttons. Good Luck!''') def init_game_data(): BASICFONT = pygame.font.Font('freesansbold.ttf', 16) infoSurf = BASICFONT.render('Hello', 1, YELLOW) infoRect = infoSurf.get_rect() infoRect.topleft = (10, WINDOWLENGTH - 25) pygame.display.update() def event_handler(pygame, clickedButton): for event in pygame.event.get(): if event.type == pygame.MOUSEBUTTONDOWN: mouseX, mouseY = event.pos clickedButton = getButtonClicked(mouseX, mouseY) elif event.type == pygame.KEYDOWN: if event.key == pygame.K_q: clickedButton = YELLOW elif event.key == pygame.K_w: clickedButton = BLUE elif event.key == pygame.K_a: clickedButton = RED elif event.key == pygame.K_s: clickedButton = GREEN return clickedButton |
Here you can see my main(), print_instructions(), init_game_data(), and event_handler(). These procedures are the base of the program. The main obviously being the core that tells the computer in what order to everything but the event_handler() goes through and checks to see if any buttons have been clicked. This allows for the game screen to be interactive with the user and allows later for graphics to also work.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
def terminate(): pygame.quit() sys.exit() def userQuit(): for event in pygame.event.get(QUIT): terminate() for event in pygame.event.get(KEYUP): if event.key == K_ESCAPE: terminate() pygame.event.post(event) def buttonFlash(color, animationSpeed = 50): if color == YELLOW: flashColor = BRIGHTYELLOW rectangle = YELLOWRECT elif color == BLUE: flashColor = BRIGHTBLUE rectangle = BLUERECT elif color == RED: flashColor = BRIGHTRED rectangle = REDRECT elif color == GREEN: flashColor = BRIGHTGREEN rectangle = GREENRECT originalSurf = DISPLAYSURF.copy() flashSurf = pygame.Surface((BUTTONSIZE, BUTTONSIZE)) flashSurf = flashSurf.convert_alpha() r, g, b = flashColor for start, end, step in((0, 255, 1), (255, 0, -1)): for alpha in range(start, end, animationSpeed*step): userQuit() DISPLAYSURF.blit(originalSurf, (0, 0)) flashSurf.fill((r, g, b, alpha)) DISPLAYSURF.blit(flashSurf, rectangle.topleft) pygame.display.update() FPSCLOCK.tick(FPS) DISPLAYSURF.blit(originalSurf, (0, 0)) def drawButtons(): pygame.draw.rect(DISPLAYSURF, YELLOW, YELLOWRECT) pygame.draw.rect(DISPLAYSURF, BLUE, BLUERECT) pygame.draw.rect(DISPLAYSURF, RED, REDRECT) pygame.draw.rect(DISPLAYSURF, GREEN, GREENRECT) def gameOver(color = WHITE, animationSpeed = 50): origSurf = DISPLAYSURF.copy() flashSurf = pygame.Surface(DISPLAYSURF.get_size()) flashSurf = flashSurf.convert_alpha() r, g, b = color for i in range(3): # do the flash 3 times for start, end, step in ((0, 255, 1), (255, 0, -1)): # The first iteration in this loop sets the following for loop # to go from 0 to 255, the second from 255 to 0. for alpha in range(start, end, animationSpeed * step): # animation loop # alpha means transparency. 255 is opaque, 0 is invisible userQuit() flashSurf.fill((r, g, b, alpha)) DISPLAYSURF.blit(origSurf, (0, 0)) DISPLAYSURF.blit(flashSurf, (0, 0)) basicFont = pygame.font.SysFont('Times New Romans', 30, False, False) gameOver = basicFont.render('GAME OVER', 1, WHITE) endLocation = (255,0) DISPLAYSURF.blit(gameOver, endLocation) drawButtons() pygame.display.update() FPSCLOCK.tick(FPS) def getButtonClicked(x, y): if YELLOWRECT.collidepoint((x, y)): return YELLOW elif BLUERECT.collidepoint((x, y)): return BLUE elif REDRECT.collidepoint((x, y)): return RED elif GREENRECT.collidepoint((x, y)): return GREEN return None if __name__ == '__main__': main() |
The rest of these procedures all work with the small details that help make the game run smoothly, making sure the user hasn’t quit the game or checking to see that they are doing the correct pattern. If one of these smaller procedures goes off and the user gets something wrong the game will go to the gameOver() procedure before resetting for the next game.