def update(self): # handle all updates - ALL CODE BELOW: self.handleKeyPress() if self.userEscape: ourFont = pygame.font.SysFont('Arial', 28) text = HelperFunctions.makeTextRect('Paused. Score: ' + str(self.gameScore) + '. Press q to quit, ESC to unpause.', (0,255,0), (400, 300), Config.screen, ourFont, True) # draw a rectangle big enough for the text background pygame.draw.rect(Config.screen, Config.BACKGROUND_COLOUR, (text.x, text.y, text.width, text.height), 1) pygame.display.update([text]) return self.clock.tick(Config.FPS) self.handleCollisions() self.handleExpiry() self.handleRandoms() ### ---------------- NEEDS TO BE SORTED OUT -------------- # while >=0 aka not active if self.freezeActiveBallsTimer > 0: self.freezeActiveBallsTimer -= Config.FPS if self.gameOver == False: movement = self.snake.move(Config.DEFAULT_SCREEN_SIZE[0], Config.DEFAULT_SCREEN_SIZE[1]) if movement != False: self.handleUpdates() else: self.gameOver = True self.exitGame() if ((self.gameOver == True) or (self.userEscape == True)): self.exitGame()
def main(): print 'TODO: get all (50,250) etc as different variables, esp the colours' playerName = '' # Initialize Pygame pygame.init() # Create a window of 800x600 pixels screen = pygame.display.set_mode(Config.DEFAULT_SCREEN_SIZE) # Set the window caption pygame.display.set_caption('PySnake') bkg = image.load_image('pysnake.jpg', img_dir) rules_one = image.load_image('pysnake_rules_one.jpg', img_dir) rules_two = image.load_image('pysnake_rules_two.jpg', img_dir) menu = generate_main_menu(screen) level_select_menu = generate_level_select(screen) high_scores_menu = generate_high_scores(screen) game_rules_one_menu = generate_game_rules(screen, 1) game_rules_two_menu = generate_game_rules(screen, 2) high_score_input_menu = generate_high_score_input(screen, playerName) state = STATE_MAIN_MENU prev_state = STATE_EXIT # rect_list is the list of pygame.Rect's that will tell pygame where to # update the screen (there is no point in updating the entire screen if only # a small portion of it changed!) rect_list = [] imageIsShown = False EVENT_CHANGE_STATE = pygame.USEREVENT + 1 # only allow what we will be dealing with, therefore speed up the program pygame.event.set_allowed(None) pygame.event.set_allowed([pygame.KEYDOWN, EVENT_CHANGE_STATE, pygame.QUIT]) print 'BUG: in Game rules, press ESC, go back, no image' ourFont = pygame.font.SysFont('Arial', 24) # The main while loop while True: # Check if the state has changed, if it has, then post a user event to # the queue to force the menu to be shown at least once # high_score_input_menu = generate_high_score_input(screen, playerName) # if len(playerName) > 0: # print playerName if prev_state != state: pygame.event.post(pygame.event.Event(EVENT_CHANGE_STATE, key=0)) prev_state = state screen.blit(bkg, (0, 0)) pygame.display.flip() # Get the next event e = pygame.event.wait() # Update the menu, based on which "state" we are in - When using the menu # in a more complex program, definitely make the states global variables # so that you can refer to them by a name if e.type == pygame.KEYDOWN or e.type == EVENT_CHANGE_STATE: if e.type == pygame.KEYDOWN: if e.key == pygame.K_ESCAPE: # if we press escape/q on the main menu, quit if state == STATE_MAIN_MENU: state = STATE_EXIT else: # otherwise return to the main menu state = STATE_MAIN_MENU # don't let the user press # if pygame.key.name(e.key) in string.lowercase: # state = ord(pygame.key.name(e.key)) + HIGH_SCORE_INPUT_OFFSET if state == STATE_MAIN_MENU: (rect_list, state) = menu.update(e, state) elif state == STATE_LEVEL_SELECT: (rect_list, state) = level_select_menu.update(e, state) elif state > LEVEL_ID_OFFSET and state \ < HIGH_SCORE_INPUT_OFFSET: (rect_list, state) = level_select_menu.update(e, state) # G = Game_Module.Game() level_files = get_level_list() fName = level_files[state % 9000 - 1]['fName'] level_settings = get_level_settings(fName) continueBool = False for val in [ 'difficulty', 'level_name', 'initial_food_num', 'initial_food_super_num', 'initial_food_mysterious_num', 'initial_food_curse_num', 'initial_ball_num', 'initial_ball_killer_num', 'max_balls', 'ball_speed', 'ball_size', 'fps', 'background_colour', ]: try: if isinstance(level_settings[val], str): pass except KeyError: print 'KEY ERROR', val continueBool = True if continueBool: continueBool = False continue # surround strings with double quotes, leave integers as they are if isinstance(level_settings[val], str): exec 'Config.' + str(val.upper()) + ' = "' \ + str(level_settings[val]) + '"' else: exec 'Config.' + str(val.upper()) + ' = ' \ + str(level_settings[val]) + '' # print eval('Config.' + str(val.upper())) # end for Config.PAGE_TITLE = Config.PAGE_TITLE + ' ' \ + level_files[state % 9000 - 1]['settings' ]['level_name'] # work out the bonus based on difficulty - will only work for valid difficulties # try: exec 'Config.DIFFICULTY_BONUS = Config.DIFFICULTY_BONUS_' \ + Config.DIFFICULTY.upper() Config.BACKGROUND = pygame.Surface(screen.get_size()) Config.BACKGROUND = Config.BACKGROUND.convert() Config.BACKGROUND.fill(Config.BACKGROUND_COLOUR) Config.screen = \ pygame.display.set_mode(Config.DEFAULT_SCREEN_SIZE) # print "COLOUR: ", Config.BACKGROUND_COLOUR # better way of doing it? # execfile('Snake.py') G = Game_Module.Game(None) running = True while running: G.update() if G.gameOver: playerScore = G.gameScore del G running = False break if HelperFunctions.isNewHighScore(playerScore): state = STATE_HIGH_SCORE_INPUT else: # state = STATE_EXIT state = STATE_HIGH_SCORE_TRY_AGAIN elif state == STATE_HIGH_SCORE_INPUT: # state = STATE_HIGH_SCORE_TRY_AGAIN # #### http://www.facebook.com/l.php?u=http%3A%2F%2Fstackoverflow.com%2Fquestions%2F14111381%2Fhow-to-make-pygame-print-input-from-user&h=kAQHS8xjR (rect_list, state) = high_score_input_menu.update(e, state) if False: pass getInput = True showUpdates = True while getInput: for keypress in pygame.event.get(): if keypress.type == pygame.KEYDOWN: if keypress.unicode.isalpha(): playerName += keypress.unicode showUpdates = True elif keypress.key == pygame.K_BACKSPACE: playerName = playerName[:-1] showUpdates = True elif keypress.key == pygame.K_RETURN: getInput = False continue if showUpdates: screen.fill((0, 0, 0)) text = ourFont.render(playerName, True, (255, 0, 0)) block = text.get_rect() block.center = (400, 300) # dead center rect_list.append(screen.blit(text, block)) text = \ ourFont.render('Please type your name, press enter to finish, and backspace to remove characters. ' , True, (255, 255, 255)) block = text.get_rect() block.center = (400, 250) # block.center[1] -= 100 rect_list.append(screen.blit(text, block)) pygame.display.update(rect_list) showUpdates = False # end while print 'Final name', playerName HelperFunctions.appendHighScore(playerScore, playerName) state = STATE_HIGH_SCORE_TRY_AGAIN elif state == STATE_LEVEL_CREATOR: screen.fill((0, 0, 0)) rect_list.append(HelperFunctions.makeTextRect( 'Please follow the instructions in the console.', (255, 255, 255), (400, 250), screen, ourFont, True, )) rect_list.append(HelperFunctions.makeTextRect( 'Once complete, please restart the menu. ', (255, 255, 255), (400, 300), screen, ourFont, True, )) pygame.display.update(rect_list) os.system(sys.executable + ' level_creator.py') state = STATE_EXIT elif state == STATE_HIGH_SCORES: # print 'High Scores' (rect_list, state) = high_scores_menu.update(e, state) highScoresList = HelperFunctions.getHighScores() yOffset = 220 screen.fill((0, 0, 0)) rect_list.append(HelperFunctions.makeTextRect('Rank', GREEN, (100, yOffset), screen, ourFont)) rect_list.append(HelperFunctions.makeTextRect('Name', GREEN, (200, yOffset), screen, ourFont)) rect_list.append(HelperFunctions.makeTextRect('Score', GREEN, (450, yOffset), screen, ourFont)) yOffset += 30 colour = dict() colour['normal'] = (255, 255, 255) colour['bronze'] = (128, 64, 0) colour['silver'] = (192, 192, 192) colour['gold'] = (232, 232, 0) for (idx, tup) in enumerate(highScoresList): # print idx if idx == 0: c = colour['gold'] elif idx == 1: c = colour['silver'] elif idx == 2: c = colour['bronze'] else: c = colour['normal'] rect_list.append(HelperFunctions.makeTextRect(str(idx + 1) + '. ', c, (100, yOffset), screen, ourFont)) rect_list.append(HelperFunctions.makeTextRect(str(tup[1]), c, (200, yOffset), screen, ourFont)) rect_list.append(HelperFunctions.makeTextRect(str(tup[0]), c, (450, yOffset), screen, ourFont)) yOffset += 30 rect_list.append(HelperFunctions.makeTextRect('Press enter or escape to return' , (255, 255, 255), (500, 300), screen, ourFont)) rect_list.append(HelperFunctions.makeTextRect('to the main menu' , (255, 255, 255), (500, 320), screen, ourFont)) pygame.display.update(rect_list) elif state == STATE_RULES_P_ONE: # High scores menu (rect_list, state) = game_rules_one_menu.update(e, state) if not imageIsShown: # only show on the first page instance, otherwise will need to keep redrawing :. inefficient rect_list.append(screen.blit(rules_one, (20, 250))) imageIsShown = True if prev_state != state: # changed page imageIsShown = False elif state == STATE_RULES_P_TWO: (rect_list, state) = game_rules_two_menu.update(e, state) if not imageIsShown: # only show on the first page instance, otherwise will need to keep redrawing :. inefficient rect_list.append(screen.blit(rules_two, (20, 250))) imageIsShown = True if prev_state != state: # changed page imageIsShown = False elif state == STATE_HIGH_SCORE_TRY_AGAIN: screen.fill((0, 0, 0)) rect_list.append(HelperFunctions.makeTextRect( 'Your final score was ' + str(playerScore) + '. Try again next time!', (255, 255, 255), (400, 250), screen, ourFont, True, )) rect_list.append(HelperFunctions.makeTextRect( 'Press any key to exit. ', (255, 255, 255), (400, 300), screen, ourFont, True, )) pygame.display.update(rect_list) # state = STATE_EXIT # wait until we get some user input, so we know they've seen the message, then exit e = pygame.event.wait() if e.type == pygame.KEYDOWN or e.type == pygame.QUIT: state = STATE_EXIT else: pygame.quit() sys.exit() # Quit if the user presses the exit button if e.type == pygame.QUIT: pygame.quit() sys.exit() # Update the screen pygame.display.update(rect_list)