Example #1
0
    def run_game(self):
        game_over = True
        running = True

        while running:
            if game_over:
                self.show_go_screen()
                game_over = False
                self.all_sprites = pygame.sprite.Group()
                self.mobs = pygame.sprite.Group()
                self.enemies = pygame.sprite.Group()
                self.bullets = pygame.sprite.Group()
                self.powerups = pygame.sprite.Group()

                self.player = Player(self.settings, self.graphics_provider,
                                     self.sound_provider, self.bullets,
                                     self.all_sprites)

                self.all_sprites.add(self.player)
                for i in range(8):
                    self.new_mob()

                for i in range(3):
                    self.new_enemy()

                score = 0

            # keep loop running at the right speed
            self.clock.tick(self.settings.FPS)
            # Process input (events)
            for event in pygame.event.get():
                # check for closing window
                if event.type == pygame.QUIT:
                    running = False

            # Update
            self.all_sprites.update()

            # check to see if a bullet hit a mob
            hits = pygame.sprite.groupcollide(self.mobs, self.bullets, True,
                                              True)
            for hit in hits:
                score += 50 - hit.radius
                random.choice(self.sound_provider.expl_sounds).play()
                expl = Explosion(hit.rect.center, 'large',
                                 self.graphics_provider)
                self.all_sprites.add(expl)
                if random.random() > 0.9:
                    powerup = Powerup(hit.rect.center, self.settings,
                                      self.graphics_provider)
                    self.all_sprites.add(powerup)
                    self.powerups.add(powerup)
                self.new_mob()

            # check to see if a bullet hit an enemy
            hits = pygame.sprite.groupcollide(self.enemies, self.bullets, True,
                                              True)
            for hit in hits:
                score += 50 - hit.radius
                random.choice(self.sound_provider.expl_sounds).play()
                expl = Explosion(hit.rect.center, 'large',
                                 self.graphics_provider)
                self.all_sprites.add(expl)
                if random.random() > 0.9:
                    powerup = Powerup(hit.rect.center, self.settings,
                                      self.graphics_provider)
                    self.all_sprites.add(powerup)
                    self.powerups.add(powerup)
                self.new_enemy()

            # check to see if a mob hit the player
            hits = pygame.sprite.spritecollide(self.player, self.mobs, True,
                                               pygame.sprite.collide_circle)
            for hit in hits:
                self.player.shield -= hit.radius * 2
                expl = Explosion(hit.rect.center, 'small',
                                 self.graphics_provider)
                self.all_sprites.add(expl)
                self.new_mob()
                if self.player.shield <= 0:
                    self.sound_provider.player_die_sound.play()
                    death_explosion = Explosion(self.player.rect.center,
                                                'player',
                                                self.graphics_provider)
                    self.all_sprites.add(death_explosion)
                    self.player.hide()
                    self.player.lives -= 1
                    self.player.shield = 100

            # check to see if player hit a powerup
            hits = pygame.sprite.spritecollide(self.player, self.powerups,
                                               True)
            for hit in hits:
                if hit.type == 'shield':
                    self.player.shield += random.randrange(10, 30)
                    self.sound_provider.shield_sound.play()
                    if self.player.shield >= 100:
                        self.player.shield = 100
                if hit.type == 'gun':
                    self.player.powerup()
                    self.sound_provider.power_sound.play()

            # if the player died and the explosion has finished playing
            if self.player.lives == 0 and not death_explosion.alive():
                game_over = True

            # Draw / render
            self.screen.fill(self.settings.colors.black)
            self.screen.blit(self.graphics_provider.background,
                             self.graphics_provider.background_rect)
            self.all_sprites.draw(self.screen)
            self.draw_text(self.screen, str(score), 18,
                           self.settings.WIDTH / 2, 10)
            self.draw_shield_bar(self.screen, 5, 5, self.player.shield)
            self.draw_lives(self.screen, self.settings.WIDTH - 100, 5,
                            self.player.lives,
                            self.graphics_provider.player_mini_img)
            # *after* drawing everything, flip the display
            pygame.display.flip()
Example #2
0
class Game:

    # initialize pygame and create window
    def __init__(self):

        # sound buffer size decrease
        pygame.mixer.pre_init(44100, -16, 1, 512)
        pygame.init()
        pygame.mixer.init()
        pygame.display.set_caption("Space Shooter")
        self.screen = pygame.display.set_mode(
            (config.WIDTH, config.HEIGHT), pygame.HWSURFACE | pygame.DOUBLEBUF)
        self.clock = pygame.time.Clock()

        self.background = Background()

        self.init_explosion_images()

        self.score = 0
        self.power_up_rate = 0.9  # default value: 0.9

        # Float_Texts
        self.score_textes = []
        self.shield_bonus_textes = []

        # Sound init
        self.sound_handler = Sound_Handler()
        self.sound_laser = self.sound_handler.sounds["laser"][1]
        pygame.mixer.music.load(config.background_music)
        pygame.mixer.music.play(loops=-1)

        # Loop continuing conditions
        self.running = True
        self.gameover = True

        # Hiding cursor
        pygame.mouse.set_visible(False)

    def init(self):

        self.sprites = pygame.sprite.Group()
        self.mobs = pygame.sprite.Group()
        self.bullets = pygame.sprite.Group()
        self.power_ups = pygame.sprite.Group()

        for i in range(config.NB_MOBS):
            new_mob = Mob()
            new_mob.add(self.mobs, self.sprites)

        self.player = Player()
        self.sprites.add(self.player)

        self.score = 0
        self.gameover = False

    def init_explosion_images(self):

        self.explosion_anim = {}
        self.explosion_anim['lg'] = []
        self.explosion_anim['sm'] = []
        self.explosion_anim['player'] = []
        for i in range(9):
            img = pygame.image.load(
                config.regular_explosion_filenames[i]).convert_alpha()
            img_lg = pygame.transform.scale(img, (75, 75))
            self.explosion_anim['lg'].append(img_lg)
            img_sm = pygame.transform.scale(img, (32, 32))
            self.explosion_anim['sm'].append(img_sm)
            img_player = pygame.image.load(
                config.sonic_explosion_filenames[i]).convert_alpha()
            self.explosion_anim['player'].append(img_player)

    def draw_text(self, text, size, x, y, color):

        font = pygame.font.Font(config.font_name, size)
        text_surface = font.render(text, True, color)  # antialiazed
        text_rect = text_surface.get_rect()
        text_rect.midtop = (x, y)
        self.screen.blit(text_surface, text_rect)

    def draw_shield_bar(self):

        x = 10
        y = 10
        BAR_LENGTH = 100
        BAR_HEIGHT = 20
        fill = (self.player.shield * 100) // self.player.initial_shield
        outline_rect = pygame.Rect(x, y, BAR_LENGTH, BAR_HEIGHT)
        fill_rect = pygame.Rect(x, y, fill, BAR_HEIGHT)
        pygame.draw.rect(self.screen, Color.GREEN.value, fill_rect)
        pygame.draw.rect(self.screen, Color.WHITE.value, outline_rect, 3)

    def draw_lives(self):

        for i in range(self.player.lives):
            img_rect = self.player.image_mini.get_rect()
            img_rect.x = config.WIDTH + (i - self.player.lives) * 40
            img_rect.y = 5
            self.screen.blit(self.player.image_mini, img_rect)

    def show_gameover_screen(self):

        waiting = True
        quitting = False

        while waiting:
            self.clock.tick(config.FPS)
            self.background.update()
            self.screen.blit(self.background.image, self.background.rect)
            self.screen.blit(self.background.image,
                             (self.background.rect.x,
                              self.background.rect.y - self.background.rect.h))
            self.draw_text("Space Shooter", 44, config.WIDTH // 2,
                           config.HEIGHT // 4 - 30, Color.WHITE.value)
            self.draw_text("--- Commands ---", 14, config.WIDTH // 2,
                           (config.HEIGHT * 2) // 4 - 30, Color.WHITE.value)
            self.draw_text("[QD] or arrow keys to move", 14, config.WIDTH // 2,
                           (config.HEIGHT * 2) // 4 + 30 - 30,
                           Color.WHITE.value)
            self.draw_text("[Space] to fire", 14, config.WIDTH // 2,
                           (config.HEIGHT * 2) // 4 + 50 - 30,
                           Color.WHITE.value)
            self.draw_text("[Esc] to quit game", 14, config.WIDTH // 2,
                           (config.HEIGHT * 2) // 4 + 70 - 30,
                           Color.WHITE.value)
            self.draw_text("Press [Enter] to play", 22, config.WIDTH // 2,
                           (config.HEIGHT * 3) // 4 + 70 - 30,
                           Color.WHITE.value)
            pygame.display.flip()

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False
                    quitting = True
                elif event.type == pygame.KEYDOWN:
                    log.info("[waiting menu] [" + str(event) + "] pressed")
                    if (event.key == pygame.K_ESCAPE):
                        self.running = False
                        quitting = True
                    if event.key == pygame.K_RETURN:
                        waiting = False
                        self.sound_handler.play('bolt')

            if quitting:
                waiting = False
                log.info("Exiting the game over waiting loop loop")

    def process_inputs(self):

        keys = pygame.key.get_pressed()
        if keys[pygame.K_SPACE]:
            now = pygame.time.get_ticks()
            if now - self.player.last_shoot > self.player.shoot_delay and not self.player.hidden:
                self.player.last_shoot = now
                self.player.shoot(self.bullets)
                self.sprites.add(self.bullets)
                self.sound_handler.play("laser")

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
            elif event.type == pygame.KEYDOWN:
                log.info("[" + str(event) + "] pressed")
                if (event.key == pygame.K_ESCAPE):
                    self.gameover = True

    def update(self):

        self.background.update()
        self.sprites.update()

        # list of mobs collided with player ; mobs are deleted
        mob_hits_with_player = pygame.sprite.spritecollide(
            self.player, self.mobs, True, pygame.sprite.collide_circle)

        for mob_hit in mob_hits_with_player:
            self.sound_handler.play("player_hit")
            self.player.shield -= mob_hit.radius * 2
            expl = Explosion(self.explosion_anim, mob_hit.rect.center, 'sm')
            self.sprites.add(expl)
            new_mob = Mob()
            new_mob.add(self.mobs, self.sprites)
            if self.player.shield < 0:
                self.sound_handler.play("player_death")
                self.death_explosion = Explosion(self.explosion_anim,
                                                 self.player.rect.center,
                                                 'player')
                self.sprites.add(self.death_explosion)
                self.player.hide()
                self.player.lives -= 1
                self.player.shield = self.player.initial_shield

        # check if player died
        if self.player.lives == 0 and not self.death_explosion.alive():
            self.gameover = True
            log.info("Game Over!")
            log.info("Score: " + str(self.score))

        # list of mobs collided with the bullets ; both are deleted
        mob_hits_with_bullets = pygame.sprite.groupcollide(
            self.mobs, self.bullets, True, True)

        for mob_hit in mob_hits_with_bullets:
            self.sound_handler.play("explosion")
            points_gained = 60 - mob_hit.radius
            self.score += points_gained
            log.info("Hit Radius: " + str(mob_hit.radius))
            self.score_textes.append(
                Float_Text(str(points_gained), 60, mob_hit.rect.midtop[0],
                           mob_hit.rect.midtop[1] - 10))
            expl = Explosion(self.explosion_anim, mob_hit.rect.center, 'lg')
            self.sprites.add(expl)
            new_mob = Mob()  # respawn a new mob
            new_mob.add(self.mobs, self.sprites)
            if random.random() > self.power_up_rate:  # 90%
                power = Power_Up(mob_hit.rect.center)
                power.add(self.sprites, self.power_ups)

        # list of power_ups collided with player ; power_ups are deleted
        power_up_hits_with_player = pygame.sprite.spritecollide(
            self.player, self.power_ups, True)

        for pu_hit in power_up_hits_with_player:
            level = pu_hit.level
            if pu_hit.type == 'shield':
                self.sound_handler.play("shield")
                bonus = 1 if level == 'bronze' else 3 if level == 'silver' else 9
                bonus *= self.player.initial_shield // random.randrange(
                    12, 30)  # 20 / 40 / 60 %
                self.player.shield += bonus
                self.player.shield = self.player.initial_shield if self.player.shield > self.player.initial_shield else self.player.shield
                self.shield_bonus_textes.append(
                    Float_Text(str(bonus), 60, pu_hit.rect.midtop[0],
                               pu_hit.rect.midtop[1] - 10))
            elif pu_hit.type == 'bolt':
                self.sound_handler.play("bolt")
                self.player.shoot_bonus_counter += 3 * (
                    1 if level == 'bronze' else 2 if level == 'silver' else 4)

        # moving floating text about points got from destroying mobs
        self.score_textes = list(
            filter(lambda x: x.lifetime > 0, self.score_textes))
        for s in self.score_textes:
            s.update(2, 2)

        # moving floating text about shield bonuses
        self.shield_bonus_textes = list(
            filter(lambda x: x.lifetime > 0, self.shield_bonus_textes))
        for s in self.shield_bonus_textes:
            s.update(1, 1)

    def draw(self):

        self.screen.blit(self.background.image, self.background.rect)
        self.screen.blit(self.background.image,
                         (self.background.rect.x,
                          self.background.rect.y - self.background.rect.h))
        self.sprites.draw(self.screen)

        for score in self.score_textes:
            self.draw_text(score.text, 20, score.x, score.y, Color.WHITE.value)

        for bonus_text in self.shield_bonus_textes:
            self.draw_text(bonus_text.text, 20, bonus_text.x, bonus_text.y,
                           Color.YELLOW.value)

        if self.player.shoot_bonus_counter > 0:
            self.draw_text(str(self.player.shoot_bonus_counter), \
                min(15 + 3*self.player.shoot_bonus_counter, config.WIDTH), \
                config.WIDTH//2, 50, Color.GREEN.value)

        self.draw_text(str(self.score), 20, config.WIDTH // 2, 10,
                       Color.WHITE.value)
        self.draw_shield_bar()
        self.draw_lives()

    def render(self):
        pygame.display.flip()

    def run(self):
        previous_tick = pygame.time.get_ticks()
        exec_time = 0
        wait_time = 0
        while self.running:
            while self.gameover:
                self.show_gameover_screen()
                self.init()
                self.gameover = False

            # execution time
            exec_time = pygame.time.get_ticks() - previous_tick
            # log.info("[exec_time] " + str(exec_time) + " ms")

            # wait until 1/FPS has passed (16.6666667 ms)
            self.clock.tick(config.FPS)  # keep loop running at the right speed

            # measure time waited
            wait_time = pygame.time.get_ticks() - previous_tick - exec_time
            # log.info("[wait_time]" + str(wait_time) + " ms")
            # log.info("[wait_time + exec_time] " + str(wait_time + exec_time) + " ms") # should be 15 or 16

            print_percent_bar(
                exec_time, 16, True, '[0]', '[16]ms [exec_time=' +
                str(exec_time) + '|wait_time=' + str(wait_time) + ']')

            # sample time right after the end of the waiting
            previous_tick = pygame.time.get_ticks()
            # log.info("[Start] " + str(previous_tick / 1000) + " s")

            self.process_inputs()
            self.update()
            self.draw()
            self.render()

        log.info("Exiting the Game.run() loop")
        pygame.quit()
Example #3
0
class TimeCrystal(Planet):
    def __init__(self, scene, pos, size, resources):
        super().__init__(scene, pos, size, resources)
        self.freeze_timer = 30 #FREEZE_INTERVAL
        self.frozen_ships = []
        self.frozen_replicas = []
        self.exp = None
        self.countdown = text.Text("", "tiny", self.pos + V2(0,-4), PICO_YELLOW, border=PICO_BLACK)
        self.countdown.offset = (0.5, 0.5)
        self.scene.ui_group.add(self.countdown)


    def generate_stranded_ships(self):
        stranded_ships = ['fighter', 'colonist', 'fighter', 'colonist']
        if random.random() > 0.5:
            stranded_ships.append('bomber')
        else:
            stranded_ships.append('interceptor')
        theta = random.random() * 6.2818
        for ship in stranded_ships:
            p = self.pos + helper.from_angle(theta) * random.randint(18,32)
            s = SHIPS_BY_NAME[ship](self.scene, p, self.scene.player_civ)
            if ship == 'colonist':
                s.set_pop(random.randint(2,5))
            self.scene.game_group.add(s)
            self.freeze(s)
            theta += random.random() + 0.1

    def add_ship(self, type, notify=True):
        print(type)
        super().add_ship(type, notify)
        print(self.ships)

    def generate_base_art(self):
        w = h = self.radius * 2
        self.art = pygame.image.load(resource_path("assets/timecrystal.png"))

    def _generate_base_frames(self):
        self._sheet = self.art
        self._frame_width = 29
        self._width = self._frame_width
        self._height = 37
        self.art_inactive = self._sheet.subsurface((0,0,self._frame_width, self._height))
        self.art_hover = self._sheet.subsurface((self._frame_width,0,self._frame_width, self._height))
        self._recalc_rect()

    def _generate_frames(self):
        return

    def special_update(self, dt):
        self.freeze_timer -= dt
        if self.freeze_timer < 0:
            radius = 60
            self.freeze_timer += FREEZE_INTERVAL
            self.exp = Explosion(self.pos, [PICO_BLUE, PICO_PINK,PICO_BLUE, PICO_PINK,PICO_BLUE, PICO_PINK], 1.0, radius, line_width=3)
            self.scene.game_group.add(self.exp)

        self.countdown.set_text("%d" % math.ceil(self.freeze_timer))

        if self.exp:
            for s in self.scene.get_civ_ships(self.scene.player_civ):
                if (s.pos - self.exp.pos).length_squared() < self.exp.size ** 2:
                    self.freeze(s)
            if not self.exp.alive():
                self.exp = None

        return super().special_update(dt)

    def freeze(self, s):
        self.frozen_ships.append(s)
        self.scene.game_group.remove(s)
        replica = self.make_frozen_sprite(s)
        self.frozen_replicas.append(replica)
        self.scene.game_group.add(replica)

    def make_frozen_sprite(self, ship):
        outline_mask = pygame.mask.from_surface(ship.image, 127)
        surf = outline_mask.to_surface(setcolor=(*PICO_WHITE,255), unsetcolor=(0,0,0,0))      

        color_mask = pygame.mask.from_threshold(ship.image, (*PICO_GREEN,255), (2,2,2,255))
        surf2 = color_mask.to_surface(setcolor=(*PICO_BLUE,255), unsetcolor=(0,0,0,0))
        surf.blit(surf2,(0,0))
        s = SimpleSprite(ship.pos, surf)
        s.offset = (0.5,0.5)
        return s

    def on_die(self):
        super().on_die()
        self.kill()

    def kill(self):
        for ship in self.frozen_ships:
            self.unfreeze_ship(ship)
        for replica in self.frozen_replicas:
            replica.kill()
        self.countdown.kill()

        sound.play_explosion()
        base_angle = random.random() * 6.2818
        for x in range(self.image.get_width()):
            for y in range(self.image.get_height()):
                color = tuple(self.image.get_at((x,y)))
                if color[3] >= 128 and color[0:3] != PICO_BLACK:
                    _,a = (V2(x,y) - V2(self.width/2,self.height/2)).as_polar()
                    a *= 3.14159 / 180
                    ad = abs(helper.get_angle_delta(a, base_angle))
                    if ad > 3.14159/2:
                        a = base_angle + 3.14159
                    else:
                        a = base_angle
                    pvel = helper.from_angle(a) * 6
                    p = particle.Particle([
                        color[0:3],
                        color[0:3],
                        DARKEN_COLOR[color[0:3]]
                        ],
                        1,
                        self.pos + V2(x - self.width // 2,y - self.height // 2),
                        1.25 + random.random() ** 2,
                        pvel
                    )
                    self.scene.game_group.add(p)  

        return super().kill()

    def unfreeze_ship(self, ship):
        self.scene.game_group.add(ship)
        ship.set_state("returning")

    def is_buildable(self):
        return False
Example #4
0
                            hit.rect.center)
        explode.effects.play()
        all_sprites.add(explode)
        # stats.life_percentage = player.shield
        # score_board.prep_shield_bar()
        newMob()
        if player.shield <= 0:
            ship_explode = Explosion(ui_settings, ship_explode_sheet, 64, 64,
                                     hit.rect.center)
            player.effects.play()
            all_sprites.add(ship_explode)
            player.hide()
            stats.lives_left -= 1
            player.shield = 100

    # Check if the player live is 0
    if stats.lives_left == 0 and not ship_explode.alive():
        game_over = True

    # Draw / render
    screen.fill(ui_settings.BLACK)
    screen.blit(background, background_rect)
    debris.scroll()
    # screen.blit(debris, debris_rect)
    score_board.show_scoreboard()
    all_sprites.draw(screen)
    # after drawing everything, flip the display
    pygame.display.flip()

pygame.quit()
Example #5
0
            stone.move(t, (screen.get_width(), screen.get_height()),
                       decrement_stones)

        if alien.alive():  #alien이 아직 살아있는 동안에 stone과의 충돌 여부를 확인.
            collided = pygame.sprite.groupcollide(stone_group, alien_group,
                                                  False, True)
            if collided:  #충돌하면 explosion위치를 alien있던 곳으로 옮기고 효과음.
                explosion.rect.x = \
                    (alien.rect.x + alien.rect.width/2) - \
                     explosion.rect.width/2
                explosion.rect.y = \
                    (alien.rect.y + alien.rect.height/2) - \
                    explosion.rect.height/2
                crash_sound.play()

        elif not explosion.alive():
            # 외계인도 죽고 폭발 애니메이션도 끝났을 때.
            game_state = GAME_CLEAR

        # 외계인이 살아 있는데 돌멩이 수가 0이면 게임 오버.
        if alien.alive() and stone_count == 0:
            game_state = GAME_OVER

        if game_state == GAME_PLAY:  # 게임 객체 업데이트
            catapult_group.update()
            stone_group.update()
            alien_group.update()

        # 3) 게임 상태 그리기
        background_group.update()
        background_group.draw(screen)