def gameLoop(): global dirn global k global highscore global namehighscore pyExit = False pyOver = False score = 0 world_num = 0 scorestr = "Score:0" # Initialize the game snake = Snake(200, 200, img) food = Food(int(width / 2), int(height / 2)) blocks = worlds(width, height, world_num) # Keeps track of the direction of the snake. dx, dy = 0, 0 lossreason = '' while not pyExit: while pyOver: image = pygame.image.load(python_path) game_display.blit(image, (0, 0)) message("Game Over! Press C to play Again, Q to Quit", (255, 0, 0), -20) message(lossreason, (255, 0, 0), 30) # display score on game over message("Your" + scorestr, (255, 0, 0), 80) if totalscore > highscore: # message("Highscore!!!",(255,0,0),120) # write new highscore highscorefile = open('highscore.txt', 'wt') highscorefile.write(str(totalscore) + "\n") # name window def namewrite(): highscorefile.write(v.get()) scorewindow.destroy() scorewindow = Tk() scorewindow.geometry('300x100') frame = Frame(scorewindow, width=100, height=100) frame.pack() scorewindow.title("congratulations") Label(frame, text='you\'ve made highscore!!!!').pack(side='top') v = StringVar() v.set("type your name") textbox = Entry(frame, textvariable=v) textbox.pack(side='top') okbutton = Button(frame, text="ok", fg="black", bg="white", command=namewrite) okbutton.pack(side='bottom') scorewindow.mainloop() highscorefile.close() # incase user wants to countinue after creating highscore # to read his new score highscorefile = open('highscore.txt', 'rt') highscore = highscorefile.readline() highscore = int(highscore) namehighscore = highscorefile.readline() highscorefile.close() else: message("Highscore by " + namehighscore + ":" + str(highscore), (255, 0, 0), 120) pygame.display.update() for event in pygame.event.get(): keyp = action() if keyp != None or event.type == pygame.KEYDOWN: try: if keyp == 'q' or event.key == pygame.K_q: pyExit = True pyOver = False except: blank = [] # bypass the exception try: if keyp == 'c' or event.key == pygame.K_c: gameLoop() except: blank = [] # bypass the exception """ Events """ #the conditions are modified to work with the buttons for event in pygame.event.get(): keyp = action() # blank is not used anywhere # it is just used to jump the exception if event.type == pygame.QUIT: pyExit = True if event.type == pygame.KEYDOWN or keyp != None: try: if keyp == 'lt' or event.key == pygame.K_LEFT: dirn = "left" dx = -1 dy = 0 except: blank = [] try: if keyp == 'rt' or event.key == pygame.K_RIGHT: dirn = "right" dx = 1 dy = 0 except: blank = [] try: if keyp == 'up' or event.key == pygame.K_UP: dirn = "up" dy = -1 dx = 0 except: blank = [] try: if keyp == 'dn' or event.key == pygame.K_DOWN: dirn = "down" dy = 1 dx = 0 except: blank = [] try: if keyp == 'p' or event.key == pygame.K_p: pause() except: blank = [] try: if keyp == 'q' or event.key == pygame.K_q: pygame.quit() quit(0) except: blank = [] # level changer value if score > 10: score = 0 world_num += 1 blocks = worlds(width, height, world_num) food.x, food.y = int(width / 2), int(height / 2) # Engage boost of pressing shift keyp = action() keyPresses = pygame.key.get_pressed() boost_speed = keyPresses[pygame.K_LSHIFT] or keyPresses[ pygame.K_RSHIFT] or keyp == 'st' # if boost_speed is true it will move 2 blocks in one gameloop # else it will just move one block iterations = [1] if boost_speed == 1: iterations.append(2) for i in iterations: """ Update snake """ snake.move(dx, dy, 10) snake.check_boundary(width, height) snake_rect = snake.get_rect() food_rect = food.get_rect() """ Snake-Snake collision """ if snake.ate_itself(): pyOver = True lossreason = 'Oooops You Hit YOURSELF' sound = pygame.mixer.Sound(point_path) sound.play() """ Snake-Block collision """ for block in blocks: block_rect = block.get_rect() if block_rect.colliderect(snake_rect): pyOver = True lossreason = 'Ooops You Hit a BLOCKER' sound = pygame.mixer.Sound(point_path) sound.play() """ Snake-Food collision """ # if snake collides with food, increase its length. if food_rect.colliderect(snake_rect): score += 1 snake.increment_length() sound = pygame.mixer.Sound(point_path) sound.play() # generate food at random x, y. food.generate_food(width, height) # try generating the food at a position where blocks are not present. while food_collides_block(food.get_rect(), blocks): food.generate_food(width - food.size, height - food.size) """ Draw """ game_display.fill((255, 255, 255)) showButton() # draw the food and snake. snake.draw(game_display, dirn, (0, 155, 0)) food.draw(game_display, (0, 255, 0)) # draw the blocks. for block in blocks: block.draw(game_display, (255, 0, 0)) # count and display score on screen totalscore = total(score, world_num) scorestr = 'Score: ' + str(totalscore) font = pygame.font.SysFont(None, 30) text = font.render(scorestr, True, (0, 0, 255)) game_display.blit(text, (0, 0, 20, 20)) pygame.display.update() clock.tick(FPS) pygame.quit() quit()
def gameLoop(): global dirn, k, highscore, namehighscore pyExit = False pyOver = False #stop intro music and play in game music infinite loop intro_sound.stop() game_sound.play(-1) score = 0 world_num = 0 scorestr = "Score:0" # Initialize the game snake = Snake(200, 200, img) food = Food(int(width / 2), int(height / 2)) blocks = worlds(width - 200, height, world_num) # Keeps track of the direction of the snake. dx, dy = 0, 0 lossreason = '' while not pyExit: if pyOver == True: #play end music endgame_sound.play(-1) while pyOver: image = pygame.image.load(python_path) game_display.blit(image, (0, 0)) message("Game Over! Press C to play Again, Q to Quit", (255, 0, 0), -20) message(lossreason, (255, 0, 0), 30) # display score on game over message("Your" + scorestr, (255, 0, 0), 80) if totalscore > highscore: # message("Highscore!!!",(255,0,0),120) # write new highscore highscorefile = open('highscore.txt', 'wt') highscorefile.write(str(totalscore) + "\n") # name window def namewrite(): highscorefile.write(v.get()) scorewindow.destroy() scorewindow = Tk() scorewindow.geometry('300x100') frame = Frame(scorewindow, width=100, height=100) frame.pack() scorewindow.title("congratulations") Label(frame, text='you\'ve made highscore!!!!').pack(side='top') v = StringVar() v.set("type your name") textbox = Entry(frame, textvariable=v) textbox.pack(side='top') okbutton = Button(frame, text="ok", fg="black", bg="white", command=namewrite) okbutton.pack(side='bottom') scorewindow.mainloop() highscorefile.close() # incase user wants to countinue after creating highscore # to read his new score highscorefile = open('highscore.txt', 'rt') highscore = highscorefile.readline() highscore = int(highscore) namehighscore = highscorefile.readline() highscorefile.close() else: message("Highscore by " + namehighscore + ":" + str(highscore), (255, 0, 0), 120) pygame.display.update() for event in pygame.event.get(): keyp = action() if keyp != None or event.type == pygame.KEYDOWN: try: if keyp == 'q' or event.key == pygame.K_q: pyExit = True pyOver = False except: blank = [] # bypass the exception try: if keyp == 'c' or event.key == pygame.K_c: #stop endgame music endgame_sound.stop() gameLoop() except: blank = [] # bypass the exception """ Events """ #the conditions are modified to work with the buttons for event in pygame.event.get(): keyp = action() # blank is not used anywhere # it is just used to jump the exception if event.type == pygame.QUIT: pyExit = True if event.type == pygame.KEYDOWN or keyp != None: try: if keyp == 'lt' or event.key == pygame.K_LEFT and dirn != "right": dirn = "left" dx = -1 dy = 0 except: blank = [] try: if keyp == 'rt' or event.key == pygame.K_RIGHT and dirn != "left": dirn = "right" dx = 1 dy = 0 except: blank = [] try: if keyp == 'up' or event.key == pygame.K_UP and dirn != "down": dirn = "up" dy = -1 dx = 0 except: blank = [] try: if keyp == 'dn' or event.key == pygame.K_DOWN and dirn != "up": dirn = "down" dy = 1 dx = 0 except: blank = [] try: if keyp == 'p' or event.key == pygame.K_p: pause(scorestr) except: blank = [] try: if keyp == 'q' or event.key == pygame.K_q: pygame.quit() quit(0) except: blank = [] # level changer value if score > 10: score = 0 world_num += 1 blocks = worlds(width - 200, height, world_num) food.x, food.y = int(width / 2), int(height / 2) # Engage boost of pressing shift keyp=action() keyPresses = pygame.key.get_pressed() boost_speed = keyPresses[pygame.K_LSHIFT] or keyPresses[pygame.K_RSHIFT] or keyp=='st' # if boost_speed is true it will move 2 blocks in one gameloop # else it will just move one block iterations = [1] if boost_speed == 1: iterations.append(2) for i in iterations: """ Update snake """ snake.move(dx, dy, 10) snake.check_boundary(width, height) snake_rect = snake.get_rect() food_rect = food.get_rect() """ Snake-Snake collision """ if snake.ate_itself(): #stop game sound game_sound.stop() pyOver = True lossreason = 'Oooops You Hit YOURSELF' """ Snake-Block collision """ for block in blocks: block_rect = block.get_rect() if block_rect.colliderect(snake_rect): #stop game sound game_sound.stop() pyOver = True lossreason = 'Ooops You Hit a BLOCKER' """ Snake-Food collision """ # if snake collides with food, increase its length. if food_rect.colliderect(snake_rect): score += 1 snake.increment_length() sound = pygame.mixer.Sound(point_path) sound.set_volume(0.3) sound.play() # generate food at random x, y. food.generate_food(width, height) # try generating the food at a position where blocks are not present. while food_collides_block(food.get_rect(), blocks): food.generate_food(width - food.size, height - food.size) """ Draw """ game_display.fill((255, 255, 255)) showButton() # draw the food and snake. snake.draw(game_display, dirn, (0, 155, 0)) food.draw(game_display, (0, 255, 0)) # draw the blocks. for block in blocks: block.draw(game_display, (255, 0, 0)) # count and display score on screen totalscore = total(score, world_num) scorestr = 'Score: ' + str(totalscore) font = pygame.font.SysFont(None, 30) text = font.render(scorestr, True, (0, 0, 255)) game_display.blit(text, (0, 0, 20, 20)) pygame.display.update() clock.tick(FPS) pygame.quit() quit()
class App(Logger): windowWidth = 880 windowHeight = 660 snake = 0 food = 0 def __init__(self, controller_type, brick_layout_type): Logger.__init__(self) self._running = True self._display_surf = None self._image_surf = None self._food_surf = None self._brick_image = None self.game = Game() self.snake = Snake(3, self.windowHeight, self.windowWidth) self.bricks = Bricks(5, 5, brick_layout_type) self.food = Food() self.food.generate_food(self.snake, self.bricks) self._score = 0 # this needs to be updated as required self.controller_type = controller_type self.snake_controller = constants.controller_name_mapping[ controller_type]() def on_init(self): pygame.init() self._display_surf = pygame.display.set_mode( (self.windowWidth, self.windowHeight), pygame.HWSURFACE) # pygame.display.set_caption('Pygame pythonspot.com example') self._running = True self._image_surf = pygame.image.load("assets/snake.png").convert() self._food_surf = pygame.image.load("assets/food.png").convert() self._brick_image = pygame.image.load("assets/brick.png").convert() self._snake_head_image = pygame.image.load( "assets/snake_head.png").convert() def on_event(self, event): if event.type == QUIT: self._running = False def on_loop(self): self.snake.update() # does snake eat food? if self.game.isCollision(self.food.x, self.food.y, self.snake.x[0], self.snake.y[0], 44): # add score of 1 for eating food self._score += 1 self.food.generate_food(self.snake, self.bricks) self.snake.length = self.snake.length + 1 # does snake collide with itself? for i in range(2, self.snake.length): if self.game.isCollision(self.snake.x[0], self.snake.y[0], self.snake.x[i], self.snake.y[i], 40): print( "Snake tried to move in the {0} direction and collided with itself." .format(constants.move_direction_text_dict[ self.snake.getCurrentDirection()])) print("x[0] (" + str(self.snake.x[0]) + "," + str(self.snake.y[0]) + ")") print("x[" + str(i) + "] (" + str(self.snake.x[i]) + "," + str(self.snake.y[i]) + ")") print("Your score: {0}".format(self._score)) return True # does snake collide with a brick? for i in range(self.bricks.getNumBricks()): if self.game.isCollision(self.bricks.x[i], self.bricks.y[i], self.snake.x[0], self.snake.y[0], 40): print("You lose! Collision with brick: ") print("x[0] (" + str(self.snake.x[0]) + "," + str(self.snake.y[0]) + ")") print("x[" + str(i) + "] (" + str(self.bricks.x[i]) + "," + str(self.bricks.y[i]) + ")") print("Your score: {0}".format(self._score)) return True return False def on_render(self, game_over=False): if not game_over: self._display_surf.fill((0, 0, 0)) self.snake.draw(self._display_surf, self._image_surf, self._snake_head_image) self.food.draw(self._display_surf, self._food_surf) self.bricks.draw(self._display_surf, self._brick_image) self.draw_score(self._display_surf, self.windowWidth - 200, self.windowHeight - 50, self._score) self.draw_snake_direction( self._display_surf, 50, self.windowHeight - 50, constants.move_direction_text_dict[ self.snake.getCurrentDirection()]) else: self.draw_game_over(self._display_surf, self._score) pygame.display.flip() def on_cleanup(self): time.sleep(2) # self.draw_game_over(self._display_surf, self._score) pygame.quit() def on_execute(self): if self.on_init() == False: self._running = False # self.start_logging_new_game() while (self._running): pygame.event.pump() self.snake, should_continue_running = self.snake_controller.perform_next_move( self.snake, self.food, self.bricks) if self.controller_type != constants.MANUAL: keys = pygame.key.get_pressed() if (keys[K_ESCAPE]): print( "Escape key pressed and so quitting the current game.") should_continue_running = False # self.log_snake_move(self.snake.getCurrentDirection()) self._running = should_continue_running is_collision = self.on_loop() if is_collision: self._running = False self.on_render(True) else: self.on_render() time.sleep(50.0 / 1000.0) self.on_cleanup() #Create the text used to display the score and draw it on the screen def draw_score(self, screen, x, y, score): font = pygame.font.Font(None, 36) #Choose the font for the text text = font.render("Score = " + str(score), 1, (255, 255, 255)) #Create the text with white color screen.blit(text, (x, y)) #Draw the text on the screen #Create the text used to display the current direction the snake head is moving def draw_snake_direction(self, screen, x, y, snake_direction_text): font = pygame.font.Font(None, 36) #Choose the font for the text text = font.render("Going: " + snake_direction_text, 1, (255, 255, 255)) #Create the text with white color screen.blit(text, (x, y)) #Draw the text on the screen # draw the game over screen # taken from https://www.teachyourselfpython.com/challenges.php?a=03_Pygame_Challenges_and_Learn&t=01_Function_based_game&s=07_Add_Game_over_feature def draw_game_over(self, screen, score): font = pygame.font.Font(None, 28) #Choose the font for the text text = font.render("COLLISION! GAME OVER!", 1, constants.WHITE) #Create the text for "GAME OVER" screen.blit(text, (self.windowWidth / 2, self.windowHeight / 2)) #Draw the text on the screen
class GameEnvironment: """ Class that models the environment in which the game is played. instance variables: screen : the pygame display surface : the pygame surface snake : A list of Snake objects fps : The speed of the game dir_change_location : A dictionary of coordinates pointing to directions to be followed at those coordinates food : A Food object status : States whether the game is running or over It is 1 if game is running, 0 if game is over. """ def __init__(self): pygame.init() self.status = 1 self.screen = pygame.display self.surface = self.screen.set_mode((800, 600)) self.snake = [Snake(200, 200, 'r')] self.fps = 100 self.dir_change_location = {} self.food = Food() self.food.generate_food() def events(self): """ Contains the event loop for the pygame window.Rectangle images for the snake and the Circle images for food are created in this event loop. Calls to other GameEnvironment methods are made from here. :return: None """ done = False clock = pygame.time.Clock() while not done: # start of the event loop for event in pygame.event.get(): # piping out the events if event.type == pygame.QUIT: self.status = 0 done = True self.food.set_level() # getting the food level set for the game self.fps = (self.food.level * 10) + 100 # setting the speed of the game according the food level self.check_wall() # checking if the snake has banged into the wall self.check_suicide() # checking if the snake has turned into itself if self.status == 0: # checking if the snake is supposed to dead. done = True self.check_food() # checking if the snake has eaten food. pressed = pygame.key.get_pressed() self.update_position(pressed, self.snake[0].x_coord, self.snake[0].y_coord) # updating the position of the snake according to input direction self.surface.fill((0, 0, 0)) for i in range(len(self.food.x)): # loop to display all food. pygame.draw.circle(self.surface, (255, 255, 255), (self.food.x[i], self.food.y[i]), 10) for i in range(len(self.snake)): # loop to display entire snake pygame.draw.rect(self.surface, (55, 255, 55), pygame.Rect(self.snake[i].get_position()[0], self.snake[i].get_position()[1], 20, 20)) self.screen.flip() clock.tick(self.fps) def update_position(self, pressed, x_coord, y_coord): """ Method to make sure that all snake objects change direction at given point :param pressed: A pygame key object :param x_coord: The x coordinate where the change in direction happens :param y_coord: The y coordinate where the change in direction happens :return: None """ dir = '' # String to represent the input direction if pressed[pygame.K_LEFT]: # Condition when left arrow key is pressed dir = 'l' elif pressed[pygame.K_UP]: # Condition when up arrow key is pressed dir = 'u' elif pressed[pygame.K_DOWN]: # Condition when down arrow key is pressed dir = 'd' elif pressed[pygame.K_RIGHT]: # Condition for right arrow key press dir = 'r' if dir != '': # when there is no input, continue in original direction self.dir_change_location[(x_coord, y_coord)] = dir for i in range(len(self.snake)): if (self.snake[i].x_coord, self.snake[i].y_coord) in \ self.dir_change_location.keys(): # checking if a snake node has reached a point where it has to # change direction. old_x = self.snake[i].x_coord old_y = self.snake[i].y_coord self.snake[i].move( self.dir_change_location[(self.snake[i].x_coord, self.snake[i].y_coord)]) # moving that snake object in the direction it has to go in at # that point. The direction is given by the dictionary. if i == len(self.snake) - 1: del self.dir_change_location[(old_x, old_y)] # once the last snake node passes a point, get rid of that # point in the dictionary to prevent the snake from # following old instructions else: self.snake[i].move(self.snake[i].direction) def check_wall(self): """ Method to check if the snake's head has hit the wall. Ends the game if this happens. :return: None """ head = self.snake[0] x = head.get_position()[0] y = head.get_position()[1] if x > 800 or y > 600 or x < 0 or y < 0: # checking if the head of the snake collides with a wall. self.status = 0 # killing the snake def check_food(self): """ Checks if the snake has passed a food object. The length of the snake increases if this happens. Makes appropriate changes to the food object too. :return: """ for i in range(len(self.food.x)): # iterating through all food on screen x = self.food.x[i] y = self.food.y[i] if pygame.Rect(self.snake[i].get_position()[0], self.snake[i].get_position()[1], 20, 20).collidepoint(x, y): # checking if the food snake's head collides with a food object self.snake.append( self.snake[len(self.snake) - 1].get_next_snake()) # making the snake longer. self.food.get_eaten(i) # recording that food was eaten for scoring purposes break def check_suicide(self): """ Checks if the snake turns into itself. Ends the game if this happens :return: None """ head = pygame.Rect(self.snake[0].get_position()[0], self.snake[0].get_position()[1], 20, 20) for snake in self.snake[1:]: body = pygame.Rect(snake.get_position()[0], snake.get_position()[1], 20, 20) if head.collidepoint(body.centerx, body.centery): # checking if the center of the snake's head is in the center of # a part of its body self.status = 0 # killing the snake break