コード例 #1
0
class GameStateManager():
    def __init__(self):
        pygame.init()
        pygame.display.set_mode([WIDTH, HEIGHT])
        pygame.display.set_caption("Pygame Tilebased RPG")
        pygame.key.set_repeat(100)
        self.SURFACE = pygame.display.get_surface()
        self.current_state = HUMS_STATE
        self.input_handler = InputHandler()
        self.camera = Camera(32, 24)
        self.states = self.create_states()
        self.player = Player(self, 18, 18, 100, 5, 5)
        self.walls = self.states[self.current_state].walls
        self.doors = self.states[self.current_state].doors
        self.npcs = self.states[self.current_state].npcs

    def update(self):
        self.draw_grid()
        self.draw_map()
        self.player.update()
        #self.player.draw(self.camera.apply(self.player))
        self.player.draw()
        self.camera.update(self.player)

    def change_state(self, state):
        self.current_state = state
        self.walls = self.states[self.current_state].walls
        self.doors = self.states[self.current_state].doors
        self.npcs = self.states[self.current_state].npcs

    def create_states(self):
        states = [None] * NUM_STATES
        states[HUMS_STATE] = HumsState(self)
        states[HUMS_INN_STATE] = HumsInnState(self)
        return states

    def draw_grid(self):
        for x in range(0, WIDTH, TILESIZE):
            pygame.draw.line(pygame.display.get_surface(), BLACK, (x, 0),
                             (x, HEIGHT))

        for y in range(0, HEIGHT, TILESIZE):
            pygame.draw.line(pygame.display.get_surface(), BLACK, (0, y),
                             (WIDTH, y))

    def draw_map(self):
        for x in range(len(self.walls)):
            self.walls[x].update()
            self.walls[x].draw(RED)
        for x in range(len(self.doors)):
            self.doors[x].update()
            self.doors[x].draw(BLUE)
        for x in range(len(self.npcs)):
            self.npcs[x].update()
            self.npcs[x].draw()

    def clear_screen(self):
        pygame.display.get_surface().fill((255, 255, 255))
コード例 #2
0
ファイル: game.py プロジェクト: FourLineCode/space-shooter
class Game:
    def __init__(self, window, first=True):
        self.window = window
        self.window_width, self.window_height = window.get_size()
        self.running = True
        self.willTabQuit = True
        self.score = 0
        self.bg = pygame.image.load(str(Path('./assets/bg.jpg')))
        self.font = pygame.font.SysFont('Hack', 14, True)
        self.midFont = pygame.font.SysFont('Hack', 24, True)
        self.bigFont = pygame.font.SysFont('Hack', 80, True)
        self.player = Player(self.window)
        self.bullet = Bullet(self.window, self.player)
        self.enemy = Enemy(self.window)
        self.display = True
        self.count = 0
        self.state = 'menu' if first else 'start'

    # Main Game State
    def run(self):
        if self.state == 'menu':
            self.menu()
        elif self.state == 'start':
            self.start()
        elif self.state == 'over':
            self.game_over()

    # Starts game
    def start(self):
        for event in pygame.event.get():
            if event.type is pygame.QUIT:
                self.running = False
            if event.type is pygame.KEYDOWN:
                if event.key is pygame.K_TAB and self.willTabQuit:
                    self.running = False
                if event.key is pygame.K_a:
                    self.player.toggleMoving(True)
                    self.player.moveLeft()
                if event.key is pygame.K_d:
                    self.player.toggleMoving(True)
                    self.player.moveRight()
                if event.key is pygame.K_w:
                    self.player.toggleMoving(True)
                    self.player.moveUp()
                if event.key is pygame.K_s:
                    self.player.toggleMoving(True)
                    self.player.moveDown()
                if event.key is pygame.K_SPACE:
                    if self.bullet.bullet_state == 'ready':
                        self.bullet.setShootingPos(self.player.playerX)
                        self.bullet.bullet_state = 'shoot'
            if event.type is pygame.KEYUP:
                self.player.toggleMoving(False)
        # Draw Entities
        self.draw_window()

    # Draws All Entities On Window
    def draw_window(self):
        # Moves Player When Key Pressed
        if self.player.moving:
            self.player.move()

        # Draws Bullet On State
        self.bullet.draw()

        # Draws Enemy
        self.enemy.move()
        self.enemy.draw()

        # Checks Bullet-Enemy Collide
        if self.bullet.checkCollide(self.enemy):
            self.enemy.randomizePosition()
            self.score += 1

        # Game Over State
        if self.enemy.isGameOver():
            self.state = 'over'

        # Draws Player
        self.player.draw()

        # Update Player Position
        self.window.blit(self.update_pos(), (self.window_width - 140, 0))

        # Draw Score
        self.window.blit(self.update_score(), (5, 20))

    # Start Menu
    def menu(self):
        for event in pygame.event.get():
            if event.type is pygame.QUIT:
                self.running = False
            if event.type is pygame.KEYDOWN:
                if event.key is pygame.K_TAB and self.willTabQuit:
                    self.running = False
                if event.key is pygame.K_SPACE:
                    self.__init__(self.window, False)
                    self.state = 'start'

        # Game Title text
        title = 'Space Shooter'
        title_text = self.bigFont.render(title, 1, pygame.Color('white'))
        title_width, title_height = title_text.get_size()
        title_x, title_y = self.window_width / 2 - title_width / \
            2, self.window_height/2 - title_height/2

        # Start Prompt Text
        start = 'Press Space To Start'
        start_text = self.midFont.render(start, 1, pygame.Color('white'))
        start_width, start_height = start_text.get_size()
        start_x, start_y = self.window_width / 2 - start_width / \
            2, self.window_height/2 - start_height/2 + (title_height/2) + 10

        self.window.blit(title_text, (title_x, title_y))

        # Blinking text
        self.count += 1
        if self.count > 30:
            self.count = 0
            self.display = not self.display
        if self.display:
            self.window.blit(start_text, (start_x, start_y))

    # Game Over Menu
    def game_over(self):
        for event in pygame.event.get():
            if event.type is pygame.QUIT:
                self.running = False
            if event.type is pygame.KEYDOWN:
                if event.key is pygame.K_TAB and self.willTabQuit:
                    self.running = False
                if event.key is pygame.K_SPACE:
                    self.__init__(self.window, False)
                    self.state = 'start'

        # Game Over Text
        over = 'GAME OVER'
        game_over_text = self.bigFont.render(over, 1, pygame.Color('white'))
        over_width, over_height = game_over_text.get_size()
        over_x, over_y = self.window_width / 2 - over_width / \
            2, self.window_height/2 - over_height/2

        # Continue Prompt Text
        con = 'Press Space To Continue'
        continue_text = self.midFont.render(con, 1, pygame.Color('white'))
        con_width, con_height = continue_text.get_size()
        con_x, con_y = self.window_width / 2 - con_width / \
            2, self.window_height/2 - con_height/2 + (over_height/2) + 10

        # Score Text
        score = f'Score: {self.score}'
        score_text = self.midFont.render(score, 1, pygame.Color('white'))
        score_width, score_height = score_text.get_size()
        score_x, score_y = self.window_width / 2 - score_width / \
            2, self.window_height/2 - score_height/2 - (over_height/2) - 10

        self.window.blit(game_over_text, (over_x, over_y))
        self.window.blit(score_text, (score_x, score_y))
        # Blinking Text
        self.count += 1
        if self.count > 30:
            self.count = 0
            self.display = not self.display
        if self.display:
            self.window.blit(continue_text, (con_x, con_y))

    def update_pos(self):
        pos = f'X: {self.player.playerX} Y: {self.player.playerY}'
        pos_text = self.font.render(pos, 1, pygame.Color("white"))
        return pos_text

    def update_score(self):
        score = f'Score: {self.score}'
        score_text = self.font.render(score, 1, pygame.Color("white"))
        return score_text
コード例 #3
0
ファイル: world.py プロジェクト: chris90483/2021GameJam
class World(object):
    def __init__(self, amount_tiles_x, amount_tiles_y, audio_manager, score):
        self.audio_manager = audio_manager
        self.score = score
        self.amount_tiles_x = amount_tiles_x
        self.amount_tiles_y = amount_tiles_y
        self.grid = Grid(self.amount_tiles_x, self.amount_tiles_y, self)
        self.player = Player(self, audio_manager)
        self.zombie_handler = ZombieHandler(self)
        self.dog_handler = DogHandler(self)
        self.emitter_handler = EmitterHandler(self.zombie_handler)
        self.destination = Destination(self)
        self.destination_flag = DestinationFlag(self)
        self.compass = Compass(self)
        self.delivery_status = DeliveryStatus(self)
        self.inventory = Inventory(self)
        self.health_bar = HealthBar(self.player)

        self.pizza = None
        self.populated_tiles = [[False for _ in range(Constant.GRID_HEIGHT)]
                                for _ in range(Constant.GRID_WIDTH)]
        self._update_spawn_regions(
            convert_world_to_grid_position(self.player.x, self.player.y))

    def handle_input(self, event):
        self.player.handle_input(event)

    def step(self):
        self.emitter_handler.step()
        player_grid_location_before = convert_world_to_grid_position(
            self.player.x, self.player.y)
        self.player.step()
        player_grid_location_after = convert_world_to_grid_position(
            self.player.x, self.player.y)
        if player_grid_location_after != player_grid_location_before:
            self._update_spawn_regions(player_grid_location_after)
        self.destination.step()
        self.zombie_handler.step()
        self.dog_handler.step()

        if self.pizza:
            self.pizza.step()

    def draw(self, screen: Surface, camera: Camera):
        # Grid
        self.grid.draw(screen, camera)
        self.destination_flag.draw(screen, camera)

        # Sound circle
        self.emitter_handler.draw(screen, camera)

        if self.pizza:
            self.pizza.draw(screen, camera)

        # Moving entites
        self.dog_handler.draw(screen, camera)
        self.player.draw(screen, camera)
        self.zombie_handler.draw(screen, camera)

        # UI
        self.compass.draw(screen, camera)
        self.delivery_status.draw(screen)
        self.inventory.draw(screen, camera)
        self.health_bar.draw(screen)

    def _update_spawn_regions(self, pos):
        x, y = pos
        new_grid = [[False for _ in range(Constant.GRID_HEIGHT)]
                    for _ in range(Constant.GRID_WIDTH)]
        new_regions = set()
        for dx in range(-Constant.GRID_SPAWN_RANGE,
                        Constant.GRID_SPAWN_RANGE + 1):
            for dy in range(-Constant.GRID_SPAWN_RANGE,
                            Constant.GRID_SPAWN_RANGE + 1):
                if self.grid.is_in_grid(x + dx, y + dy):
                    new_grid[x + dx][y + dy] = True
                    if not self.populated_tiles[x + dx][y + dy]:
                        new_regions.add((x + dx, y + dy))

        for region in new_regions:
            self._spawn_in_tile(region)

        del self.populated_tiles
        self.populated_tiles = new_grid

    def _spawn_in_tile(self, region):
        dist_to_center = distance(
            region, (Constant.GRID_WIDTH // 2, Constant.GRID_HEIGHT // 2))
        world_x, world_y = region[0] * Constant.TILE_SIZE, region[
            1] * Constant.TILE_SIZE

        if self.grid.grid[region[0]][region[1]].type in {
                CellType.NATURE, CellType.ROAD
        } and dist_to_center > 4:
            zombies = 0
            if int(Constant.AVG_ZOMBIES_PER_TILE_DISTANCE_FROM_CENTER *
                   dist_to_center) > 0:
                zombies = random.randint(
                    0,
                    int(Constant.AVG_ZOMBIES_PER_TILE_DISTANCE_FROM_CENTER *
                        dist_to_center))
            blue_zombie = Constant.BLUE_ZOMBIE_PROB_INCREASE_PER_TILE_DISTANCE_FROM_CENTER * dist_to_center > random.random(
            )
            dog = Constant.DOG_PROB_INCREASE_PER_TILE_DISTANCE_FROM_CENTER * dist_to_center > random.random(
            )

            for _ in range(zombies):
                x, y = int(world_x +
                           random.random() * Constant.TILE_SIZE), int(
                               world_y + random.random() * Constant.TILE_SIZE)
                self.zombie_handler.add_zombie(Zombie(x, y, self))

            if blue_zombie:
                x, y = int(world_x +
                           random.random() * Constant.TILE_SIZE), int(
                               world_y + random.random() * Constant.TILE_SIZE)
                self.zombie_handler.add_zombie(
                    Zombie(x, y, self, is_super_zombie=True))

            if dog:
                x, y = int(world_x +
                           random.random() * Constant.TILE_SIZE), int(
                               world_y + random.random() * Constant.TILE_SIZE)
                self.dog_handler.add_dog(Dog(x, y, self.player, self))
コード例 #4
0
def game():
    fps = 60
    game_loop = True

    # player
    player = Player(width, height)

    # ball
    ball = Ball(width, height)
    game_over = False

    # blocks
    blocks = []
    b_width, b_height = width // 5 - 20, height // (4 * 5) - 10
    x, y = 30, 10
    for i in range(5):
        for j in range(5):
            blocks.append(Block(height, width, b_width, b_height, x, y,
                                (random.randint(20, 255), random.randint(20, 255),
                                 random.randint(20, 255))))  # block color never black
            x += 10 + b_width
        y += 10 + b_height
        x = 30

    # score
    max_score = len(blocks)

    while game_loop:
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                return

        # check for user input
        keys = pygame.key.get_pressed()

        if keys[pygame.K_LEFT]:
            player.moveX(player.velocity * -1)
        if keys[pygame.K_RIGHT]:
            player.moveX(player.velocity)

        if not game_over:
            game_over = ball.move(player)
            ball.check_collision(blocks)
            if not game_over:
                game_over = len(blocks) == 0

        # clearing screen
        window.fill((0, 0, 0))

        if game_over:
            # Game Over text
            go_label = font.render("Game Over!", True, (255, 255, 255))
            score_label = font.render("Score: " + str(max_score - len(blocks)), True, (255, 255, 0))
            window.blit(go_label, ((width - 150) // 2, (height - 150) // 2))
            window.blit(score_label, ((width - 120) // 2, (height - 60) // 2))

            # Try Again button
            if _render_btn("Try again", ((width - btn_width) // 2, 0.75 * height), pygame.mouse.get_pos()):
                game_loop = False
                continue
        else:
            # drawing entities
            player.draw(window)
            ball.draw(window)
            for block in blocks:
                block.draw(window)

        # updates
        pygame.display.update()
        clock.tick(fps)
コード例 #5
0
def play(screen: pygame.surface.Surface,
         level_number: int = 1,
         user_seed: str = None) -> int:
    """
    Функция запуска игрового процесса
    :param screen: Экран для отрисовки
    :param level_number: Номер текущего уровня
    :param user_seed: Сид карты. Если он есть, по нему создаются уровни,
    раставляются враги и прочее
    :return: Код завершения игры (значения описаны в main.py)
    """
    # Псевдо загрузочный экран (для красоты)
    loading_screen(screen)
    # Размеры экрана
    screen_width, screen_height = screen.get_size()
    # Группа со всеми спрайтами
    all_sprites = pygame.sprite.Group()
    # Группа со спрайтами тайлов пола
    tiles_group = pygame.sprite.Group()
    # Группа со спрайтами ящиков и бочек
    # (они отдельно, т.к. это разрушаемые объекты)
    furniture_group = pygame.sprite.Group()
    # Группа со спрайтами преград (т.е. все физические объекты)
    collidable_tiles_group = pygame.sprite.Group()
    # Группа со спрайтами врагов
    enemies_group = pygame.sprite.Group()
    # Группа со спрайтами дверей
    doors_group = pygame.sprite.Group()
    # Группа со спрайтами факелов
    torches_group = pygame.sprite.Group()
    # Группа со спрайтом конца уровня (т.е. с лестницой перехода вниз)
    end_of_level = pygame.sprite.Group()
    # Группа с предметаими, которые находятся на полу
    GroundItem.sprites_group = pygame.sprite.Group()
    # Группа с сундуками
    Chest.chest_group = pygame.sprite.Group()

    is_open = True
    # Поверхность для эффекта затемнения
    transparent_grey = pygame.surface.Surface((screen_width, screen_height),
                                              pygame.SRCALPHA).convert_alpha()
    clock = pygame.time.Clock()  # Часы
    current_seed = user_seed  # текущий сид
    # Создаем уровень с помощью функции из generation_map
    level, level_seed = generate_new_level(
        current_seed.split('\n')[0].split() if current_seed else 0)
    # Игрок (None, т.к. будет переопределён либо при инициализации, либо при по)
    player = None
    if current_seed:
        data = current_seed.split('\n')  # Данные из сида
        # Получение данных об игроке из сида и создание игрока
        _, _, player_level, health, mana, money = data[3].split()[:-1]
        player = Player(0, 0, player_level, all_sprites, health, mana, money)
        # Получение данных об асистентах игрока
        for n in range(int(data[3].split()[-1])):
            # Получениев параметров асистента и его создание
            x1, y1, health, mana, *name = data[4 + n].split()
            assistant = PlayerAssistant(0, 0, player, all_sprites, health,
                                        mana, name)
            # Добавление асистента
            player.add_assistant(assistant)
    # Необходимые аргументы для инициализации уровня
    args = (level, level_number, all_sprites, tiles_group, furniture_group,
            collidable_tiles_group,
            enemies_group, doors_group, torches_group, end_of_level,
            current_seed.split('\n')[1].split() if current_seed else [],
            current_seed.split('\n')[2].split() if current_seed else [],
            player)
    # Инициализация уровня и получение данных об игроке и частях сида
    player, monsters_seed, boxes_seed = initialise_level(*args)
    if current_seed:
        # Если сид был передан, сдвигаем игрока на расстояние от начала уровня (лестницы)
        # Которое было записано в сид
        x_from_start, y_from_start = map(
            float,
            current_seed.split('\n')[3].split()[:2])
        player.rect.center = player.rect.centerx + x_from_start, player.rect.centery + y_from_start
    # Смещение всех асистентов игрока
    for assistant in player.assistants:
        assistant.rect.center = player.rect.center
    # Обновление и сохранение сида после инициализации уровня
    current_seed = '\n'.join([
        ' '.join(level_seed), ' '.join(monsters_seed), ' '.join(boxes_seed),
        str(player),
        str(level_number)
    ])
    save(current_seed)
    camera = Camera(screen.get_size())  # камера
    # Инициализация начальной позиции прицела игрока
    player.scope.init_scope_position((screen_width * 0.5, screen_height * 0.5))
    # Шрифт для вывода фпс в левом верхнем углу
    fps_font = load_game_font(48)
    # Иконка рядом с номером уровня (в правом верхнем углу)
    level_number_icon = load_tile('DOWNSTAIRS.png')
    # Иконка рядом с количеством врагов на уровне (в правом верхнем углу)
    monster_number_icon = load_image(
        'assets/sprites/UI/icons/monster_number.png', (TILE_SIZE, ) * 2)
    # Шрифт для вывода номера уровня и количества врагов
    level_and_enemies_font = load_game_font(64)
    # Сообщение, которое будет появлятся при приближении игрока к сундуку
    chest_title = Message(screen, 'Нажмите Е (или L2), чтобы открыть сундук',
                          screen.get_height() * 0.1)
    # Сообщение, которое будет появлятся при приближении игрока к спуску вниз
    downstairs_title = Message(
        screen, 'Нажмите Е (или L2), чтобы перейти на следующий уровень',
        screen.get_height() * 0.1)
    # Иконки для отображения иконок (контейнеров) с заклинаниями внизу экрана
    spells_containers = (
        SpellContainer("fire_spell.png", FireSpell, player),
        SpellContainer("ice_spell.png", IceSpell, player),
        SpellContainer("poison_spell.png", PoisonSpell, player),
        SpellContainer("void_spell.png", VoidSpell, player),
        SpellContainer("light_spell.png", FlashSpell, player),
        SpellContainer("teleport_spell.png", TeleportSpell, player),
    )
    # Панель с иконкой и информацией об игроке в левом верхнем углу
    player_icon = PlayerIcon(player)
    # Высота для высчитывания позиции отрисовки иконки асистента
    assistants_height = 180
    # Отступ для вывода иконки игрока и его ассистентов
    indent = 20
    # Фоновая музыка
    pygame.mixer.music.load("assets/audio/music/game_bg.ogg")
    pygame.mixer.music.play(-1)
    pygame.mixer.music.set_volume(DEFAULT_MUSIC_VOLUME)
    # Установка событий, обрабатываемых pygame, чтобы не тратить
    # время на обработку ненужных событий (это относится ко всей игре в целом,
    # где обрабатываются события)
    pygame.event.set_allowed((
        pygame.QUIT,
        pygame.MOUSEBUTTONUP,
        pygame.KEYDOWN,
    ))
    # Игровой цикл
    while is_open:
        was_pause_activated = False  # была ли активирована пауза
        keys = pygame.key.get_pressed()  # нажатые клавиши
        buttons = pygame.mouse.get_pressed(5)  # нажатые кнопки мыши
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                is_open = False
            if event.type == pygame.KEYDOWN:
                if event.key == CONTROLS["KEYBOARD_PAUSE"]:
                    was_pause_activated = True
        # Провверка использования заклинаний с джойстика
        if player.joystick:
            if player.joystick.get_button(CONTROLS["JOYSTICK_UI_PAUSE"]):
                was_pause_activated = True
            if player.joystick.get_button(CONTROLS["JOYSTICK_SPELL_FIRE"]):
                player.shoot('fire', enemies_group)
            if player.joystick.get_button(CONTROLS["JOYSTICK_SPELL_ICE"]):
                player.shoot('ice', enemies_group)
            if player.joystick.get_button(CONTROLS["JOYSTICK_SPELL_LIGHT"]):
                player.shoot('flash', enemies_group)
            if player.joystick.get_button(CONTROLS["JOYSTICK_SPELL_POISON"]):
                player.shoot('poison', enemies_group)
            if player.joystick.get_button(CONTROLS["JOYSTICK_SPELL_VOID"]):
                player.shoot('void', enemies_group)
            # Используется ось, т.к. назначен триггер R2
            if player.joystick.get_axis(CONTROLS["JOYSTICK_SPELL_TELEPORT"]
                                        ) > JOYSTICK_SENSITIVITY:
                player.shoot('teleport', tiles_group)
        # Иначе ввод с клавиатуры
        else:
            if keys[CONTROLS["KEYBOARD_SPELL_FIRE"]] or buttons[
                    CONTROLS["MOUSE_SPELL_FIRE"]]:
                player.shoot('fire', enemies_group)
            if keys[CONTROLS["KEYBOARD_SPELL_ICE"]] or buttons[
                    CONTROLS["MOUSE_SPELL_ICE"]]:
                player.shoot('ice', enemies_group)
            if keys[CONTROLS["KEYBOARD_SPELL_LIGHT"]] or buttons[
                    CONTROLS["MOUSE_SPELL_LIGHT"]]:
                player.shoot('flash', enemies_group)
            if keys[CONTROLS["KEYBOARD_SPELL_POISON"]] or buttons[
                    CONTROLS["MOUSE_SPELL_POISON"]]:
                player.shoot('poison', enemies_group)
            if keys[CONTROLS["KEYBOARD_SPELL_VOID"]]:
                player.shoot('void', enemies_group)
            if keys[CONTROLS["KEYBOARD_SPELL_TELEPORT"]]:
                player.shoot('teleport', tiles_group)
        # Обработка паузы
        if was_pause_activated:
            # # Остановка звуков и музыки
            pygame.mixer.pause()
            pygame.mixer.music.pause()
            # Запуск меню паузы
            code = game_menu.execute(screen)
            if code == 1:
                # Псевдо экран загрузки перед следующими действиями (для красоты)
                loading_screen(screen)
                # Очищаем все группы со спрайтами
                all_sprites.empty()
                tiles_group.empty()
                furniture_group.empty()
                collidable_tiles_group.empty()
                enemies_group.empty()
                doors_group.empty()
                torches_group.empty()
                end_of_level.empty()
                Chest.chest_group.empty()
                GroundItem.sprites_group.empty()
                Entity.damages_group.empty()
                # Сохранение данных перед выходом
                save('')
                return 2
            if code is not None:
                # Ставим экран загрузки перед следующими действиями
                loading_screen(screen)
                # Очищаем все группы со спрайтами
                all_sprites.empty()
                tiles_group.empty()
                furniture_group.empty()
                collidable_tiles_group.empty()
                enemies_group.empty()
                doors_group.empty()
                torches_group.empty()
                end_of_level.empty()
                Chest.chest_group.empty()
                GroundItem.sprites_group.empty()
                Entity.damages_group.empty()
                # Сохранение данных перед выходом
                if player.alive:
                    current_seed = '\n'.join([
                        ' '.join(level_seed), ' '.join(monsters_seed),
                        ' '.join(boxes_seed),
                        str(player),
                        str(level_number)
                    ])
                    save(current_seed)
                else:
                    save('')
                return -1
            # Возвращение звука и мызыки так, как было до паузы
            pygame.mixer.unpause()
            pygame.mixer.music.unpause()
        screen.fill(BACKGROUND_COLOR)  # Очистка экрана
        player.update()  # Обновление игрока
        # Если игрок умер, то открывается экран конца игры
        if player.destroyed:
            # Остановка звуков и музыки
            pygame.mixer.pause()
            pygame.mixer.music.pause()
            # Подсчёт количества живых асистентов у игрока (для вывода статистики)
            count_of_alive_assistants = 0
            for sprite in player.assistants.sprites():
                sprite: PlayerAssistant
                # Если асистент живой увеличиваем счётчик
                count_of_alive_assistants += int(sprite.alive)
            # Запуск экрана с концом
            end_screen.execute(screen, player.money, count_of_alive_assistants)
            return -1
        # Проверка на столкновение с любым сундуком
        if pygame.sprite.spritecollideany(player, Chest.chest_group):
            # Обновление времени столкновения с сундуком для
            # красивой отрисовки сообщения
            chest_title.last_collide_time = pygame.time.get_ticks()
            # Проверка на использование (с джойстика или клавиатуры)
            if ((player.joystick and player.joystick.get_axis(
                    CONTROLS['JOYSTICK_USE']) > JOYSTICK_SENSITIVITY)
                    or (keys[CONTROLS['KEYBOARD_USE']])):
                pygame.sprite.spritecollide(player, Chest.chest_group,
                                            False)[0].open()

        enemies_group.update(player)  # обновление врагов
        player.assistants.update(enemies_group)  # обновление асистентов
        Entity.spells_group.update()  # обновление заклинаний
        # Обновление факелов (для звука огня по расстоянию до факела)
        torches_group.update(player)
        # Обновление всех дверей
        doors_group.update(player, enemies_group,
                           [player] + list(player.assistants))
        Chest.chest_group.update()  # обновление сундуков
        Entity.damages_group.update()  # обновление текста с выводом урона
        # Проверка перехода на следующий уровень, при соприкосновении с лестницой вниз
        if pygame.sprite.spritecollideany(player.collider, end_of_level):
            # Обновление времени столкновения с лестницой вниз для
            # красивой отрисовки сообщения
            downstairs_title.last_collide_time = pygame.time.get_ticks()
            if (keys[pygame.K_e]
                    or (player.joystick and player.joystick.get_axis(
                        CONTROLS['JOYSTICK_USE']) > JOYSTICK_SENSITIVITY)):
                # Затухание музыки и звуком
                pygame.mixer.fadeout(1000)
                pygame.mixer.music.fadeout(1000)
                # Псевдо загрузочный экран для красоты
                loading_screen(screen)
                # Если игрок прошёл 10 уровней, то это победа
                if level_number == 10:
                    # Подсчёт количества живых асистентов у игрока (для вывода статистики)
                    count_of_alive_assistants = 0
                    for sprite in player.assistants.sprites():
                        sprite: PlayerAssistant
                        # Если асистент живой увеличиваем счётчик
                        count_of_alive_assistants += int(sprite.alive)
                    # Победный экран
                    end_screen.execute(screen,
                                       player.money,
                                       count_of_alive_assistants,
                                       is_win=True)
                    return -1
                # Иначе перезагружаются параметры для нового уровня
                else:
                    # Очистка всех групп со спрайтами
                    all_sprites.empty()
                    tiles_group.empty()
                    furniture_group.empty()
                    collidable_tiles_group.empty()
                    enemies_group.empty()
                    doors_group.empty()
                    torches_group.empty()
                    end_of_level.empty()
                    Chest.chest_group.empty()
                    GroundItem.sprites_group.empty()
                    Entity.damages_group.empty()
                    level_number += 1  # увеличение номер уровня
                    # Создание целиком нового уровень функцией из generation_map
                    level, level_seed = generate_new_level(0)
                    # Необходимые аргументы для инициализации уровня
                    args = (level, level_number, all_sprites, tiles_group,
                            furniture_group, collidable_tiles_group,
                            enemies_group, doors_group, torches_group,
                            end_of_level, [], [])
                    # Инициализация уровня и получение данных об игроке и частях сида
                    player, monsters_seed, boxes_seed = initialise_level(
                        *args, player=player)
                    # Добавление игрока и асистентов
                    all_sprites.add(player)
                    all_sprites.add(player.assistants)
                    # Смещение асистентов к игроку
                    for assistant in player.assistants:
                        assistant.rect.center = player.rect.center
                    # Изменение текущего сида и файла сохранения
                    current_seed = '\n'.join([
                        ' '.join(level_seed), ' '.join(monsters_seed),
                        ' '.join(boxes_seed),
                        str(player),
                        str(level_number)
                    ])
                    save(current_seed)
                    # Установка начальной позиции приуела
                    player.scope.init_scope_position(
                        (screen_width * 0.5, screen_height * 0.5))
                    # Иконки для отображения иконок (контейнеров) с заклинаниями внизу экрана
                    spells_containers = (
                        SpellContainer("fire_spell.png", FireSpell, player),
                        SpellContainer("ice_spell.png", IceSpell, player),
                        SpellContainer("poison_spell.png", PoisonSpell,
                                       player),
                        SpellContainer("void_spell.png", VoidSpell, player),
                        SpellContainer("light_spell.png", FlashSpell, player),
                        SpellContainer("teleport_spell.png", TeleportSpell,
                                       player),
                    )
                    # Включение музыки после обновления параметров
                    pygame.mixer.music.play(-1)
                    continue
        # Применение смещения камеры относительно игрока
        camera.update(player)
        for sprite in all_sprites:
            camera.apply(sprite)
        # Отрисовка спрайтов в определённом порядке,
        # чтобы они не перекрывали друг друга
        tiles_group.draw(screen)  # тайлы пола
        torches_group.draw(screen)  # факеда
        # Сундуки
        for chest in Chest.chest_group:
            chest.draw_back_image(screen)
        # предметы на земле (мясо и деньги)
        GroundItem.sprites_group.draw(screen)
        collidable_tiles_group.draw(
            screen)  # физические объекты не являющиеся стенами
        doors_group.draw(screen)  # двери
        enemies_group.draw(screen)  # враги
        player.assistants.draw(screen)  # асистенты
        # Шкалы здоровья у асистентов
        for assistant in player.assistants:
            assistant.draw_health_bar(screen)
        player.draw(screen)  # игрок
        Entity.spells_group.draw(screen)  # заклинания
        player.draw_health_bar(screen)  # шкала здоровья у игрока
        # Шкала здоровья у врагов
        for enemy in enemies_group:
            enemy.draw_health_bar(screen)
        Entity.damages_group.draw(screen)  # текст с уроном
        chest_title.draw(screen)  # сообщение по мере приближении к сундуку
        # сообщение по мере приближении к лестнице вниз
        downstairs_title.draw(screen)
        # Значения для определения того, какие иконки текст,
        # нужно отображать на иконках с заклинаниями (нужно, чтобы игроку было
        # проще привыкнуть к управлению)
        is_joystick = player.joystick is not None
        if is_joystick:
            spell_args = ("o", "x", "triangle", "square", "L1", "L2")
        else:
            spell_args = ("1", "2", "3", "4", "5", "Space")
        # Контейнеры с заклинаниями
        for i in range(len(spells_containers) - 1, -1, -1):
            pos = (screen_width * (0.375 + 0.05 * i), screen_height * 0.9)
            spells_containers[i].draw(screen, pos, is_joystick, spell_args[i])
        # Панель с игроком в левом верхнем углу
        player_icon.draw(screen, (indent, indent))
        # Иконоки у асистентов
        for number_of_assistant, assistant in enumerate(player.assistants):
            if not assistant.icon:
                assistant.icon = PlayerIcon(assistant)
            assistant.icon.draw(
                screen,
                (indent + 20, assistants_height + number_of_assistant * 80),
                0.5)
        # фпс
        fps_text = fps_font.render(str(round(clock.get_fps())), True,
                                   (100, 255, 100))
        screen.blit(fps_text, (2, 2))
        # Иконка и количество врагов на уровне
        monster_number_text = level_and_enemies_font.render(
            str(len(enemies_group)), True, (255, 255, 255))
        screen.blit(monster_number_icon, (screen_width - 70, 80))
        screen.blit(monster_number_text, (screen_width - 120, 80))
        # Иконка и номер уровня
        level_number_text = level_and_enemies_font.render(
            str(level_number), True, (255, 255, 255))
        screen.blit(level_number_icon, (screen_width - 70, 10))
        screen.blit(level_number_text, (screen_width - 120, 10))
        # Прицел игрока
        player.scope.draw(screen)

        clock.tick(FPS)
        pygame.display.flip()

    # Запись сохранения после закрытия игры
    save(current_seed)
    return 0
コード例 #6
0
ファイル: main.py プロジェクト: brunobdcorreia/Pygar.io
        else:
            poison.remove(p)

    for f in food:
        for enemy in enemies:
            if (is_colliding(enemy, f)):
                enemy.increase_size(f.get_size())
                f.deactivate()

        if (is_colliding(player, f)):
            player.increase_size(f.get_size())
            f.deactivate()

    for p in poison:
        for enemy in enemies:
            if (is_colliding(enemy, p)):
                enemy.decrease_size(p.get_size())
                p.deactivate()

        if (is_colliding(player, p)):
            player.decrease_size(p.get_size())
            p.deactivate()

    for enemy in enemies:
        enemy.update(player, enemy.get_distance_from_food(food))
        enemy.draw(screen)

    player.update()
    player.draw(screen)
    pygame.display.flip()