Exemplo n.º 1
0
class GameScene(Scene):
    def __init__(self, director, background=(0, 0, 0)):
        super().__init__(director)

        self.background = background

        self.ship = Ship(director.screen)

        self.ship_bullets_allowed = 3

        self.laser_sound = pygame.mixer.Sound('assets/sounds/laser.ogg')
        self.alein_explosion = pygame.mixer.Sound(
            'assets/sounds/alien_explosion.ogg')
        self.ship_explosion = pygame.mixer.Sound(
            'assets/sounds/ship_explosion.ogg')
        self.ufo_sound = pygame.mixer.Sound('assets/sounds/ufo.ogg')

        self.background_sound = pygame.mixer.Sound(
            'assets/sounds/background.ogg')

        self.gg_sound = pygame.mixer.Sound('assets/sounds/game_over.ogg')

        self.bullets = Group()
        self.fleet = Group()
        self.explosions = Group()
        self.bunkers = Group()

        self.fleet_drop_speed = 10

        self.rows = 8
        self.cols = self.get_number_aliens_x()

        self.game_stats = GameStats(director)

        self.old_ticks = pygame.time.get_ticks()

        self.ufo_time = random.randint(15, 30) * 1000
        self.ufo_ticks = pygame.time.get_ticks()

        self.ufo = None

    def exit(self):
        self.game_stats.save_scores()

    def reset(self, alien_speed=0.2):
        self.game_stats.reset()

        self.ship_bullets = 0

        self.alien_speed = alien_speed

        self.number_of_bunkers = 5

        self.bullets.empty()
        self.fleet.empty()
        self.bunkers.empty()

        self.create_fleet()
        self.create_bunkers()

        self.ship.reset()

        self.game_stats.save_scores()

        self.ufo_time = random.randint(15, 30) * 1000
        self.ufo_ticks = pygame.time.get_ticks()

        self.ufo = None

        self.background_sound.play(-1)

    def get_number_aliens_x(self):
        alien = Alien(self.director.screen)
        available_space_x = self.director.screen.get_rect().width - 2 * \
            alien.rect.width
        number_aliens_x = int(available_space_x / (2 * alien.rect.width))

        return number_aliens_x

    def create_alien(self, alien_number, row_number, alien_type):
        alien = Alien(self.director.screen,
                      alien_type=alien_type,
                      speed_factor=self.alien_speed)

        alien_width = alien.rect.width

        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.fleet.add(alien)

    def create_fleet(self):
        alien_type = 0
        change_type = self.rows / 4

        for row_number in range(self.rows):
            if int(row_number % change_type) == 0:
                alien_type += 1

            for alien_number in range(self.cols):
                self.create_alien(alien_number, row_number, alien_type)

    def create_bunkers(self):
        space = int(
            (self.director.screen.get_rect().right -
             ((self.number_of_bunkers - 1) * 56)) / self.number_of_bunkers)
        x = space

        for i in range(self.number_of_bunkers):
            self.bunkers.add(Bunker(self.director.screen, x))

            x += space

    def fire_bullet(self, rect, bullet_type="ship"):
        if bullet_type == "ship":
            if self.ship_bullets < self.ship_bullets_allowed:
                new_bullet = Bullet(self.director.screen, rect.centerx,
                                    rect.top)

                self.bullets.add(new_bullet)
                self.laser_sound.play()

                self.ship_bullets += 1
        else:
            new_bullet = Bullet(self.director.screen, rect.centerx, rect.top,
                                (200, 0, 0), 1)

            self.bullets.add(new_bullet)
            self.laser_sound.play()

    def keydown(self, key):
        if key == pygame.K_RIGHT or key == pygame.K_d:
            self.ship.moving_right = True
        elif key == pygame.K_LEFT or key == pygame.K_a:
            self.ship.moving_left = True
        elif key == pygame.K_SPACE:
            self.fire_bullet(self.ship.rect)

    def keyup(self, key):
        if key == pygame.K_RIGHT or key == pygame.K_d:
            self.ship.moving_right = False
        elif key == pygame.K_LEFT or key == pygame.K_a:
            self.ship.moving_left = False

    def create_explosion(self, center, character_type="alien"):
        new_explosion = Explosion(self.director.screen, center)

        self.explosions.add(new_explosion)

        if character_type == "alien":
            self.alein_explosion.play()
        else:
            self.ship_explosion.play()

    def change_fleet_direction(self):
        for alien in self.fleet.sprites():
            alien.direction *= -1
            alien.rect.y += self.fleet_drop_speed

    def check_explosions(self):
        for explosion in self.explosions.sprites():
            if explosion.explosion == 8:
                self.explosions.remove(explosion)

    def check_fleet_edges(self):
        for alien in self.fleet.sprites():
            if alien.check_edges():
                self.change_fleet_direction()
                break

    def check_fleet_bottom(self):
        screen_bottom = self.director.screen.get_rect().bottom

        if self.fleet.sprites()[-1].rect.bottom > screen_bottom:
            self.lose_ship()

    def check_bullets(self):
        screen_height = self.director.screen.get_rect().height

        for bullet in self.bullets.sprites():
            if bullet.speed_factor < 0:
                if bullet.rect.bottom <= 0:
                    self.bullets.remove(bullet)
                    self.ship_bullets -= 1
                else:
                    for alien in self.fleet.sprites():
                        if bullet.rect.colliderect(alien.rect):
                            self.game_stats.score += alien.alien_type * 10
                            self.create_explosion(alien.rect.center)
                            self.fleet.remove(alien)
                            self.bullets.remove(bullet)

                            self.ship_bullets -= 1

                            self.alein_explosion.play()
                    if self.ufo is not None:
                        if bullet.rect.colliderect(self.ufo.rect):
                            self.game_stats.score += random.randint(1, 5) * \
                                1000
                            self.create_explosion(self.ufo.rect.center)
                            self.ship_bullets -= 1
                            self.alein_explosion.play()
                            self.ufo = None
                            self.ufo_sound.stop()
                    for bunker in self.bunkers:
                        if bunker.collide(bullet.rect):
                            self.bullets.remove(bullet)

                            self.ship_explosion.play()

                            self.ship_bullets -= 1

                            if not bunker.standing():
                                self.bunkers.remove(bunker)
            else:
                if bullet.rect.top >= screen_height:
                    self.bullets.remove(bullet)
                elif bullet.rect.colliderect(self.ship.rect):
                    self.create_explosion(self.ship.rect.center)
                    self.bullets.remove(bullet)

                    self.ship_explosion.play()

                    self.lose_ship()

                for bunker in self.bunkers:
                    if bunker.collide(bullet.rect):
                        self.bullets.remove(bullet)

                        self.ship_explosion.play()

                        if not bunker.standing():
                            self.bunkers.remove(bunker)

    def move_aliens_top(self):
        alien = Alien(self.director.screen,
                      alien_type=self.fleet.sprites()[0].alien_type)
        top_y = alien.rect.height

        prev_alien_y = self.fleet.sprites()[0].rect.y

        for alien in self.fleet.sprites():
            if (alien.rect.y > prev_alien_y):
                top_y += 2 * alien.rect.height

            prev_alien_y = alien.rect.y

            alien.rect.y = top_y

    def lose_ship(self):
        if self.game_stats.ships_left > 0:
            self.game_stats.ships_left -= 1

            self.move_aliens_top()

            self.ship.reset()
        else:
            self.gg_sound.play()

            self.background_sound.stop()

            self.director.set_scene("menu")

    def update(self):
        if len(self.fleet.sprites()) == 0:
            self.ufo_sound.stop()
            self.background_sound.stop()
            self.alien_speed += 0.2
            self.reset(self.alien_speed)

            print(len(self.fleet.sprites()))

        if self.ufo is not None:
            if self.ufo.check_edges():
                self.ufo = None

                self.ufo_sound.stop()

                self.ufo_time = random.randint(15, 30) * 1000
                self.ufo_ticks = pygame.time.get_ticks()
            else:
                self.ufo.update()
        else:
            if pygame.time.get_ticks() - self.ufo_ticks >= \
                    self.ufo_time:
                self.ufo = UFO(self.director.screen, self.alien_speed * 2)

                self.ufo_sound.play(-1)

        self.check_explosions()
        self.explosions.update()

        self.ship.update()

        self.check_fleet_edges()
        self.check_fleet_bottom()
        self.fleet.update()

        if len(self.fleet.sprites()) > 0 and \
                pygame.time.get_ticks() - self.old_ticks >= \
                10000 / self.game_stats.level:
            fleet = self.fleet.sprites()
            self.fire_bullet(fleet[random.randint(0,
                                                  len(fleet) - 1)].rect,
                             "alien")
            self.old_ticks = pygame.time.get_ticks()

        self.check_bullets()
        self.bullets.update()

        if len(self.fleet.sprites()) > 0 and \
                self.fleet.sprites()[-1].rect.bottom >= \
                self.bunkers.sprites()[0].top_left_triangle_rect.top:
            for alien in self.fleet.sprites():
                for bunker in self.bunkers.sprites():
                    if bunker.collide(alien.rect):
                        self.create_explosion(alien.rect.center)
                        self.fleet.remove(alien)

                        self.alein_explosion.play()

                        if not bunker.standing():
                            self.bunkers.remove(bunker)

        self.game_stats.update()

        if self.game_stats.ships == 0:
            self.ufo_sound.stop()
            self.background_sound.stop()

    def render(self):
        self.director.screen.fill(self.background)

        self.game_stats.render()

        for explsion in self.explosions.sprites():
            explsion.render()

        self.ship.render()

        for bullet in self.bullets.sprites():
            bullet.render()

        for alien in self.fleet.sprites():
            alien.render()

        for bunker in self.bunkers.sprites():
            bunker.render()

        if self.ufo is not None:
            self.ufo.render()
Exemplo n.º 2
0
class MenuScene(Scene):
    def __init__(self, director, background=(0, 0, 0)):
        super().__init__(director)

        self.background = background

        text_rect = pygame.Rect(0, 20, 300, 140)
        text_rect.centerx = director.screen.get_rect().centerx

        self.logo = Text(text_rect, 140, (255, 255, 255), director.screen,
                         "SPACE")

        text_rect.centery += 60

        self.header = Text(text_rect, 90, (0, 180, 0), director.screen,
                           "INVADERS")

        self.alien_one = Alien(director.screen)
        self.alien_two = Alien(screen=director.screen, alien_type=2)
        self.alien_three = Alien(screen=director.screen, alien_type=3)
        self.alien_four = Alien(screen=director.screen, alien_type=4)
        self.ufo = UFO(director.screen)

        self.alien_one.rect.center = self.alien_two.rect.center = \
            self.alien_three.rect.center = self.alien_four.rect.center = \
            self.ufo.rect.center = director.screen.get_rect().center

        self.alien_one.rect.centerx -= self.ufo.rect.width + 20
        self.alien_two.rect.centerx -= self.ufo.rect.width + 20
        self.alien_three.rect.centerx -= self.ufo.rect.width + 20
        self.alien_four.rect.centerx -= self.ufo.rect.width + 20
        self.ufo.rect.centerx -= self.ufo.rect.width + 20

        self.alien_one.rect.centery -= self.alien_one.rect.height * 2 + 40
        self.alien_two.rect.centery -= self.alien_two.rect.height + 20
        self.alien_four.rect.centery += self.alien_four.rect.height + 20
        self.ufo.rect.centery += self.alien_four.rect.height + \
            self.ufo.rect.height + 40

        self.score_one = Text(self.alien_one.rect, 30, (150, 150, 150),
                              director.screen, "= 10")
        self.score_two = Text(self.alien_two.rect, 30, (150, 150, 150),
                              director.screen, "= 20")
        self.score_three = Text(self.alien_three.rect, 30, (150, 150, 150),
                                director.screen, "= 30")
        self.score_four = Text(self.alien_four.rect, 30, (150, 150, 150),
                               director.screen, "= 40")
        self.score_five = Text(self.ufo.rect, 30, (150, 150, 150),
                               director.screen, "= ???")

        self.score_one.rect.centerx = self.score_two.rect.centerx = \
            self.score_three.rect.centerx = self.score_four.rect.centerx = \
            self.score_five.rect.centerx = self.ufo.rect.centerx + \
            self.ufo.rect.width + 20

        self.score_five.rect.centerx += 8

        self.score_one.prep_img()
        self.score_two.prep_img()
        self.score_three.prep_img()
        self.score_four.prep_img()
        self.score_five.prep_img()

        menu_rect = pygame.Rect(0, 0, 100, 30)

        menu_rect.center = director.screen.get_rect().center
        menu_rect.y = director.screen.get_rect().bottom - 150

        self.play = Text(menu_rect, 50, (255, 255, 255), director.screen,
                         "PLAY GAME")

        menu_rect.y += 60

        self.high_score = Text(menu_rect, 50, (255, 255, 255), director.screen,
                               "HIGH SCORES")

        self.mouse_on = None

    def mousebuttondown(self, button, point):
        self.mouse_on = None

        if self.play.rect.collidepoint(point):
            self.director.set_scene("game")
        elif self.high_score.rect.collidepoint(point):
            self.director.set_scene("scores")

    def update(self):
        point = pygame.mouse.get_pos()

        if self.mouse_on is not None:
            self.mouse_on.color = (255, 255, 255)
            self.mouse_on.prep_img()
            self.mouse_on = None

        if self.play.rect.collidepoint(point):
            self.mouse_on = self.play
        elif self.high_score.rect.collidepoint(point):
            self.mouse_on = self.high_score

    def render(self):
        self.director.screen.fill(self.background)

        self.logo.render()
        self.header.render()

        self.alien_one.render()
        self.alien_two.render()
        self.alien_three.render()
        self.alien_four.render()
        self.ufo.render()

        self.score_one.render()
        self.score_two.render()
        self.score_three.render()
        self.score_four.render()
        self.score_five.render()

        if self.mouse_on is not None:
            self.mouse_on.color = (0, 180, 0)
            self.mouse_on.prep_img()

        self.play.render()
        self.high_score.render()