def gameLoop(gameboard): if len(gameboard.tiles) == 0: # if the board is empty, i.e. it's a new game... gameboard.spawn() #...start the game with one spawn running = True #by default the game is 'running' (i.e. has not been quit out of or has crashed) while running: #will not stop looping unless broken out of by force using a 'break'/'return' statement or a 'quit' type event has been triggered features = drawGameScreen(gameboard) #draw the elements of the game screen and store the properties of them inside an array called 'features' for event in pygame.event.get(): #for each event in the current event queue if event.type == pygame.QUIT: #if the type of event is a 'quit' (i.e. the red x has been clicked or an alternative quit command is entered)... running = False #...then flag this fact so that the loop is broken out of elif event.type == pygame.KEYDOWN: #if the event type is a 'key press'... if event.key == pygame.K_LEFT: #...and it is the left key that has been pressed... if gameboard.tilesLeft(): #...then move the tiles to the left... initSpawn(gameboard) #...and decide whether to spawn new tile(s) or to end the game elif event.key == pygame.K_RIGHT: #...and it is the right key that has been pressed... if gameboard.tilesRight(): #...then move the tiles to the right... initSpawn(gameboard) #...and decide whether to spawn new tile(s) or to end the game elif event.key == pygame.K_UP: #...and it is the up key that has been pressed... if gameboard.tilesUp(): #...then move the tiles up... initSpawn(gameboard) #...and decide whether to spawn new tile(s) or to end the game elif event.key == pygame.K_DOWN: #...and it is the down that has been pressed... if gameboard.tilesDown(): #...then move the tiles dwon... initSpawn(gameboard) #...and decide whether to spawn new tile(s) or to end the game mouse = pygame.mouse.get_pos() #get the position of the mouse if event.type == pygame.MOUSEBUTTONUP: #if the user clicks... if features[4].collidepoint(mouse): #...and the position of the mouse is within the bounds of the the 'options' button... optionsLoop() #...then switch to the 'options' screen drawGameScreen(gameboard) #draw the screen with the updated block positions and score pygame.display.update() #and update the screen for tile in gameboard.tiles: #for each tile... if tile.element % 11 == 0: #...if the tile is the eleventh element (works for every level using moduulus)... pygame.time.wait(1000) #...wait 1000ms... display.fill(WHITE) #...wipe the screen... drawLabel('Level Complete', font(50), BLACK, ((DISPLAY_WIDTH / 2), (DISPLAY_HEIGHT / 2))) #...draw 'level complete' onto the screen... pygame.display.update() #...update the screen with this message... pygame.time.wait(1000) #...wait another 1000ms... if gameboard.level < 11: #...if the level being completed is not the 11th... gameboard.level += 1 #...then increment the level... gameboard.state = [['Empty' for col in range(5)] for row in range(5)] #...reset the game state to an empty grid... gameboard.tiles = [] #...empty the arroy of tiles... gameboard.spawn() #...and spawn the first block for that new level break #break out of this 'for' loop else: #if the player has completed all 11 levels... pygame.time.wait(1000) #...wait 1000ms... display.fill(WHITE) #...wipe the screen... drawLabel('Level Complete', font(50), BLACK, ((DISPLAY_WIDTH / 2), (DISPLAY_HEIGHT / 2))) #...draw 'game complete' onto the screen... pygame.display.update() #...update the screen with this message... pygame.time.wait(1000) #...wait another 1000ms... leaderboardLoop() #...then go to leaderboard screen saveGameState(gameboard) #save the game state after every iteration of this 'event' loop ('autosave' feature) pygame.display.update() #update the screen with any new drawings clock.tick(120) #the game should run at a frame rate of 120 frames per second pygame.quit() #if the game is not 'running' anymore then quit out of pygame
def instructionsLoop(): print('end: ', getTime()) running = True #by default the game is 'running' (i.e. has not been quit out of or has crashed) while running: #will not stop looping unless broken out of by force using a 'break'/'return' statement or a 'quit' type event has been triggered features = drawInstructionsScreen() #draw the elements of the 'instructions' screen and store the properties of them inside an array called 'features' for event in pygame.event.get(): #for each event in the current event queue if event.type == pygame.QUIT: #if the type of event is a 'quit' (i.e. the red x has been clicked or an alternative quit command is entered)... running = False #...then flag this fact so that the loop is broken out of mouse = pygame.mouse.get_pos() #get the position of the mouse if event.type == pygame.MOUSEBUTTONUP: #if the user clicks... if features[0].collidepoint(mouse): #...and the position of the mouse is within the bounds of the the 'back' button... return #...then switch back to the 'main menu' screen by returning nothing and breaking out of the instructions 'loop', back into the 'main menu' loop pygame.display.update() #update the screen clock.tick(120) #the game should run at a frame rate of 120 frames per second pygame.quit() #if the game is not 'running' anymore then quit out of pygame
def leaderboardLoop(gameOver = False): running = True #by default the game is 'running' (i.e. has not been quit out of or has crashed) while running: #will not stop looping unless broken out of by force using a 'break'/'return' statement or a 'quit' type event has been triggered features = drawLeaderboardScreen() #draw the elements of the 'leaderboard' screen and store the properties of them inside an array called 'features' for event in pygame.event.get(): #for each event in the current event queue if event.type == pygame.QUIT: #if the type of event is a 'quit' (i.e. the red x has been clicked or an alternative quit command is entered)... running = False #...then flag this fact so that the loop is broken out of mouse = pygame.mouse.get_pos() #get the position of the mouse if event.type == pygame.MOUSEBUTTONUP: #if the type of event is a 'mouse button up' (i.e. the mouse button has been lifted after being pressed down)... if features[1].collidepoint(mouse) and gameOver: #if this screen is up just after the game is over then back button... mainMenuLoop() #...returns user to the main menu elif features[1].collidepoint(mouse): #if the screen accessed from anywhere else... return #...this button returns user to the previous screen pygame.display.update() #update the screen clock.tick(120) #the game should run at a frame rate of 120 frames per second pygame.quit() #if the game is not 'running' anymore then quit out of pygame
def mainMenuLoop(): running = True #by default the game is 'running' (i.e. has not been quit out of or has crashed) while running: #will not stop looping unless broken out of by force using a 'break'/'return' statement or a 'quit' type event has been triggered features = drawMainMenuScreen() #draw the elements of the 'game' screen and store the properties of them inside an array called 'features' for event in pygame.event.get(): #for each event in the current event queue if event.type == pygame.QUIT: #if the type of event is a 'quit' (i.e. the red x has been clicked or an alternative quit command is entered)... running = False #...then flag this fact so that the loop is broken out of mouse = pygame.mouse.get_pos() #get the position of the mouse if event.type == pygame.MOUSEBUTTONUP: #if the user clicks... if features[0].collidepoint(mouse): #...and the position of the mouse is within the bounds of the the 'new game' button... nameInputLoop(newGame = True) #...then switch to the 'name input' screen with the 'newGame' flag set to true elif features[1].collidepoint(mouse): #...and the position of the mouse is within the bounds of the the 'load game' button... nameInputLoop(newGame = False) #...then switch to the 'name input' screen with the 'newGame' flag set to false elif features[2].collidepoint(mouse): #...and the position of the mouse is within the bounds of the the 'new game' button... leaderboardLoop() #...then switch to the 'leaderboard' screen elif features[3].collidepoint(mouse): #...and the position of the mouse is within the bounds of the the 'new game' button... print('start: ', getTime()) instructionsLoop() #...then switch to the 'instructions' screen pygame.display.update() #update the screen clock.tick(120) #the game should run at a frame rate of 120 frames per second pygame.quit() #if the game is not 'running' anymore then quit out of pygame
def nameInputLoop(newGame): running = True #by default the game is 'running' (i.e. has not been quit out of or has crashed) username = [] #initialise the username to an empty list of characters while running: #will not stop looping unless broken out of by force using a 'break'/'return' statement or a 'quit' type event has been triggered features = drawNameInputScreen(newGame, username) #draw the elements of the 'game' screen and store the properties of them inside an array called 'features' for event in pygame.event.get(): #for each event in the current event queue if event.type == pygame.QUIT: #if the type of event is a 'quit' (i.e. the red x has been clicked or an alternative quit command is entered)... running = False #...then flag this fact so that the loop is broken out of mouse = pygame.mouse.get_pos() #get the position of the mouse if event.type == pygame.MOUSEBUTTONUP: #if the user clicks... if features[2].collidepoint(mouse): #...and the position of the mouse is within the bounds of the the input box... clickedInBox = True #...then flag this fact... while clickedInBox and running: #...and loop whilst they haven't clicked outside the box and haven't quit pygame.draw.rect(display, (255, 0, 0), [150, 310, 200, 30], 2) #change the border of the input box to red to indicate that the box has been clicked on for event in pygame.event.get(): #for each event in the event queue (an internal event queue loop is needed as we have now entered a secondary while loop) mouse = pygame.mouse.get_pos() #variable that holds the current coordinate of the mouse if event.type == pygame.QUIT: #if the type of event is a 'quit' (i.e. the red x has been clicked or an alternative quit command is entered)... running = False #...then flag this fact so that the loop is broken out of elif event.type == pygame.MOUSEBUTTONUP: #if the user clicks... if not features[2].collidepoint(mouse): #...outwith the input box... if features[3].collidepoint(mouse): #...and within the 'enter' button (or enter key is pressed)... if len(list(username)) >= 3: #...and username has the minimum number of characters... usernameSubmitted(newGame, username) #...then submit that username else: #if the username is not long enough... drawLabel('Username needs to be at least 3 characters!', font(25), BLACK, (250, 450)) #...draw a message saying so... pygame.display.update() #...display it... pygame.time.wait(500) #...for a brief moment... drawNameInputScreen(newGame, username) #...and then draw the screen again, covering/hiding the message if features[4].collidepoint(mouse): #if the user clicks outwith the input box and within the 'Back' button then... return #...return to main menu else: #a click anywhere else and we will... clickedInBox = False #...flag this fact... break #...and break out of this loop, returning to the 'not clicked in box' loop elif event.type == pygame.KEYDOWN: #if the user presses the... if event.key == pygame.K_RETURN: #...return key... if len(list(username)) >= 3: #...then check username has the minimum number of characters... usernameSubmitted(newGame, username) #...then either load a game using that username or start a new one else: drawLabel('Username needs to be at least 3 characters!', font(25), BLACK, (250, 450)) #...draw a message saying so... pygame.display.update() #...display it... pygame.time.wait(500) #...for a brief moment... drawNameInputScreen(newGame, username) #...and then draw the screen again, covering/hiding the message elif event.key == pygame.K_BACKSPACE: #...backspace... if len(username) > 0: #...check that the current username has characters to prevent an 'out of bounds' exception being raised on the username array username = list(username) #convert the username into a list... del username[-1] #...remove the last char from the list... username = ''.join(username) #...join that list back into a string... drawNameInputScreen(newGame, username) #...and draw the updated username inside the input box elif len(username) < 8: #if the press another key then first check we don't end up putting more than 8 chars into the string if re.match('[a-z0-9]', chr(event.key)): #if they press a key between a-z or 0-9 (regex)... username = list(username) #...convert the username into a list username.append(chr(event.key)) #...add that character to the list... username = ''.join(username) #...join that list back into a string drawNameInputScreen(newGame, username) #...and draw the updated username inside the input box else: #if they press any other key... drawLabel('Invalid character!', font(25), BLACK, (250, 450)) #...draw a message saying so... pygame.display.update() #...display it... pygame.time.wait(500) #...for a brief moment... username = ''.join(username) #...join the username list into a string... drawNameInputScreen(newGame, username) #...and then draw the screen again, covering/hiding the message else: #if they press another key but the string already has 8 chars then... drawLabel('Only allowed up to 8 characters!', font(25), BLACK, (250, 450)) #...draw a message saying so... pygame.display.update() #...display it... pygame.time.wait(500) #...for a brief moment... drawNameInputScreen(newGame, username) #...and then draw the screen again, covering/hiding the message pygame.display.update() #update the display with anything that has been drawn (new chars inside the input box) clock.tick(120) #the game should run at a frame rate of 120 frames per second elif features[3].collidepoint(mouse) and len(list(username)) >= 3 and len(list(username)) <= 8: #if the start/continue button is clicked and username is valid... usernameSubmitted(newGame, username) #...submit it elif features[3].collidepoint(mouse) and len(list(username)) < 3: #if the start/continue button is clicked and the username is too short... drawLabel('Username needs to be at least 3 characters!', font(25), BLACK, (250, 450)) #...draw a message saying so... pygame.display.update() #...display it... pygame.time.wait(500) #...for a brief moment... drawNameInputScreen(newGame, username) #...and then draw the screen again, covering/hiding the message elif features[3].collidepoint(mouse) and len(list(username)) > 8: #if the start/continue button is clicked and the username is too long... drawLabel('Only allowed up to 8 characters!', font(25), BLACK, (250, 450)) #...draw a message saying so... pygame.display.update() #...display it... pygame.time.wait(500) #...for a brief moment... drawNameInputScreen(newGame, username) #...and then draw the screen again, covering/hiding the message elif features[4].collidepoint(mouse): #if the 'back' button is clicked... return #...then switch back to the 'main menu' screen by returning nothing and breaking out of the 'name input' loop, back into the 'main menu' loop pygame.display.update() #update the screen clock.tick(120) #the game should run at a frame rate of 120 frames per second pygame.quit() #if the game is not 'running' anymore then quit out of pygame