예제 #1
0
def main():
    pg.init()
    pg.font.init()
    screen = pg.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
    pg.display.set_caption('My_game')
    clock = pg.time.Clock()

    # sprites
    img = load_image('player.png')
    Player.images = [img]
    img = load_image('player_shot.png')
    Player_shot.images = [img]
    img = load_image('enemy_new.png')
    Enemy.images = [img]

    # sounds
    crow_sound = load_sound('crow.wav')
    shot_sound = load_sound('shot.wav')
    shot_sound.set_volume(0.1)

    background = pg.Surface(SCREEN_RECT.size)
    background.fill(BACKGROUND_COLOR)
    screen.blit(background, (0, 0))

    pg.display.flip()

    # Создание контейнеров
    all = pg.sprite.RenderUpdates()
    shots = pg.sprite.Group()
    enemies = pg.sprite.Group()

    # Присвоение контейнеров
    Player.containers = all
    Player_shot.containers = all, shots
    Enemy.containers = all, enemies

    player = Player()
    # Таймеры появлений объектов
    gun_timer = 0
    enemy_spawn_timer = 0
    crow_sound_timer = 0
    score_delta = 0
    score = Score()
    game_over = False

    def check_quit_keys():
        for event in pg.event.get():
            if event.type == QUIT or \
                    (event.type == KEYDOWN and event.key == K_ESCAPE):
                return True

    if pg.font:
        all.add(score)

    # initialiaing fonts
    pg.font.init()
    my_font = pg.font.SysFont('Comic Sans MS', 40)
    my_font_bot = pg.font.SysFont('Comic Sans MS', 20)
    text_over = my_font.render('Game over', False, (0, 0, 0))
    text_score = my_font.render('Score: ' + str(score.score), False, (0, 0, 0))
    instruction = my_font_bot.render('Press S to start a new game ', False,
                                     (0, 0, 0))

    while player.alive():
        if check_quit_keys():
            break

        key_state = pg.key.get_pressed()
        horiz_direction = key_state[K_RIGHT] - key_state[K_LEFT]
        vert_direction = key_state[K_DOWN] - key_state[K_UP]
        player.move(horiz_direction, vert_direction)

        score_delta = 0

        for shot in shots:
            enemies_hit_list = pg.sprite.spritecollide(shot, enemies, True)
            if len(enemies_hit_list) > 0:
                if crow_sound_timer <= 0:
                    crow_sound.play()
                    crow_sound_timer = Enemy.CROW_SOUND_COOLDOWN
                shot.kill()
                score_delta += len(enemies_hit_list)
        crow_sound_timer -= 1

        if score_delta > 0:
            score.set_score_delta(score_delta)

        d = pg.sprite.spritecollide(player, enemies, True)
        if len(d) > 0:
            player.kill()
            text_score = my_font.render('Score: ' + str(score.score), False,
                                        (0, 0, 0))
            game_over = True

        if key_state[K_x]:
            if gun_timer != 0:
                gun_timer = gun_timer - 1
            else:
                Player_shot(player.get_guns()[0])
                Player_shot(player.get_guns()[1])
                shot_sound.play()
                gun_timer = Player_shot.GUN_RELOAD

        if enemy_spawn_timer != 0:
            enemy_spawn_timer = enemy_spawn_timer - 1
        else:
            Enemy()
            enemy_spawn_timer = Enemy.SPAWN_COOLDOWN

        all.clear(screen, background)
        all.update()
        pg.display.update(all.draw(screen))
        clock.tick(60)
    while game_over:
        if check_quit_keys():
            break

        key_state = pg.key.get_pressed()
        if key_state[K_s]:
            main()
            break
        screen.blit(background, (0, 0))
        screen.blit(text_over, (100, 0))
        screen.blit(text_score, (125, 100))
        screen.blit(instruction, (50, 600))
        pg.display.update()
        clock.tick(60)
    pg.quit()
예제 #2
0
class Level(State):
    event_block_limit = 180
    bonus_num = 100000
    show_label_time = 300
    amount_of_levels = 1

    def __init__(self, level_num: int):
        super().__init__()
        self.players = pygame.sprite.Group()
        self.player_1: Player = pygame.sprite.Sprite()
        self.player_2: Player = pygame.sprite.Sprite()

        self.enemies = pygame.sprite.Group()
        self.enemy_hitboxes = pygame.sprite.Group()
        self.enemy_bullets = pygame.sprite.Group()
        self.boss: Enemy = pygame.sprite.Sprite()

        self.special_effects = pygame.sprite.Group()
        self.items = pygame.sprite.Group()

        self.controls: Dict[str, int] = {}
        self.event_block: bool = True  # No moving at the start

        self.level_num: int = level_num
        self.background: Background = Background(self.level_num)

        self.enemy_spawn_dict: dict = MAPS[f"map{level_num}"]

        # This is used if the player wants to join midway through the game, or if they die.
        self.player_1_choose: bool = False
        self.player_1_choose_time: int = 60 * 20  # 20 seconds to choose
        self.player_2_choose: bool = False
        self.player_2_choose_time: int = 60 * 20
        self.choice = {'1p': 0, '2p': 0}

        self.show_continue = False
        self.continue_time = 10 * 60  # 10 seconds to continue

        self.stage_clear = False
        self.show_label_timer = 0

        self.stage_transition = StageTransition(level_num)
        self.hud = Hud(self)

    def startup(self, persist: dict):
        self.frame = 0

        self.players.empty()
        self.enemies.empty()
        self.enemy_hitboxes.empty()
        self.enemy_bullets.empty()
        self.special_effects.empty()
        self.items.empty()

        self.boss = pygame.sprite.Sprite()

        self.done = False
        self.show_continue = False
        self.continue_time = 10 * 60
        self.stage_transition = StageTransition(self.level_num)
        self.event_block = True
        self.stage_clear = True
        self.show_label_timer = 0

        self.persist = persist
        self.controls = self.persist['controls']  # Guarantee will load
        self.coins = self.persist[
            'coins']  # no need to do try except because player had to insert coins to start
        # Player 1
        if 'player_1' in self.persist:
            self.player_1 = self.persist['player_1']
            if self.player_1.alive():  # If it's not just a base sprite
                # Reset position, hitbox and rect positions will be updated on next frame.
                self.player_1.pos = PVector(150, 700)
                self.player_1.game = self  # Make sure it's spawning bullets, etc in the right game.
                self.players.add(self.player_1)
        # If the player just instantiated a character from select screen
        elif 'choice' in self.persist and self.persist['choice']['1p']:
            self.player_1 = Player(self, self.persist['choice']['1p'],
                                   PVector(150, 700))
        else:  # Just create a raw sprite for .alive() checking
            self.player_1 = pygame.sprite.Sprite()

        # Player 2
        if 'player_2' in self.persist:
            self.player_2 = self.persist['player_2']
            if self.player_2.alive():  # If it's not just a base sprite
                # Reset position, hitbox and rect positions will be updated on next frame.
                self.player_2.pos = PVector(150, 700)
                self.player_2.game = self  # Make sure it's spawning bullets, etc in the right game.
                self.players.add(self.player_2)
        # If the player just instantiated a character from select screen
        elif 'choice' in self.persist and self.persist['choice']['2p']:
            self.player_2 = Player(self, self.persist['choice']['2p'],
                                   PVector(450, 700))
        else:  # Just create a raw sprite for .alive() checking
            self.player_2 = pygame.sprite.Sprite()

        self.set_music()

    def cleanup(self):
        persist = {
            'controls': self.controls,
            'coins': self.coins,
            'player_1': self.player_1,
            'player_2': self.player_2
        }
        return persist

    def update(self):
        if self.frame == self.event_block_limit:
            self.event_block = False
        self.stage_transition.update()
        self.check_continue()

        if not self.show_continue:
            # Game frames should only continue when the players are playing,
            # otherwise, enemies will all spawn, and boss will spawn as well.
            # One problem that could occur is that boss spawns when player is selecting ship, however. To remedy this,
            # To remedy this, only advance frames if there is at least one player playing.
            # This can be checked with self.players.
            if self.stage_clear:
                self.stage_clear_effect()
            if self.players:
                self.frame += 1
            self.player_choose_update()
            self.background.update()
            self.spawn_enemies(
            )  # Spawn enemies will not spawn duplicates when frame is frozen since key is deleted.
            self.players.update()
            self.enemies.update()
            self.items.update()
            self.special_effects.update()
            self.enemy_bullets.update()
            self.collision_check()
        else:
            pass
        self.hud.update()  # Always update hud to show remaining time.

    def draw(self, surface: pygame.Surface):
        self.background.draw(surface)
        # This calls the draw function instead of just blitting image at rect position.
        [player.draw(surface) for player in self.players]
        self.enemies.draw(surface)
        self.enemy_bullets.draw(surface)
        self.special_effects.draw(surface)
        self.items.draw(surface)
        self.hud.draw(surface)
        self.stage_transition.draw(surface)

    def set_music(self):
        if self.level_num == 1:
            pygame.mixer.music.load(MUSIC['01_-_speedway_0'])
        elif self.level_num == 2:
            pygame.mixer.music.load(MUSIC['02_-_chip_beach_0'])
        elif self.level_num == 3:
            pygame.mixer.music.load(MUSIC['03_-_press_any_key_to_continue_0'])
        elif self.level_num == 4:
            pygame.mixer.music.load(MUSIC['04_-_i_want_more_candy_0'])
        elif self.level_num == 5:
            pygame.mixer.music.load(MUSIC['05_-_rain_island_0'])
        # pygame.mixer.music.play(-1)

    def spawn_enemies(self):
        if self.frame % 60 == 1:
            # enemy_dict[f'{randint(1,5)}'](self, PVector(randint(0, 600), 0))
            # enemy_dict[f'{7}'](self, PVector(randint(0, 600), 1000))
            pass
        enemies = self.enemy_spawn_dict.get(str(self.frame))
        if enemies:
            for enemy in enemies:
                new_enemy = enemy_dict[enemy](self,
                                              PVector.from_tuple(
                                                  enemies[enemy]))
                if 'Boss' in new_enemy.__class__.__name__:
                    self.boss = new_enemy

            self.enemy_spawn_dict.pop(str(self.frame))

            # This makes sure that the same enemy doesn't get spawned over and over again if the frame is frozen there.

    def collision_check(self):
        self.bullet_hit_enemy_check()
        self.player_hit_item_check()
        self.enemy_hit_player_check()  #TODO TO REMOVE GODMODE

    def bullet_hit_enemy_check(self):
        for player in self.players:
            collide_dict = pygame.sprite.groupcollide(player.bullets,
                                                      self.enemy_hitboxes,
                                                      True, False)
            for bullet, enemies in collide_dict.items():
                player.get_bullet_score()
                BulletExplosion(self, player.weapon_level, bullet.pos)
                for enemy in enemies:
                    enemy.body.take_damage(bullet)
                # Remove laser if it is past impact point
                if isinstance(bullet, PlayerLaserBullet):
                    # This is because homing bullets can take longer to hit something,
                    # and when they do, may cut off laser.
                    if player.weapon_2:
                        for b in player.bullets:
                            if b.pos.y < bullet.pos.y:
                                b.kill()
        # if self.player_1.alive():
        #     collide_dict = pygame.sprite.groupcollide(self.player_1.bullets, self.enemy_hitboxes, True, False)
        #     for bullet, enemies in collide_dict.items():
        #         self.player_1.get_bullet_score()
        #         BulletExplosion(self, self.player_1.weapon_level, bullet.pos)
        #         for enemy in enemies:
        #             enemy.body.take_damage(bullet)
        #         # Remove laser if it is past impact point
        #         if self.player_1.weapon_2:
        #             for b in self.player_1.bullets:
        #                 if b.pos.y < bullet.pos.y:
        #                     b.kill()
        # if self.player_2.alive():
        #     collide_dict = pygame.sprite.groupcollide(self.player_2.bullets, self.enemy_hitboxes, True, False)
        #     for bullet, enemies in collide_dict.items():
        #         self.player_2.get_bullet_score()
        #         BulletExplosion(self, self.player_2.weapon_level, bullet.pos)
        #         for enemy in enemies:
        #             enemy.body.take_damage(bullet)
        #         # Remove laser if it is past impact point
        #         if self.player_2.weapon_2:
        #             for b in self.player_2.bullets:
        #                 if b.pos.y < bullet.pos.y:
        #                     b.kill()

    def player_hit_item_check(self):
        for player in self.players:
            if player.explosion:
                continue
            collide_dict = pygame.sprite.spritecollide(player, self.items,
                                                       True)
            for item in collide_dict:
                item.apply_effect(player)

    def enemy_hit_player_check(self):
        for player in self.players:
            if pygame.sprite.spritecollideany(
                    player.hitbox,
                    self.enemy_hitboxes) or pygame.sprite.spritecollideany(
                        player.hitbox,
                        self.enemy_bullets,
                        collided=pygame.sprite.collide_circle):
                if not player.invincible:
                    player.explosion = True

    def player_choose_update(self):
        if self.player_1_choose:
            self.player_1_choose_time -= 1
            if self.player_1_choose_time <= 0:
                self.player_1 = Player(self, self.choice['1p'],
                                       PVector(150, 700))
                self.player_1_choose = False
                self.player_1_choose_time = 20  # Redundant since keyboard input also resets choose time

        if self.player_2_choose:
            self.player_2_choose_time -= 1
            if self.player_2_choose_time <= 0:
                self.player_2 = Player(self, self.choice['2p'],
                                       PVector(450, 700))
                self.player_2_choose = False
                self.player_2_choose_time = 20  # Redundant since keyboard input also resets choose time

    def check_continue(self):
        if not self.players and self.player_1_choose == self.player_2_choose == False:
            # If everyone's dead and no one is spawning
            self.show_continue = True
            self.continue_time -= 1
            if self.continue_time <= 0:
                self.done = True
                self.next = 'GAME OVER'
        else:
            self.show_continue = False
            self.continue_time = 10 * 60

    def stage_clear_effect(self):
        if self.player_1_choose:
            self.player_1 = Player(self, self.choice['1p'], PVector(150, 700))
            self.player_1_choose = False
            self.player_1_choose_time = 20 * 60

        if self.player_2_choose:
            self.player_2 = Player(self, self.choice['2p'], PVector(450, 700))
            self.player_2_choose = False
            self.player_2_choose_time = 20 * 60
        pygame.mixer.music.fadeout(500)
        if self.player_1.alive():
            self.player_1.pos = PVector(150, 700)
            self.player_1.rect.center = tuple(self.player_1.pos)
            self.player_1.hitbox.rect.center = tuple(self.player_1.pos)
            self.player_1.direction = PVector(0, 0)
            self.player_1.bullets.empty()
            bonus = self.bonus_num * (self.player_1.lives +
                                      self.player_1.bomb_num)
            self.player_1.score += int(bonus / self.show_label_time)

        if self.player_2.alive():
            self.player_2.pos = PVector(450, 700)
            self.player_2.rect.center = tuple(self.player_2.pos)
            self.player_2.hitbox.rect.center = tuple(self.player_2.pos)
            self.player_2.direction = PVector(0, 0)
            self.player_2.bullets.empty()
            bonus = self.bonus_num * (self.player_2.lives +
                                      self.player_2.bomb_num)
            self.player_2.score += int(bonus / self.show_label_time)

        self.show_label_timer += 1
        self.event_block = True
        if self.show_label_timer >= self.show_label_time + 1:
            self.done = True
            self.next = f'LEVEL{self.level_num+1}' if self.level_num < self.amount_of_levels else 'GAME OVER'

    def event_process(self, events: List[pygame.event.Event]):
        if self.event_block:
            return  # Don't take input if we are in stage transition territory
        keys = pygame.key.get_pressed()

        for event in events:
            if event.type == pygame.KEYDOWN:
                if event.key in {
                        self.controls['1p_coin'], self.controls['2p_coin']
                }:
                    SFX['coin'].play()
                    self.coins += 1

                if event.key == self.controls['1p_start']:
                    if not self.player_1.alive(
                    ) and not self.player_1_choose and self.coins > 0:
                        self.coins -= 1
                        self.player_1_choose = True
                        self.choice['1p'] = 1

                if event.key == self.controls['2p_start']:
                    if not self.player_2.alive(
                    ) and not self.player_2_choose and self.coins > 0:
                        self.coins -= 1
                        self.player_2_choose = True
                        self.choice['2p'] = 2

                if event.key in [
                        self.controls[x]
                        for x in ['1p_up', '1p_down', '1p_left', '1p_right']
                ]:
                    if self.player_1_choose:
                        self.choice['1p'] = (self.choice['1p'] + 2
                                             ) % 4  # Alternate between 1 and 3

                if event.key in [
                        self.controls[x]
                        for x in ['2p_up', '2p_down', '2p_left', '2p_right']
                ]:
                    if self.player_1_choose:
                        self.choice['2p'] = self.choice[
                            '2p'] % 4 + 2  # Alternate between 2 and 4

                if event.key == self.controls['1p_button_a']:
                    if self.player_1.alive():  # Player 1 is actually playing
                        self.player_1.weapon_time = pygame.time.get_ticks(
                        )  # Counter for when to switch to strong
                        # weapon
                    if self.player_1_choose:
                        self.player_1 = Player(self, self.choice['1p'],
                                               PVector(150, 700))
                        self.player_1_choose = False
                        self.player_1_choose_time = 60 * 20

                if event.key == self.controls['1p_button_b']:
                    if self.player_1.alive():
                        self.player_1.activate_bomb()
                    if self.player_1_choose:
                        self.player_1 = Player(self, self.choice['1p'],
                                               PVector(150, 700))
                        self.player_1_choose = False
                        self.player_1_choose_time = 60 * 20

                if event.key == self.controls['2p_button_a']:
                    if self.player_2.alive():  # Player 1 is actually playing
                        self.player_2.weapon_time = pygame.time.get_ticks(
                        )  # Counter for when to switch to strong
                        # weapon
                    if self.player_2_choose:
                        self.player_2 = Player(self, self.choice['2p'],
                                               PVector(450, 700))
                        self.player_2_choose = False
                        self.player_2_choose_time = 60 * 20

                if event.key == self.controls['2p_button_b']:
                    if self.player_2.alive():
                        self.player_2.activate_bomb()
                    if self.player_2_choose:
                        self.player_2 = Player(self, self.choice['2p'],
                                               PVector(450, 700))
                        self.player_2_choose = False
                        self.player_2_choose_time = 60 * 20

            elif event.type == pygame.KEYUP:
                if event.key == self.controls['1p_button_a']:
                    if self.player_1.alive():
                        self.player_1.weapon_1 = False
                        self.player_1.weapon_2 = False

                if event.key == self.controls['2p_button_a']:
                    if self.player_2.alive():
                        self.player_2.weapon_1 = False
                        self.player_2.weapon_2 = False

        if self.player_1.alive():
            if keys[self.controls['1p_up']] and keys[self.controls['1p_down']]:
                self.player_1.direction.y = 0
            elif keys[self.controls['1p_up']]:
                self.player_1.direction.y = -1
            elif keys[self.controls['1p_down']]:
                self.player_1.direction.y = 1
            else:
                self.player_1.direction.y = 0

            if keys[self.controls['1p_left']] and keys[
                    self.controls['1p_right']]:
                self.player_1.direction.x = 0
            elif keys[self.controls['1p_left']]:
                self.player_1.direction.x = -1
            elif keys[self.controls['1p_right']]:
                self.player_1.direction.x = 1
            else:
                self.player_1.direction.x = 0

            if keys[self.controls['1p_button_a']]:
                if pygame.time.get_ticks(
                ) - self.player_1.weapon_charge_up_time > self.player_1.weapon_time:
                    self.player_1.weapon_2 = True
                    self.player_1.weapon_1 = False
                else:
                    self.player_1.weapon_1 = True

        if self.player_2.alive():
            if keys[self.controls['2p_up']] and keys[self.controls['2p_down']]:
                self.player_2.direction.y = 0
            elif keys[self.controls['2p_up']]:
                self.player_2.direction.y = -1
            elif keys[self.controls['2p_down']]:
                self.player_2.direction.y = 1
            else:
                self.player_2.direction.y = 0

            if keys[self.controls['2p_left']] and keys[
                    self.controls['2p_right']]:
                self.player_2.direction.x = 0
            elif keys[self.controls['2p_left']]:
                self.player_2.direction.x = -1
            elif keys[self.controls['2p_right']]:
                self.player_2.direction.x = 1
            else:
                self.player_2.direction.x = 0

            if keys[self.controls['2p_button_a']]:
                if pygame.time.get_ticks(
                ) - self.player_2.weapon_charge_up_time > self.player_2.weapon_time:
                    self.player_2.weapon_2 = True
                    self.player_2.weapon_1 = False
                else:
                    self.player_2.weapon_1 = True
예제 #3
0
class Game:
    def __init__(self, gui=True):
        self.surface = None
        self.gui = gui
        self.file = None
        self.screen = curses.initscr()
        curses.curs_set(0)

        if gui:
            pygame.init()
            self.surface = pygame.display.set_mode((640, 480))
            self.red_image = pygame.image.load(
                os.path.join(cfg.GFX_DIR, 'player-red.png')).convert_alpha()
            self.blue_image = pygame.image.load(
                os.path.join(cfg.GFX_DIR, 'player-blue.png')).convert_alpha()
            self.bullet_image = pygame.image.load(
                os.path.join(cfg.GFX_DIR, 'bullet.png')).convert_alpha()
            self.player = Player(self.blue_image, x=640, y=480)
            self.bot = Player(self.red_image, angle=180)
            self.bullets = pygame.sprite.RenderPlain()
            self.sprites = pygame.sprite.RenderPlain(self.player, self.bot)
            self.game_time = 0

    def run(self):
        tick = time.clock()
        running = True

        while running:
            if self.gui:
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        running = False

                    self.handle_arrow_keys(event, self.player)
                    self.handle_wsad_keys(event, self.bot)

                if time.clock() - tick > 1 / 60:
                    tick = time.clock()
                    self.game_time += 1
                    self.on_render()
                    if self.game_time % 5 == 0:
                        self.raport()
                    self.save_game_state('game.sav')

                if not self.player.alive() or not self.bot.alive():
                    self.raport()
                    running = False

        self.file.close()
        pygame.quit()

    def handle_wsad_keys(self, event, player):
        input_state = player.input_state

        if event.type == pygame.KEYDOWN:

            if event.key == pygame.K_w:
                input_state.up = True

            elif event.key == pygame.K_s:
                input_state.down = True

            elif event.key == pygame.K_a:
                input_state.left = True

            elif event.key == pygame.K_d:
                input_state.right = True

            elif event.key == pygame.K_e:
                bullet = Bullet(
                    self.bullet_image,
                    x=player.rect.x + 22,  # wyśrodkowanie w poziomie
                    y=player.rect.y + (-20 if player.angle == 0 else
                                       60),  # podniesienie ponad gracza
                    going_up=player.angle == 0,
                    damage=cfg.BULLET_DAMAGE)
                self.bullets.add(bullet)

        if event.type == pygame.KEYUP:

            if event.key == pygame.K_w:
                input_state.up = False

            elif event.key == pygame.K_s:
                input_state.down = False

            elif event.key == pygame.K_a:
                input_state.left = False

            elif event.key == pygame.K_d:
                input_state.right = False

    def handle_arrow_keys(self, event, player):
        input_state = player.input_state

        if event.type == pygame.KEYDOWN:

            if event.key == pygame.K_UP:
                input_state.up = True

            elif event.key == pygame.K_DOWN:
                input_state.down = True

            elif event.key == pygame.K_LEFT:
                input_state.left = True

            elif event.key == pygame.K_RIGHT:
                input_state.right = True

            elif event.key == pygame.K_SPACE:
                # input_state.shoot = True
                bullet = Bullet(
                    self.bullet_image,
                    x=player.rect.x + 22,  # wyśrodkowanie w poziomie
                    y=player.rect.y + (-20 if player.angle == 0 else
                                       60),  # podniesienie ponad gracza
                    going_up=player.angle == 0,
                    damage=cfg.BULLET_DAMAGE)
                self.bullets.add(bullet)

        if event.type == pygame.KEYUP:

            if event.key == pygame.K_UP:
                input_state.up = False

            elif event.key == pygame.K_DOWN:
                input_state.down = False

            elif event.key == pygame.K_LEFT:
                input_state.left = False

            elif event.key == pygame.K_RIGHT:
                input_state.right = False

            # elif event.key == pygame.K_SPACE:
            # input_state.shoot = False

    def on_render(self):
        self.surface.fill((253, 246, 227))

        self.sprites.update()
        self.bullets.update(self.player, self.bot)

        self.sprites.draw(self.surface)
        self.bullets.draw(self.surface)

        pygame.display.flip()

    def get_game_state(self):
        state = [
            self.player.rect.x,
            self.player.rect.y,
            self.player.health,
            self.bot.rect.x,
            self.bot.rect.y,
            self.bot.health,
            len(self.bullets),
        ]

        bullets_going_up = []
        bullets_going_down = []

        for bullet in iter(self.bullets):
            if bullet.going_up:
                bullets_going_up.append(bullet)

            if not bullet.going_up:
                bullets_going_down.append(bullet)

        sorted(bullets_going_up)
        sorted(bullets_going_down)

        for bullet in bullets_going_up:
            state.append(bullet.rect.x)
            state.append(bullet.rect.y)

        for bullet in bullets_going_down:
            state.append(bullet.rect.x)
            state.append(bullet.rect.y)

        return state

    def save_game_state(self, filename):
        if not self.file:
            self.file = open(filename, 'w+')

        state = self.get_game_state()

        for item in state:
            self.file.write('%s ' % str(item))

        self.file.write('\n')

    def count_fitness(self, player, opponent):
        return cfg.DMG_TAKEN_MULTIPLIER * (100-player.health) + \
               cfg.GAME_TIME_MULTIPLIER * self.game_time + \
               cfg.DMG_GIVEN_MULTIPLIER * (100-opponent.health)

    def raport(self):
        self.screen.clear()
        self.screen.addstr(0, 0, 'Game time: ' + str(self.game_time))

        self.screen.addstr(
            2, 0, 'Red health: ' + str(self.bot.health) +
            (' (alive)' if self.bot.alive() else ' (dead)'))
        self.screen.addstr(
            3, 0, 'Blue health: ' + str(self.player.health) +
            (' (alive)' if self.player.alive() else ' (dead)'))

        self.screen.addstr(
            2, 25,
            'fitness: ' + str(self.count_fitness(self.bot, self.player)))
        self.screen.addstr(
            3, 25,
            'fitness: ' + str(self.count_fitness(self.player, self.bot)))

        self.screen.addstr(5, 0, 'Bullet damage: ' + str(cfg.BULLET_DAMAGE))
        self.screen.addstr(5, 20, 'DMG taken multiplier: ' + str(-5))
        self.screen.addstr(5, 50, 'DMG given multiplier: ' + str(10))
        self.screen.addstr(5, 80, 'Game time multiplier: ' + str(2))
        self.screen.addstr(6, 0,
                           'Bullets on screen: ' + str(len(self.bullets)))

        self.screen.refresh()