Beispiel #1
0
def rainbow_effect_on_water(screen: pygame.surface.Surface,
                            water_tile: pygame.surface.Surface) -> None:
    orig_screen = screen.copy()
    water_color = pygame.transform.average_color(water_tile,
                                                 water_tile.get_rect())

    # Cycle through the rainbow colors
    clock = pygame.time.Clock()
    for i in range(4):
        for rainbow_color in rainbow_colors:
            try:
                pygame.transform.threshold(screen,
                                           orig_screen,
                                           search_color=water_color,
                                           threshold=pygame.Color(50, 50, 50),
                                           set_color=rainbow_color,
                                           inverse_set=True)
                clock.tick(5)
                pygame.display.flip()
            except:
                print('Color not found: ', rainbow_color, flush=True)

    # Restore original screen
    screen.blit(orig_screen, (0, 0))
    pygame.display.flip()
Beispiel #2
0
 def update(self, screen: pygame.surface.Surface) -> bool:
     self.rect = screen.get_rect()
     self.update_humans_to_zombies()
     self.update_eaten_food()
     self.check_and_fix_edges()
     self.check_food()
     return not self.all_dead()
Beispiel #3
0
    def __init__(self,
                 pos: tuple,
                 method,
                 image: pygame.surface.Surface,
                 text: pygame.surface.Surface,
                 mixer,
                 *groups,
                 args: tuple = (),
                 anchor: tuple = (0, 0)):
        image.blit(text, (image.get_rect().centerx - text.get_rect().centerx,
                          image.get_rect().centery - text.get_rect().centery))

        self.method = method
        self.args = args
        self.mixer = mixer

        super().__init__(pos, image, *groups, anchor=anchor)
Beispiel #4
0
    def draw(self, surface: pygame.surface.Surface) -> None:

        # tell the map_layer (BufferedRenderer) to draw to the surface
        # the draw function requires a rect to draw to.
        self.map_layer.draw(surface, surface.get_rect())

        # blit our text over the map
        self.draw_text(surface)
Beispiel #5
0
    def replace_circle(self, image: pygame.surface.Surface):
        """[summary].

        Args:
            image (pygame.surface.Surface): [description].
        """
        sprite = SimpleSprite(rect=image.get_rect(), image=image)
        sprite.rect.center = self.badgesprite.center
        self.badgesprite.add(sprite)
        self.add(sprite)
Beispiel #6
0
    def drawForeground(
        self: "MapView",
        screen: pg.surface.Surface,
        position: Vector,  # World position
        texture: pg.surface.Surface,
    ) -> None:
        w, h = texture.get_rect().size
        scaledHeight = int(h * self.zoomRatio)
        scaledTexture = pg.transform.scale(texture, (self.scaledTileSize, scaledHeight))

        screenPos = self.worldToScreen(position)
        topLeft = screenPos + Vector(0, self.scaledTileSize - scaledHeight)

        screen.blit(scaledTexture, topLeft.toTuple())
def execute(screen: pygame.surface.Surface):
    """
    Функция запускает меню игры на паузе на переданном экране. В
    зависимости от действий закрывает всю игру, либо продолжает дальше
    :param screen: Экран на котором надо отрисовывать менюв
    :return: Возвращает -1, если игру надо закрыть, None если нет
    """
    is_open = True
    clock = pygame.time.Clock()
    joystick = get_joystick() if check_any_joystick() else None

    # Смещение между UI элементами
    UI_MARGIN = 20
    # Фоновое изображение для всего экрана
    background_image = load_image("pause_menu_BG.png", "assets/UI")
    background_image = pygame.transform.scale(background_image,
                                              screen.get_size())
    # Фоновое игображение
    ui_background_image = load_image("pause_menu_UI_BG.png", "assets/UI")
    # Центральная координата всего меню на экране
    menu_top_left = (screen.get_width() * 0.5 -
                     ui_background_image.get_width() * 0.5,
                     screen.get_height() * 0.5 -
                     ui_background_image.get_height() * 0.5)

    # Создание UI элементов
    next_y = menu_top_left[1] + ui_background_image.get_width(
    ) * 0.5 - UI_MARGIN * 2.5
    button_continue = Button((screen.get_width() // 2, next_y),
                             "Продолжить",
                             32,
                             base_button_filename="button_1.png",
                             hover_button_filename="button_1_hover.png")

    next_y += button_continue.rect.width * 0.5 + UI_MARGIN
    button_exit = Button((screen.get_width() // 2, next_y),
                         "Выйти в меню",
                         32,
                         base_button_filename="button_1.png",
                         hover_button_filename="button_1_hover.png")

    # Добавление в группу
    UI_sprites = pygame.sprite.Group()
    UI_sprites.add(button_continue)
    UI_sprites.add(button_exit)

    # Изображение для курсора
    cursor_image = load_image("cursor.png", "assets/UI/icons")
    # координаты курсора
    cursor_x, cursor_y = screen.get_rect().center
    cursor_speed = 25  # скорость курсора (нужно если используется джойстик)

    # Цикл меню
    while is_open:
        # Переменная, становящайся True если было нажатие курсора
        # (предусмотрен как джойстик, так и обычная мышка)
        was_click = False

        # Обработка событий
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                is_open = False
                break

            if event.type == pygame.MOUSEBUTTONUP:
                if event.button == 1:
                    was_click = True

            if event.type == Button.PRESS_TYPE:
                # Текст нажатой кнопки
                # (гарантированно есть, т.к. устанавливается при инициализации)
                sender_text = event.dict["sender_text"]

                # Продолжить
                if sender_text == button_continue.text:
                    is_open = False
                    UI_sprites.empty()  # удаление всех спрайтов в группе
                    break

                # Выход
                if sender_text == button_exit.text:
                    return -1

        # Определение местоположения для курсора
        if joystick:
            axis_x, axis_y = joystick.get_axis(0), joystick.get_axis(1)
            cursor_x += cursor_speed * axis_x if abs(
                axis_x) >= JOYSTICK_SENSITIVITY else 0
            cursor_y += cursor_speed * axis_y if abs(
                axis_y) >= JOYSTICK_SENSITIVITY else 0
            # Проверка на нажатие
            was_click = joystick.get_button(CONTROLS["JOYSTICK_UI_CLICK"])
        else:
            cursor_x, cursor_y = pygame.mouse.get_pos()

        cursor_position = (cursor_x, cursor_y)
        # Обновляем все UI элементы
        UI_sprites.update(cursor_position, was_click)

        # Очистка экрана
        screen.fill((0, 0, 0))

        # Фоновое изображение окна
        screen.blit(background_image, (0, 0))
        # Фоновое изобраджение UI
        screen.blit(ui_background_image, menu_top_left)
        # Рисуем весь UI
        UI_sprites.draw(screen)

        # Рисуем курсор поверх всего
        screen.blit(cursor_image, cursor_position)
        pygame.display.flip()

        # Обновляем состояние джойстика
        joystick = get_joystick() if check_any_joystick() else None
        clock.tick(FPS)
Beispiel #8
0
def execute(screen: pygame.surface.Surface) -> int:
    """
    Функция запускает меню игры на паузе на переданном экране. В
    зависимости от действий закрывает всю игру, либо продолжает дальше
    :param screen: Экран на котором надо отрисовывать меню
    :return: Возвращает код. (1 - начать заного, -1 - закрыть игру, None - ничего)
    """
    is_open = True
    clock = pygame.time.Clock()
    joystick = get_joystick() if check_any_joystick() else None
    # Смещение между UI элементами
    margin = 20
    # Фоновое изображение для всего экрана
    background_image = AnimatedBackground(
        "pause_menu_BG_{0}.png", "assets/sprites/UI/backgrounds/pause_BG", 1,
        45, 25, screen.get_size())
    menu_width, menu_height = 280, 360
    # Фоновое игображение
    background_menu_image = scale_frame(
        load_image("assets/sprites/UI/backgrounds/pause_menu_UI_BG.png"),
        (menu_width, menu_height))
    # Центральная координата всего меню на экране
    menu_top_left = (screen.get_width() * 0.5 - menu_width * 0.5,
                     screen.get_height() * 0.25)
    # Группа со спрайтами интерфейса
    UI_sprites = pygame.sprite.Group()
    # Создание кнопок
    next_y = menu_top_left[1] + margin * 3.5  # позиция y следущего элемента
    titles = ("Продолжить", "Начать заново", "Выйти в меню"
              )  # заголовки кнопок
    for number in range(len(titles)):
        # Текущая кнопка
        button = Button((screen.get_width() // 2, next_y),
                        titles[number],
                        32,
                        base_button_filename="button_1.png",
                        hover_button_filename="button_1_hover.png")
        # Высчитывание следущей позиции по y со смещением
        next_y += button.rect.height + margin
        # Добавление в группу
        UI_sprites.add(button)
    # Изображение для курсора
    cursor_image = load_image("assets/sprites/UI/icons/cursor.png")
    # координаты курсора
    cursor_x, cursor_y = screen.get_rect().center
    cursor_speed = 40  # скорость курсора (нужно если используется джойстик)
    # Цикл меню
    while is_open:
        # Переменная, становящайся True если было нажатие курсора
        # (предусмотрен как джойстик, так и обычная мышка)
        was_click = False
        # Обработка событий
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                is_open = False
                break

            if event.type == pygame.MOUSEBUTTONUP:
                if event.button == 1:
                    was_click = True

            if event.type == pygame.KEYDOWN:
                if event.key == CONTROLS["KEYBOARD_PAUSE"]:
                    is_open = False
                    UI_sprites.empty()  # удаление всех спрайтов в группе
                    break

            if event.type == Button.PRESS_TYPE:
                # Текст нажатой кнопки
                # (гарантированно есть, т.к. устанавливается при инициализации)
                sender_text = event.dict["sender_text"]
                # Продолжить
                if sender_text == titles[0]:
                    is_open = False
                    UI_sprites.empty()  # удаление всех спрайтов в группе
                    break
                # Начать заного
                if sender_text == titles[1]:
                    return 1
                # Выход
                if sender_text == titles[-1]:
                    return -1
        # Определение местоположения для курсора
        if joystick:
            axis_x, axis_y = joystick.get_axis(0), joystick.get_axis(1)
            cursor_x += cursor_speed * axis_x if abs(
                axis_x) >= JOYSTICK_SENSITIVITY else 0
            cursor_y += cursor_speed * axis_y if abs(
                axis_y) >= JOYSTICK_SENSITIVITY else 0
            # Проверка на нажатие
            was_click = joystick.get_button(CONTROLS["JOYSTICK_UI_CLICK"])
        else:
            cursor_x, cursor_y = pygame.mouse.get_pos()
        cursor_position = cursor_x, cursor_y

        # Обновляем все UI элементы
        UI_sprites.update(cursor_position, was_click)
        # Очистка экрана
        screen.fill((0, 0, 0))
        # Фоновое изображение окна
        background_image.update()
        screen.blit(background_image.image, (0, 0))
        # Фоновое изобраджение UI
        screen.blit(background_menu_image, menu_top_left)
        # Рисуем весь UI
        UI_sprites.draw(screen)
        # Рисуем курсор поверх всего
        screen.blit(cursor_image, cursor_position)
        pygame.display.flip()
        # Обновляем состояние джойстика
        joystick = get_joystick() if check_any_joystick() else None
        clock.tick(FPS)
Beispiel #9
0
def execute(screen: pygame.surface.Surface,
            money: int,
            count_of_alive_assistants: int,
            is_win=False):
    """
    Функция запускает конечной экран (либо смерти, либо победы)
    :param screen: Экран на котором надо отрисовывать менюв
    :param is_win: Флаг, выиграл ли игрок
    :param money: Количество собранных игроком и асистентом денег
    :param count_of_alive_assistants: Количетсво всех живых осистентов к концу игры
    игры
    """
    is_open = True
    # Фоновое изображение для всего экрана
    if is_win:
        # Фоновая музыка при победе
        pygame.mixer.music.load("assets/audio/music/win_screen_BG.ogg")
        pygame.mixer.music.play(-1)
        animated_background = AnimatedBackground(
            "win_{0}.png", "assets/sprites/UI/backgrounds/triumph_screen", 1,
            8, 80, screen.get_size())
        # Картигка с заголовком победы
        title_you_win = load_image('assets/sprites/UI/you_win.png')
        you_win_rect = title_you_win.get_rect()
        you_win_rect.center = screen.get_rect().centerx, int(
            screen.get_rect().centery * 0.7)
    else:
        # Фоновая музыка при проигрыше
        pygame.mixer.music.load("assets/audio/music/fail_screen_BG.mp3")
        pygame.mixer.music.play(-1)
        # Высчитывание размера для фона и сам фон
        size = screen.get_width() // 3, screen.get_height() // 3
        animated_background = AnimatedBackground(
            "death_{0}.png",
            "assets/sprites/UI/backgrounds/fail_screen",
            1,
            23,
            140,
            size,
            scale_2n=True)
    # Лого игры
    logo = LogoImage((screen.get_width() * 0.5, screen.get_height() * 0.1))
    # Изображение курсора
    cursor_image = load_image("assets/sprites/UI/icons/cursor.png")
    # Получение джойстика (если есть) и определение начальной позиции курсора
    if check_any_joystick():
        joystick = get_joystick()
        cursor_x, cursor_y = screen.get_rect().center
    else:
        joystick = None
        # Т.к. джойстика нет позиция будет сразу переопределна далее,
        # поэтому тут начальная позиция не задаётся
        cursor_x, cursor_y = 0, 0
    # Т.к. игрок завершил игру, то файл с сохранением будет перезаписан
    if os.path.isfile("data/save.txt"):
        with open('data/save.txt', 'r+', encoding="utf-8") as file:
            file.truncate(0)
    # Кортеж с текстом который надо вывести (каждый элемент на новой строке)
    texts = (f"Деньги собранные игроком вместе с асистентом: {money}",
             f"Количество живых асистентов: {count_of_alive_assistants}")
    # Шрифт для поверхностей ниже
    title_font = load_game_font(64)
    # Поверхности с одним и тем же текстом, но разный цвет делает крассивый эффект
    text_surfaces_yellow = [
        title_font.render(part.strip(), True, (255, 184, 50)) for part in texts
    ]
    text_surfaces_red = [
        title_font.render(part.strip(), True, (179, 64, 16)) for part in texts
    ]
    # Смещение между наложенными поверхностями для красивого эффекта
    surfaces_offset = 3
    margin = title_font.get_height() * 0.9  # отступ между двумя поверхностями
    # События, которые активируют закрытие экрана с концном
    QUITING_EVENTS = (
        pygame.QUIT,
        pygame.MOUSEBUTTONUP,
        pygame.KEYDOWN,
    )
    # Цикл меню
    while is_open:
        # Обработка событий
        for event in pygame.event.get():
            if event.type in QUITING_EVENTS:
                is_open = False
                break
        # Обновление позиции курсора
        if joystick is not None:
            # Проверка на выход
            if joystick.get_button(CONTROLS["JOYSTICK_UI_CLICK"]):
                break
            # Значение осей на левом стике
            axis_x, axis_y = joystick.get_axis(0), joystick.get_axis(1)
            # Перемещение курсора при движении оси
            if abs(axis_x) >= JOYSTICK_SENSITIVITY:
                cursor_x += JOYSTICK_CURSOR_SPEED * axis_x
            if abs(axis_y) >= JOYSTICK_SENSITIVITY:
                cursor_y += JOYSTICK_CURSOR_SPEED * axis_y
        else:
            cursor_x, cursor_y = pygame.mouse.get_pos()
        # На экране проигрыша есть фон, которого нет на экране победы
        if not is_win:
            screen.fill((31, 30, 36))
        # Вывод текущего кадра фонового изображения
        animated_background.update()
        screen.blit(
            animated_background.image,
            animated_background.image.get_rect(
                center=screen.get_rect().center))
        # Вывод картинки победного заголовка, если игрок выиграл
        if is_win:
            # Анализатор может ругаться, но если is_win истина, то
            # переменные 100% объявлены выше
            screen.blit(title_you_win, you_win_rect)
        # следущая позиция по y (будет нужно при вычислении смещения)
        next_y = 20
        # Вывод красного текста
        for text_surface in text_surfaces_red:
            y_pos = screen.get_height() * 0.6 + next_y
            screen.blit(
                text_surface,
                text_surface.get_rect(midtop=(screen.get_rect().centerx +
                                              surfaces_offset,
                                              y_pos + surfaces_offset)))
            next_y += margin
        next_y = 20
        # Вывод жёлтого текста
        for text_surface in text_surfaces_yellow:
            y_pos = screen.get_height() * 0.6 + next_y
            screen.blit(
                text_surface,
                text_surface.get_rect(midtop=(screen.get_rect().centerx,
                                              y_pos)))
            next_y += margin
        # Вывод логотипа игры
        screen.blit(logo.image, logo.rect.topleft)
        # Вывод изображения курсора
        screen.blit(cursor_image, (cursor_x, cursor_y))

        # Обновление состояния джойстика
        joystick = get_joystick() if check_any_joystick() else None
        pygame.display.flip()
Beispiel #10
0
def execute(screen: pygame.surface.Surface, is_win=False):
    """
    Функция запускает конечной экран (либо смерти, либо победы)
    :param screen: Экран на котором надо отрисовывать менюв
    :param is_win: Флаг, выиграл ли игрок
    """

    is_open = True
    clock = pygame.time.Clock()
    joystick = get_joystick() if check_any_joystick() else None

    # Фоновое изображение для всего экрана
    if not is_win:
        animated_background = AnimatedBackground("death_{0}.png", 1, 23, 60,
                                                 screen.get_size())
    else:
        # Фоновая музыка для победителя
        pygame.mixer.music.load(
            concat_two_file_paths("assets/audio", "win_screen_BG.ogg"))
        pygame.mixer.music.play(-1)
        animated_background = AnimatedBackground("win_{0}.png", 1, 8, 60,
                                                 screen.get_size())

    # Лого игры
    logo = LogoImage((screen.get_width() * 0.5, screen.get_height() * 0.1))

    # Кнопка возвращения в меню
    button_exit = Button((screen.get_width() // 2, screen.get_height() * 0.9),
                         "Вернутся в меню",
                         32,
                         base_button_filename="button_1.png",
                         hover_button_filename="button_1_hover.png")

    # Добавление в группу
    UI_sprites = pygame.sprite.Group()
    UI_sprites.add(logo)
    UI_sprites.add(button_exit)

    # Изображение для курсора
    cursor_image = load_image("cursor.png", "assets/UI/icons")
    # координаты курсора
    cursor_x, cursor_y = screen.get_rect().center
    cursor_speed = 15  # скорость курсора (нужно если используется джойстик)

    # Т.к. игрок завершил игру, то файл с сохранением будет перезаписан
    if os.path.isfile("data/save.txt"):
        with open('data/save.txt', 'r+', encoding="utf-8") as file:
            file.truncate(0)

    # Цикл меню
    while is_open:
        # Переменная, становящайся True если было нажатие курсора
        # (предусмотрен как джойстик, так и обычная мышка)
        was_click = False

        # Обработка событий
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                is_open = False
                break

            if event.type == pygame.MOUSEBUTTONUP:
                if event.button == 1:
                    was_click = True

            if event.type == Button.PRESS_TYPE:
                # Текст нажатой кнопки
                # (гарантированно есть, т.к. устанавливается при инициализации)
                sender_text = event.dict["sender_text"]

                # Выход
                if sender_text == button_exit.text:
                    return

        # Определение местоположения для курсора
        if joystick:
            axis_x, axis_y = joystick.get_axis(0), joystick.get_axis(1)
            cursor_x += cursor_speed * axis_x if abs(
                axis_x) >= JOYSTICK_SENSITIVITY else 0
            cursor_y += cursor_speed * axis_y if abs(
                axis_y) >= JOYSTICK_SENSITIVITY else 0
            # Проверка на нажатие
            was_click = joystick.get_button(CONTROLS["JOYSTICK_UI_CLICK"])
        else:
            cursor_x, cursor_y = pygame.mouse.get_pos()

        cursor_position = (cursor_x, cursor_y)
        # Обновляем все UI элементы
        UI_sprites.update(cursor_position, was_click)

        # Очистка экрана
        screen.fill((0, 0, 0))

        animated_background.update()
        # Вывод текущего кадра фонового изображения
        screen.blit(animated_background.image, (0, 0))

        # Рисуем весь UI
        UI_sprites.draw(screen)

        # Рисуем курсор поверх всего
        screen.blit(cursor_image, cursor_position)
        pygame.display.flip()

        # Обновляем состояние джойстика
        joystick = get_joystick() if check_any_joystick() else None
        clock.tick(FPS)
Beispiel #11
0
def game(displaysurf: pg.surface.Surface, clock: pg.time.Clock, diff: str,
         diff_color: Tuple[int, int, int]) -> int:
    """게임의 메인 로직을 실행한다.

    Args:
        displaysurf: init 함수에 의해 반환된 최상위 Surface
        clock: init 함수에 의해 반환된 Clock
        diff: prompt_difficulty 함수에 의해 반환된 난이도
        diff_color: prompt_difficulty 함수에 의해 반환된 난이도에 해당하는 색상

    Returns:
        게임 결과(점수)

    """

    screenrect = displaysurf.get_rect()  # 게임 영역 설정

    groupdict: Dict[str, pg.sprite.Group] = dict()  # 그룹 불러오기
    groupdict = {
        'bullet': pg.sprite.Group(),
        'player': pg.sprite.Group(),
        'enemy': pg.sprite.Group(),
        'danmaku': pg.sprite.Group()
    }

    spritedict: Dict[str, Element] = dict()

    parser = Parser(screenrect, groupdict, spritedict)  # 패턴 구문분석

    spritedict['player'] = parser.load('assets/player.json')
    groupdict['player'].add(spritedict['player'])  # 플레이어 추가

    loadeddict = loadfiles(diff)  # 패턴 파일 로드
    sounddict = loadsounds()

    _frame: int = 0
    frame: int = 0
    score: int = ct.INITIALSCORE
    limittime: float = ct.LIMITTIME
    onon: int = 0  # 변수 결정

    pg.mixer.Sound.play(sounddict['bgm'])

    while True:  # 게임 구동기
        _frame += 1  # 시간 증가
        frame += 1

        if frame == limittime // 1 and onon == 0:  # 게임 중 적 생성 시간일 때
            enemychoose(groupdict['enemy'], parser, loadeddict)  # 적 생성
            frame = 0  # 적 생성 시간 초기화
            if limittime > ct.OVERLIMIT:
                limittime -= ct.LIMITREDUCE  # 적 생성 주기 단축
            else:
                onon = 1  # 게임 종료 시간

        if onon == 1:  # 게임 끝
            if frame == ct.OVERTIME:
                return score

        for event in pg.event.get():
            groupdict['player'].update(event=event)  # 객체 위치 이동
            if event.type == pg.QUIT:  # 종료 버튼
                pg.quit()
                sys.exit()

        displaysurf.fill(ct.BLACK)  # 배경 색
        if pg.sprite.groupcollide(groupdict['player'], groupdict['danmaku'],
                                  False, False):
            score -= 1  # 부딫혔을 때 충돌 카운트 +1
            pg.mixer.Sound.play(sounddict['gothit'])

        # 쏜 총이 적 맞았을 때 적 kill
        pg.sprite.groupcollide(groupdict['bullet'], groupdict['enemy'], False,
                               True)

        enemyn = len(groupdict['enemy'])
        for key in groupdict:
            groupdict[key].update()  # 모든 객체 위치 업데이트
            groupdict[key].draw(displaysurf)
        # 적이 자연적으로 죽을 경우 페널티
        score -= ct.PENALTY * (enemyn - len(groupdict['enemy']))

        write_text(displaysurf, 60, (20, 20), f"{score}", ct.WHITE)
        write_text_rt(displaysurf, 60, (ct.WIDTH - 20, 20), diff, diff_color)

        pg.display.update()
        clock.tick(ct.FPS)  # 시간 업데이트