Exemple #1
0
    #check if player got hit by an obstacle
    obstacle1.obstacleOnHit(player1)
    obstacle1.obstacleOnHit(player2)
    obstacle2.obstacleOnHit(player1)
    obstacle2.obstacleOnHit(player2)
    obstacle3.obstacleOnHit(player1)
    obstacle3.obstacleOnHit(player2)

    #display obstacles
    obstacle1.obstacleScreenPosition(screen)
    obstacle2.obstacleScreenPosition(screen)
    obstacle3.obstacleScreenPosition(screen)

    #display map
    gameMap.setGround(screen)

    if ((player1.max_hp <= 0 or player2.max_hp <= 0)
        and winner == 0):
        if (player1.max_hp < player2.max_hp):
            winner = 2
        else:
            winner = 1

    if (winner != 0):
        game = GameOver(winner)
        game.show_winner(screen)

    #Update the display
    pygame.display.update()
Exemple #2
0
from random import randrange

from bird import Bird
from bone import Bone
from game_over import GameOver
from get_key import ClearConsole, GetKey, Wait, WindowSize
from laser import Laser
from map import Map
from paco import Paco
from saver import Saver
from start import Start

if __name__ == '__main__':
    map = Map(133, 33, '#')
    start = Start(133, 33)
    finish = GameOver(133, 33)
    paconator = Paco(1, 15, 133, 33)
    getKey = GetKey()
    save = Saver()
    pigeons = []
    lasers = []
    bones = []
    play_game = False
    game_over = False
    ammo = 20
    points = 0
    x = save.load()
    record = int(x)
    WindowSize()

    # ====== START SCREEN ======
Exemple #3
0
class SnakeGame(FloatLayout):
    head = ObjectProperty(Snake)
    sock = ObjectProperty(Sock)
    score = ObjectProperty(Score)
    g_over = ObjectProperty(GameOver())
    body = []

    def __init__(self):
        super().__init__()

        self.history_pos, self.history_v = None, None
        self.reset_histories()
        self.next_dir = self.head.v
        self.sock.spawn()

        # Init keyboard
        self._keyboard = Window.request_keyboard(self._on_keyboard_closed,
                                                 self)
        self._keyboard.bind(on_key_down=self._on_key_down)

        self.expand_snake = False
        self.crashed = False

    def _on_key_down(self, keyboard, keycode, text, modifiers):
        vx, vy = self.head.v
        if keycode[1] == 'up' and vy > -1:
            self.next_dir = Vector(0, 1)
        elif keycode[1] == 'right' and vx > -1:
            self.next_dir = Vector(1, 0)
        elif keycode[1] == 'down' and vy < 1:
            self.next_dir = Vector(0, -1)
        elif keycode[1] == 'left' and vx < 1:
            self.next_dir = Vector(-1, 0)
        elif keycode[1] == 'spacebar':
            self.restart_game()

    def restart_game(self):
        self.head.pos = self.center
        self.next_dir = Vector(1, 0)
        self.reset_body()
        self.reset_histories()
        self.crashed = False
        self.score.reset()
        self.remove_widget(self.g_over)

    def reset_body(self):
        for snek in self.body:
            self.remove_widget(snek)
        self.body = []

    def reset_histories(self):
        self.history_pos = [(self.head.pos[0], self.head.pos[1])]
        self.history_v = [self.head.v]

    def on_width(self, instance, value):
        self.sock.update_grid_width(value)
        self.sock.spawn()

    def on_height(self, instance, value):
        self.sock.update_grid_height(value)
        self.sock.spawn()

    def sock_snacked(self):
        return self.head.pos == self.sock.pos

    def _on_keyboard_closed(self):
        self._keyboard.unbind(on_key_down=self._on_keyboard_down)
        self._keyboard = None

    def add_body_part(self):
        new_body_part = Snake(pos=self.history_pos[0])
        new_body_part.v = self.history_v[0]
        self.body.insert(0, new_body_part)
        self.add_widget(new_body_part)
        self.expand_snake = False
        self.history_pos.insert(0, ('dummy', 'dummy'))
        self.history_v.insert(0, self.head.v)

    def update_history_pos(self):
        for i, position in enumerate(self.history_pos[1:]):
            self.history_pos[i] = position
        self.history_pos[-1] = (self.head.pos[0], self.head.pos[1])

    def update_history_v(self):
        for i, v in enumerate(self.history_v[1:]):
            self.history_v[i] = v
        self.history_v[-1] = self.head.v

    def update_head_v(self):
        self.head.v = self.next_dir

    def body_move(self):
        if len(self.body) > 0:
            for i, snek in enumerate(self.body):
                snek.v = self.history_v[i + 1]
                snek.move()

    def collision(self):
        if self.head.x < self.x or self.head.right > self.right:
            return True
        if self.head.y < self.y or self.head.top > self.top:
            return True
        for snek in self.body:
            if self.head.pos == snek.pos:
                return True
        return False

    def update(self, dt):
        if not self.crashed:
            self.update_history_pos()
            self.update_head_v()
            self.head.move()
            self.body_move()
            self.update_history_v()
            if self.sock_snacked():
                self.expand_snake = True
                self.sock.spawn()
                self.score.score += 1
                self.score.text = str(self.score.score)
            if self.expand_snake:
                self.add_body_part()
            if self.collision():
                self.crashed = True
                self.add_widget(self.g_over)
                    break  # Break loop if it reaches level 6.
            window_clear('cls')

        if level_complete:
            print(GAME_OVER)
            print(DOLL_PICTURE[lap_counter])
        else:
            print(GAME_OVER)
            print(DOLL_PICTURE[num_image + 1])

        dashboard(word, formatted_word, string_entered, formatted_string_ent,\
                  found_letters)

        keep_playing = ask_continue_playing(keep_playing, level_complete, word)

    if level_complete:
        print(GAME_OVER)
        print(DOLL_PICTURE[lap_counter])
    else:
        print(GAME_OVER)
        print(DOLL_PICTURE[6])


if __name__ == '__main__':
    LEVEL = Levels().LEVELS
    DOLL_PICTURE = Images().IMAGES
    GAME_OVER = GameOver().GAME_OVER
    WORDS = list_words()
    NUM_OF_WORDS_IN_LIST = len(WORDS) - 1
    main()
Exemple #5
0
class Field:
    def __init__(self, screen: Screen):
        self.screen = screen
        self.width = screen.window_width() - 2 * OFFSET
        self.height = screen.window_height() - 2 * OFFSET - SCORE_SPACE
        self.turtle = Turtle()
        self.turtle.hideturtle()
        self.lanes = []
        self.player = Player(min_x=-self.width / 2,
                             max_x=self.width / 2,
                             min_y=-self.height / 2 + 10,
                             max_y=self.height / 2 - 10)
        self.game_over = GameOver()

        self.__prepare_listener()
        self.__prepare_field()
        self.__prepare_lanes()
        self.__prepare_game_over()

    def __prepare_field(self):
        origin_x = -self.width / 2
        origin_y = -self.height / 2
        self.turtle.penup()
        self.turtle.goto(x=origin_x, y=origin_y)

        # draw rectangle
        self.turtle.pendown()
        self.turtle.goto(x=-origin_x, y=origin_y)
        self.turtle.goto(x=-origin_x, y=-origin_y)
        self.turtle.goto(x=origin_x, y=-origin_y)
        self.turtle.goto(x=origin_x, y=origin_y)

    def __prepare_lanes(self):
        max_number_of_lane = int(self.height /
                                 (lane.MINIMUM_WIDTH + LANE_SPACE * 2)) - 1
        # print(max_number_of_lane)
        if max_number_of_lane <= 0:
            raise Exception("Your screen size is way too small")

        for i in range(1, max_number_of_lane + 1):
            origin = (float(-self.width / 2), -self.height / 2 +
                      (lane.MINIMUM_WIDTH + LANE_SPACE * 2) * i)
            new_lane = Lane(origin,
                            width=self.width,
                            height=lane.MINIMUM_WIDTH + LANE_SPACE * 2,
                            should_draw_outline=False)
            if i % 2 == 0:
                new_lane.direction = Direction.RIGHT_TO_LEFT

            self.lanes.append(new_lane)

    def __prepare_listener(self):
        self.screen.listen()
        self.screen.onkey(self.player.go_up, "Up")
        self.screen.onkey(self.player.go_left, "Left")
        self.screen.onkey(self.player.go_right, "Right")
        self.screen.onkey(self.player.go_back, "Down")

    def __prepare_game_over(self):
        self.game_over.penup()
        self.game_over.goto(0, 0)

    def move_cars(self):
        for current_lane in self.lanes:
            current_lane.move_cars()

    def player_did_hit_by_car(self) -> bool:
        for current_lane in self.lanes:
            if current_lane.player_did_hit_by_car(self.player):
                return True
        return False

    @property
    def player_did_reach_top(self):
        return self.player.did_reach_top

    def reset_game(self):
        self.player.go_to_starting_pos()

    def set_up_scoreboard(self, turtle: Turtle):
        turtle.penup()
        turtle.goto(x=-self.width / 2, y=self.height / 2)

    def show_game_over(self):
        self.game_over.display_game_over()
Exemple #6
0
                    auto.back(10)

    # Detect collision
    for car in car_list:
        if car.distance(tim.position()) < 30 and car.ycor() == tim.ycor():
            # Turn off listener
            screen.onkeypress(tim.do_nothing, "Up")

            # Squash turtle
            tim.shapetransform(-1, -1, 0, 1)

            # So that the "GAME OVER" will be on top
            screen.update()

            game_on = False
            end_game = GameOver()
            screen.update()
    if tim.has_crossed_finish():
        tim.to_start()
        level.level += 1
        level.update_level()
        for c in range(0, 3):
            car_list.append(Car())
        if sleep_time > .05:
            sleep_time -= .005
        else:
            for car in car_list:
                car.speed_up()


screen.exitonclick()
Exemple #7
0
class Game:
    BLACK = (0, 0, 0)

    def __init__(self):
        pygame.init()
        self.settings = ai_settings = Settings()
        self.screen = pygame.display.set_mode(
            (ai_settings.screen_width, ai_settings.screen_height))
        pygame.display.set_caption('Pacman Portal')
        self.play_button = Button(ai_settings=ai_settings,
                                  screen=self.screen,
                                  msg='Play Game')

        self.stats = GameStats(settings=ai_settings)
        self.sb = Scoreboard(settings=ai_settings,
                             screen=self.screen,
                             stats=self.stats)

        # self.expandfile = ExpandFile('images/pacman_maze.txt', expandby=4)
        self.maze = Maze(self.screen,
                         mazefile='images/pacman_maze.txt',
                         brickfile='brick',
                         blueportalfile='bluePortal',
                         orangeportalfile='orangePortal',
                         shieldfile='shield',
                         pointfile='point',
                         powerfile='power',
                         cherryfile='cherry')

        self.blueGhost = Ghost(screen=self.screen,
                               settings=ai_settings,
                               ghost_type=1)
        self.redGhost = Ghost(screen=self.screen,
                              settings=ai_settings,
                              ghost_type=2)
        self.orangeGhost = Ghost(screen=self.screen,
                                 settings=ai_settings,
                                 ghost_type=3)
        self.pinkGhost = Ghost(screen=self.screen,
                               settings=ai_settings,
                               ghost_type=4)
        self.player = Player(screen=self.screen,
                             settings=ai_settings,
                             stats=self.stats,
                             sb=self.sb,
                             inky=self.blueGhost,
                             blinky=self.redGhost,
                             clyde=self.orangeGhost,
                             pinky=self.pinkGhost)
        self.game_over_screen = GameOver(screen=self.screen,
                                         settings=self.settings)

    def __str__(self):
        return 'Game(Pacman Portal), maze=' + str(self.maze) + ')'

    def play(self):
        eloop = EventLoop(finished=True, settings=self.settings)
        self.reset_game()
        while True:
            while eloop.finished:
                eloop.check_play_button(self.stats, self.sb, self.play_button)
                if not self.stats.game_active:
                    self.play_button.draw_button()
                pygame.display.flip()
            while self.settings.begin.get_busy():
                eloop.check_events(self.stats, self.player)
                self.settings.begin.get_busy()
            while not eloop.finished:
                eloop.check_events(self.stats, self.player)
                self.update_screen()
                self.player_ghost_update()
                if self.stats.lives_left == 0:
                    self.reset_game()
                    while self.game_over_screen.counter != 2:
                        eloop.check_events(self.stats, self.player)
                        self.game_over_screen.blit_me()
                        pygame.display.flip()
                    eloop.finished = True

    def update_screen(self):
        self.screen.fill(self.BLACK)
        self.maze.blitme()
        self.player.blitme()
        self.blueGhost.blitme()
        self.redGhost.blitme()
        self.orangeGhost.blitme()
        self.pinkGhost.blitme()
        self.sb.show_score()
        pygame.display.flip()

    def player_ghost_update(self):
        self.player.update(self.maze)
        self.blueGhost.update(self.maze)
        self.redGhost.update(self.maze)
        self.orangeGhost.update(self.maze)
        self.pinkGhost.update(self.maze)

    def reset_game(self):
        pygame.mixer.stop()
        self.blueGhost.reset_ghost()
        self.redGhost.reset_ghost()
        self.orangeGhost.reset_ghost()
        self.pinkGhost.reset_ghost()
        self.player.reset_player()
        self.stats.reset_stats()
        self.settings.reset_settings()
        self.maze.build()
        pygame.mouse.set_visible(True)
        self.stats.game_active = False
class AlienInvasion:
    """Overall class to manage game assets and behaviour."""
    def __init__(self):
        """Initialize the game, create game resources."""
        pygame.init()
        self.settings = Settings()

        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Alien Invasion")

        # Create an instance to store game stats and create a scoreboard
        self.stats = GameStats(self)
        self.sb = Scoreboard(self)

        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()

        # Make the title banner and play button
        self.play_button = Button(self, "START")
        self.title_banner = Banner(self, "Alien Invasion")

        # Make a countdown object for displaying count on game start / new ship
        self.countdown = Countdown(self)

        # Make an object for a banner displaying "GAME OVER" when no ships
        # remain
        self.gameover = GameOver(self)

    def run_game(self):
        """Start the main loop of the game."""
        while True:
            self._check_events()

            if self.stats.game_active:
                self.ship.update()
                self._update_bullets()
                self._update_aliens()

            self._update_screen()

    def _check_events(self):
        """ Watch for keyboard and mouse events"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._check_play_button(mouse_pos)
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

    def _check_keydown_events(self, event):
        """Respond to keypresses."""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

    def _check_keyup_events(self, event):
        """Respond to key releases"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _update_screen(self):
        # Redraw the screen during each pass through the loop
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.aliens.draw(self.screen)

        # Draw the score information
        self.sb.show_score()

        # Draw the play button if the game is inactive
        if not self.stats.game_active:
            self.title_banner.draw_banner()
            self.play_button.draw_button()

        # Make the most recently drawn screen visible.
        pygame.display.flip()

    def _reset_game(self):
        """Clears game statistics and resets all sprites."""
        self.stats.reset_stats()
        self.settings.initialize_dynamic_settings()
        self.sb.prep_score()
        self.sb.prep_level()
        self.sb.prep_ships()

        # Delete remaining ships and bullets
        self.aliens.empty()
        self.bullets.empty()

        # Create new alien fleet and center the ship
        self._create_fleet()
        self.ship.center_ship()

    def _check_play_button(self, mouse_pos):
        """Start a new game when the player clicks START."""
        button_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if button_clicked and not self.stats.game_active:
            # Reset the game statistics and settings
            self._reset_game()
            self.stats.game_active = True
            self._count_down(3)

            # Hide the mouse cursor
            pygame.mouse.set_visible(False)

    def _count_down(self, start):
        """Counts down from start and calls current count to be rendered."""
        count = start
        while count > 0:
            self._update_screen()
            self.countdown.draw_count(count)
            pygame.display.flip()
            sleep(1)
            count -= 1

    def _fire_bullet(self):
        """Create a new bullet and add it to the bullets group."""
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_bullets(self):
        """Update position of bullets and delete old bullets."""
        self.bullets.update()

        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

        self._check_bullet_alien_collisions()

    def _create_fleet(self):
        """Create a fleet of aliens."""
        # Create an alien and find the number of aliens in a row
        # Spacing between each alien is equal to one alien width
        # Make an alien
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        available_space_x = self.settings.screen_width - (2 * alien_width)
        number_aliens_x = available_space_x // (2 * alien_width)

        # Determine the number of rows of aliens that fit on the screen
        ship_height = self.ship.rect.height
        available_space_y = (self.settings.screen_height - (3 * alien_height) -
                             ship_height)
        number_rows = available_space_y // (2 * alien_height)

        # Create the full fleet of aliens
        for row_number in range(number_rows):
            for alien_number in range(number_aliens_x):
                self._create_alien(alien_number, row_number)

    def _create_alien(self, alien_number, row_number):
        """Create an alien and place it in the row."""
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien.x = alien_width + 2 * alien_width * alien_number
        alien.rect.x = alien.x
        alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
        self.aliens.add(alien)

    def _check_fleet_edges(self):
        """Respond appropriately if any aliens have reached an edge."""
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        """Drop the entire fleet and change the fleet's direction."""
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _update_aliens(self):
        """Check if the fleet is at an edge, then update the positions of all
		aliens in the fleet."""
        self._check_fleet_edges()
        self.aliens.update()

        # Look for alien-ship collisions
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self._ship_hit()

        # Look for aliens hitting the bottom of the screen
        self._check_aliens_bottom()

    def _check_bullet_alien_collisions(self):
        """Respond to bullet-alien collisions."""
        # Check for bullets that have hit aliens.
        # If so, get rid of the bullet and the aliens.
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens,
                                                True, True)

        if collisions:
            for aliens in collisions.values():
                self.stats.score += self.settings.alien_points * len(aliens)
            self.sb.prep_score()
            self.sb.check_high_score()

        if not self.aliens:
            # Destroy existing bullets and create new fleet
            self.bullets.empty()
            self._create_fleet()

            # Increase level
            self.settings.increase_speed()
            self.stats.level += 1
            self.sb.prep_level()

    def _ship_hit(self):
        """Respond to the ship being hit by an alien."""
        # Decrement ships left and update scoreboard
        self.stats.ships_left -= 1
        self.sb.prep_ships()

        if self.stats.ships_left > 0:
            # Get rid of any remaining aliens and bullets
            self.aliens.empty()
            self.bullets.empty()

            # Create a new fleet and center the ship
            self._create_fleet()
            self.ship.center_ship()

            # Pause
            sleep(1)
            self._count_down(3)

        else:
            self.stats.game_active = False
            self._game_over()
            pygame.mouse.set_visible(True)

    def _check_aliens_bottom(self):
        """Check if any aliens have reached the bottom of the screen."""
        screen_rect = self.screen.get_rect()
        for alien in self.aliens.sprites():
            if alien.rect.bottom >= screen_rect.bottom:
                # Treat this the same as if the ship got hit
                self._ship_hit()
                break

    def _game_over(self):
        """Displays a GAME OVER banner for three seconds when no ships
		remain."""
        self.gameover.draw_game_over()
        pygame.display.flip()
        sleep(3)
Exemple #9
0
class FlappyUnicorn:
    """ A general class to manage the game. """
    def __init__(self):
        """ Constructor """
        pygame.init()
        pygame.mixer.init()

        # Load game icon
        self.game_icon = pygame.image.load('images/game/icon.png')
        pygame.display.set_icon(self.game_icon)

        self.settings = Settings()

        # Set screen dimensions.
        self.SCREEN_HEIGHT, self.SCREEN_WIDTH = self.settings.screen_height, self.settings.screen_width
        pygame.display.set_caption("Flappy Unicorn")
        self.screen = pygame.display.set_mode(
            (self.SCREEN_WIDTH, self.SCREEN_HEIGHT))
        self.screen_rect = self.screen.get_rect()

        self.game_active = False
        self.game_over = False

        self.pillar_time_elapsed = 0
        self.cloud_time_elapsed = 0
        self.clock_tick = 0

        # Audio instance.
        self.audio = Audio()

        # Create start and game over screens.
        self.start_screen = StartScreen(self)
        self.game_over_screen = GameOver(self)

        # Create an animated flying unicorn
        self.unicorn = Unicorn(self)
        self.unicorn_sprite = pygame.sprite.Group(self.unicorn)

        # Create the background
        self.background = Background(self)

        # Create ground.
        self.ground = Ground(self)

        # Create cloud.
        self.clouds = pygame.sprite.Group()

        # Create pillar sprite group.
        self.pillars = pygame.sprite.Group()

        # Create the scoreboard.
        self.scoreboard = Scoreboard(self)

    def run(self):
        """ Main game loop. """

        # Create clock to track time.
        clock = pygame.time.Clock()

        while True:
            # Check key pressed events.
            self._check_key_events()
            self._update_screen()

            # Update clock and time elapsed.
            self.pillar_time_elapsed += clock.get_time()
            self.cloud_time_elapsed += clock.get_time()

            clock.tick(60)

    def _check_key_events(self):
        """ Check for key pressed events. """
        for event in pygame.event.get():
            # Quit / Exit game.
            if event.type == pygame.QUIT:
                sys.exit(0)

            # Key pressed event.
            if event.type == pygame.KEYDOWN:
                self._check_key_down_events(event)

            # Mouse clicked event.
            if event.type == pygame.MOUSEBUTTONDOWN:
                mouse_position = pygame.mouse.get_pos()
                self._check_button_clicked(mouse_position)

    def _check_key_down_events(self, event):
        """ Respond to a key pressed down event. """

        if not self.game_over and not self.start_screen.screen_active:
            if event.key == pygame.K_SPACE:
                self.unicorn.jump_count = 0
                self.audio.play_sound('wings')

        elif event.key == pygame.K_q:
            sys.exit(0)

        elif event.key == pygame.K_p:
            self.game_active = True
            self.start_screen.screen_active = False

    def _check_button_clicked(self, mouse_position):
        """ Check if player clicked a button and process request. """

        # Start game button
        if self.start_screen.start_button.rect.collidepoint(mouse_position):
            self.game_active = True
            self.start_screen.screen_active = False
            pygame.mouse.set_visible(False)

        # Retry Button
        if self.game_over_screen.retry_button.rect.collidepoint(
                mouse_position):
            self.restart()

    def _check_unicorn_collision(self):
        """ Respond to a collision event. """

        for unicorn in self.unicorn_sprite:
            if unicorn.rect.bottom >= self.settings.gnd_col_zone or unicorn.rect.top <= self.screen_rect.top:
                self._game_over_loop()
                self.audio.play_sound('hit')
                return

        obstacle_collision = pygame.sprite.groupcollide(
            self.unicorn_sprite, self.pillars, False, False)
        if obstacle_collision:
            self._game_over_loop()
            self.audio.play_sound('hit')

    def _check_clouds(self):
        """ Manage clouds on screen. """

        if self.cloud_time_elapsed > self.settings.cloud_frequency and len(
                self.clouds) < self.settings.cloud_qty:
            self.cloud_time_elapsed = 0
            new_cloud = Cloud(self)
            self.clouds.add(new_cloud)

        self._check_cloud_edges()

    def _check_cloud_edges(self):
        """ Loop through cloud sprites and check if cloud is still on screen.
            Remove clouds that have scrolled off the display.
        """
        for cloud in self.clouds:
            if cloud.cloud_rect.right <= 0:
                self.clouds.remove(cloud)

    def _create_pillar(self):
        """ Create a new pillar object and add to the pillar sprite group. """
        top_pillar = PillarTop(self)
        bottom_pillar = PillarBottom(self, top_pillar.rect)
        pillars = [top_pillar, bottom_pillar]
        self.pillars.add(*pillars)

    def _check_pillars(self):
        """ A method that manages the pillar obstacles. """

        if self.pillar_time_elapsed > self.settings.pillar_frequency:
            # If a certain time has elapsed (settings.pillar_frequency) create a new pillar.
            self.pillar_time_elapsed = 0
            self._create_pillar()

        self._check_pillar_edges()

    def _check_pillar_edges(self):
        """
            Loop through the group of pillar sprites and check their right edge.
            Remove pillar sprites that have left the screen.
        """
        for pillar in self.pillars.copy():
            if pillar.rect.right <= 0:
                self.pillars.remove(pillar)

    def _perform_checks(self):
        """ Check sprite positions. """

        self._check_pillars()
        self._check_clouds()
        self._check_unicorn_collision()
        self.scoreboard.check_score_zone(self.unicorn_sprite, self.pillars)

    def _update_screen(self):
        """ Update surfaces and flip screen. """

        # Update background image.
        self.background.update()

        if self.game_active:
            self._perform_checks()
            self.scoreboard.update()

            # Draw the pillar sprites that have been added to the pillar sprite group.
            for pillar in self.pillars.sprites():
                pillar.draw_pillars()

            # Update unicorn position and animation.
            self.unicorn_sprite.update()
            self.unicorn_sprite.draw(self.screen)

            # Draw new clouds to screen.
            for cloud in self.clouds.sprites():
                cloud.draw_cloud()

            if not self.game_over:
                # Update scrolling ground position.
                self.ground.update()
                # Update clouds position
                self.clouds.update()
                # Update pillar position
                self.pillars.update()

        elif not self.game_over:
            # Start Screen.
            self.ground.blit_background(start_screen=True)
            self.start_screen.blit_me()
        else:
            self._game_over_loop()

        # Flip the new display to screen.
        pygame.display.flip()

    def _game_over_loop(self):
        """
            Halt game blit game over and retry button to screen.
            Enable mouse cursor.
        """
        self.game_over = True
        self.game_active = False

        if self.unicorn.rect.bottom >= self.screen_rect.bottom:
            self.unicorn.rect.bottom = self.screen_rect.bottom

        self.unicorn_sprite.update(animation=False)
        self.unicorn_sprite.draw(self.screen)
        self.pillars.draw(self.screen)
        self.ground.blit_background()
        self.scoreboard.update()
        self.game_over_screen.blit_me()

        # Enable mouse cursor.
        pygame.mouse.set_visible(True)

    def restart(self):
        """ Reset game attributes and start a new game. """
        self.pillars.empty()
        self.clouds.empty()
        self.unicorn.reset_rect()
        self.scoreboard.score = 0
        self.pillar_time_elapsed = 0
        self.cloud_time_elapsed = 0
        self.game_over = False
        self.game_active = True
        pygame.mouse.set_visible(False)