示例#1
0
    def __init__(self):

        pygame.init()

        self.screen = pygame.display.set_mode(
            (SCREEN_WIDTH, SCREEN_HEIGHT), 0, 32)
        self.clock = pygame.time.Clock()

        # Game states
        self.paused = 0
        self.game_over = 0
        self.running = 1
        self.keep_drawing_ship = 1

        # Game objects
        self.ship = ship.Ship(
            self.screen, (SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2))
        self.asteroids = []
        self.bullets = []

        # Scoreboard
        self.score = 0
        self.scoreboard = Scoreboard(self.screen)

        # Bullet Gauge
        self.bullet_gauge = BulletGauge(self.screen, 10, self.spawn_bullet)

        # Health bar
        self.health_bar = Bar(self.screen, self.ship.max_health,
                              [30, SCREEN_HEIGHT - 20,
                               80, 10],
                              RED, WHITE)
        # Game Over Text
        self.game_over_text = GameOverText(self.screen)
        self.reduce_game_over_text_alpha = Timer(
            100, self.game_over_text.reduce_alpha)

        # Asteroid spawning
        self.since_last_asteroid = 0
        self.new_asteroid_time = 1000

        # Levels
        self.level_gen = generate_levels()
        self.level = 1
        self.level_limit = next(self.level_gen)

        self.level_text = LevelText(self.screen)
示例#2
0
class Game(object):

    def __init__(self):

        pygame.init()

        self.screen = pygame.display.set_mode(
            (SCREEN_WIDTH, SCREEN_HEIGHT), 0, 32)
        self.clock = pygame.time.Clock()

        # Game states
        self.paused = 0
        self.game_over = 0
        self.running = 1
        self.keep_drawing_ship = 1

        # Game objects
        self.ship = ship.Ship(
            self.screen, (SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2))
        self.asteroids = []
        self.bullets = []

        # Scoreboard
        self.score = 0
        self.scoreboard = Scoreboard(self.screen)

        # Bullet Gauge
        self.bullet_gauge = BulletGauge(self.screen, 10, self.spawn_bullet)

        # Health bar
        self.health_bar = Bar(self.screen, self.ship.max_health,
                              [30, SCREEN_HEIGHT - 20,
                               80, 10],
                              RED, WHITE)
        # Game Over Text
        self.game_over_text = GameOverText(self.screen)
        self.reduce_game_over_text_alpha = Timer(
            100, self.game_over_text.reduce_alpha)

        # Asteroid spawning
        self.since_last_asteroid = 0
        self.new_asteroid_time = 1000

        # Levels
        self.level_gen = generate_levels()
        self.level = 1
        self.level_limit = next(self.level_gen)

        self.level_text = LevelText(self.screen)

    def run(self):

        while self.running:

            time_passed = self.clock.tick(60)

            # KEYBOARD INPUT
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = 0
                    break

                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        self.running = 0
                        break
                    if event.key == pygame.K_SPACE:
                        if not self.paused and not self.game_over:
                            self.bullet_gauge.shoot()

                    if event.key == pygame.K_p:
                        self.paused = not self.paused

            if not self.paused and not self.game_over:
                self.update(time_passed)

            if self.game_over:
                self.update_game_over_sequence(time_passed)

            self.draw()

    def update(self, time_passed):
        # Send keyboard input
        self.ship.handleKeyevents(pygame.key.get_pressed())

        # Object updates
        self.ship.update(time_passed)

        for bullet in self.bullets:
            bullet.update(time_passed)

        for asteroid in self.asteroids:
            asteroid.update(time_passed, self.ship.pos)

        # Maintenance functions
        self.ship.keep_in_bounds()
        self.maintain_bullets()
        self.maintain_asteroids()

        # Collisions
        self.handle_collisions()

        # Update bullet gauge
        self.bullet_gauge.update(time_passed)

        # Update levels
        self.handle_levels()

        # Add asteroids
        self.spawn_asteroid(time_passed)

    def draw(self):
        self.screen.fill(BLACK)

        # Game HUD
        self.scoreboard.blitme(self.score)
        self.level_text.blitme(self.level)
        if not self.game_over:
            self.bullet_gauge.blitme()
            self.health_bar.blitme(self.ship.health)

        for bullet in self.bullets:
            bullet.blitme()

        for asteroid in self.asteroids:
            asteroid.blitme()

        if self.keep_drawing_ship:
            self.ship.blitme()

        # Game over sequence
        if self.game_over:
            self.explosion.blitme()
            self.game_over_text.blitme()

        pygame.display.flip()

    def maintain_bullets(self):
        for i, bullet in reverse_enumerate(self.bullets):
            if not bullet.in_bounds():
                self.bullets = self.bullets[:i] + self.bullets[i + 1:]

    def maintain_asteroids(self):
        for i, asteroid in reverse_enumerate(self.asteroids):
            if asteroid.time_alive > 1000.0 and not asteroid.in_bounds():
                self.asteroids = self.asteroids[:i] + self.asteroids[i + 1:]

    def handle_collisions(self):

        # Between bullets and asteroids
        for i, bullet in reverse_enumerate(self.bullets):
            for j, asteroid in reverse_enumerate(self.asteroids):
                if collisions.do_collide(bullet, asteroid):

                    self.bullets = self.bullets[:i] + self.bullets[i + 1:]
                    self.asteroids = self.asteroids[
                        :j] + self.asteroids[j + 1:]

                    self.score += 1
                    break

        if not self.ship.invincible:
            for i, asteroid in enumerate(self.asteroids):
                if collisions.do_collide(self.ship, asteroid):
                    self.ship_collision(i)
                    break  # Do not collide with anymore asteroids

    def ship_collision(self, asteroid_index):
        self.ship.health -= 1

        if self.ship.health == 0:
            self.game_over_sequence(asteroid_index)
        else:
            self.ship.make_invincible()

    def spawn_bullet(self):
        self.bullets.append(Bullet(
            self.screen, self.ship.pos, self.ship.dir))

    def handle_levels(self):

        # Check if we passed current level

        if self.score >= self.level_limit:
            self.level += 1
            self.level_limit = next(self.level_gen)

    def spawn_asteroid(self, time_passed):

        self.since_last_asteroid += time_passed

        if self.since_last_asteroid > self.new_asteroid_time:

            rand = random.randint(1, 25)

            if rand <= 1:
                self.asteroids.append(HomingAsteroid(self.screen))
            else:
                self.asteroids.append(Asteroid(self.screen))

            self.since_last_asteroid = 0.0

            # Randomize asteroid spawns and add difficulty
            # by making asteroid spawn faster
            self.new_asteroid_time = (
                random.randint(500, 600) - LEVEL_TIME_CONSTANT * self.level)

    def game_over_sequence(self, colliding_asteroid_index):
        """
        Sequence played when game is over.
        Leave only colliding asteroid, remove all bullets.
        Create ship explosion.
        Make ship stop displaying, but spawn ship animation.
        """
        self.game_over = 1

        time_per_frame = 200

        self.bullets = []
        self.asteroids = [self.asteroids[colliding_asteroid_index]]

        self.spawn_ship_explosion(time_per_frame)

        self.ship_timer = Timer(
            time_per_frame * 4, self.stop_drawing_ship, 1)

    def spawn_ship_explosion(self, ms_per_frame):

        explosion_images = [par_dir() + '/images/explosion%i.png' %
                            i for i in range(1, 11)]

        self.explosion = Animation(
            self.screen, self.ship.pos, explosion_images,
            ms_per_frame, ms_per_frame * 10)

    def stop_drawing_ship(self):
        self.keep_drawing_ship = 0

    def update_game_over_sequence(self, time_passed):
        self.explosion.update(time_passed)
        self.ship_timer.update(time_passed)
        self.reduce_game_over_text_alpha.update(time_passed)