Пример #1
0
class Speaker(pygame_gui.elements.UIWindow):
    def __init__(self, pos, manager):
        super().__init__(
            pygame.Rect(pos, (400, 128)),
            manager=manager,
            window_display_title="speaker",
            object_id="#speaker",
        )
        self.label = UILabel(
            relative_rect=pygame.Rect(-20, 10, 400, 20),
            text="",
            manager=manager,
            container=self,
        )
        self.input = UITextEntryLine(relative_rect=pygame.Rect(0, 40, 368, 30),
                                     manager=manager,
                                     container=self)
        self.engine = pyttsx3.init()
        self.engine.setProperty("rate", 150)
        self.speakthrd = None

    def process_event(self, event):
        super().process_event(event)
        if event.type == pygame.USEREVENT and event.ui_element == self.input and event.user_type == pygame_gui.UI_TEXT_ENTRY_FINISHED and (
                self.speakthrd is None or
                not self.speakthrd.is_alive()) and self.input.get_text != "":
            self.engine.say(self.input.get_text)
            self.speakthrd = threading.Thread(target=self.engine.runAndWait,
                                              args=())
            self.speakthrd.start()
            self.label.set_text(self.input.get_text)
            self.input.set_text("")
Пример #2
0
class TextValueLabel(object):
    def __init__(self, text_rect: pygame.rect.Rect, text, value, manager,
                 container):
        self.ui_manager = manager
        self.text_rect = text_rect
        self.container = container
        self.text = text
        self.value = value
        self.text_label = UILabel(self.text_rect,
                                  text,
                                  manager=self.ui_manager,
                                  container=self.container)
        self.value_label = UILabel(pygame.Rect(
            (self.text_rect.x, self.text_rect.y + self.text_rect.height),
            (self.text_rect.width, self.text_rect.height)),
                                   value,
                                   manager=self.ui_manager,
                                   container=self.container)

    def set_value(self, value):
        self.value = value
        self.value_label.set_text(value)

    def set_text(self, text):
        self.text = text
        self.text_label.set_text(text)
Пример #3
0
class Label(ColorElement):
    def __init__(self,
                 text,
                 layout_info,
                 container,
                 text_color=BLACK,
                 background_color=TRANSPARENT,
                 padding=None):
        super().__init__(layout_info, container, padding)
        self.text = text
        self.element = UILabel(relative_rect=self.bounds,
                               manager=self.manager,
                               text=text)
        self.text_color = text_color
        self.background_color = background_color

    def set_text(self, text):
        self.text = text
        self.element.set_text(text)

    @property
    def text_color(self):
        return self.element.text_colour

    @text_color.setter
    def text_color(self, color):
        if color is None:
            return

        self.element.text_colour = color
        self.element.rebuild()
Пример #4
0
class SpeakSpell(pygame_gui.elements.UIWindow):
    speakthrd = None

    def __init__(self, pos, manager):
        super().__init__(
            pygame.Rect(pos, (400,128)),
            manager=manager,
            window_display_title='speaknspell',
            object_id='#speaknspell'
        )

        self.label = UILabel(
            relative_rect=pygame.Rect(-20, 10, 400, 20),
            text='',
            manager=manager,
            container=self
        )

        self.input = UITextEntryLine(
            relative_rect=pygame.Rect(0, 40, 368, 30),
            manager=manager,
            container=self
        )

        self.engine = pyttsx3.init()
        self.engine.setProperty('rate', 150)
        self.speakthrd = None

        self.speak('Hello, thank you for using snakeware!')

    def speak(self, text):
        if self.speakthrd is not None and self.speakthrd.is_alive():
            return

        if text == '':
            return

        self.engine.say(text)
        self.speakthrd = threading.Thread(target=self.engine.runAndWait, args=())
        self.speakthrd.start()
        self.label.set_text(text)
        self.input.set_text('')

    def process_event(self, event):
        super().process_event(event)
        if event.type == pygame.USEREVENT and event.ui_element == self.input:
            if event.user_type == pygame_gui.UI_TEXT_ENTRY_FINISHED:
                self.speak(self.input.get_text())
Пример #5
0
class EverythingWindow(UIWindow):
    def __init__(self, rect, ui_manager):
        super().__init__(rect,
                         ui_manager,
                         window_display_title='Everything Container',
                         object_id='#everything_window',
                         resizable=True)

        self.test_slider = UIHorizontalSlider(pygame.Rect(
            (int(self.rect.width / 2), int(self.rect.height * 0.70)),
            (240, 25)),
                                              50.0, (0.0, 100.0),
                                              self.ui_manager,
                                              container=self)

        self.slider_label = UILabel(
            pygame.Rect(
                (int(self.rect.width / 2) + 250, int(self.rect.height * 0.70)),
                (27, 25)),
            str(int(self.test_slider.get_current_value())),
            self.ui_manager,
            container=self)

        self.test_text_entry = UITextEntryLine(pygame.Rect(
            (int(self.rect.width / 2), int(self.rect.height * 0.50)),
            (200, -1)),
                                               self.ui_manager,
                                               container=self)
        self.test_text_entry.set_forbidden_characters('numbers')

        current_resolution_string = 'Item 1'
        self.test_drop_down_menu = UIDropDownMenu(
            [
                'Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6',
                'Item 7', 'Item 8', 'Item 9', 'Item 10', 'Item 11', 'Item 12',
                'Item 13', 'Item 14', 'Item 15', 'Item 16', 'Item 17',
                'Item 18', 'Item 19', 'Item 20', 'Item 21', 'Item 22',
                'Item 23', 'Item 24', 'Item 25', 'Item 26', 'Item 27',
                'Item 28', 'Item 29', 'Item 30'
            ],
            current_resolution_string,
            pygame.Rect(
                (int(self.rect.width / 2), int(self.rect.height * 0.3)),
                (200, 25)),
            self.ui_manager,
            container=self)

        self.health_bar = UIScreenSpaceHealthBar(pygame.Rect(
            (int(self.rect.width / 9), int(self.rect.height * 0.7)),
            (200, 20)),
                                                 self.ui_manager,
                                                 container=self)

        loaded_test_image = pygame.image.load(
            'data/images/splat.png').convert_alpha()

        self.test_image = UIImage(pygame.Rect(
            (int(self.rect.width / 9), int(self.rect.height * 0.3)),
            loaded_test_image.get_rect().size),
                                  loaded_test_image,
                                  self.ui_manager,
                                  container=self)

    def update(self, time_delta):
        super().update(time_delta)

        if self.alive() and self.test_slider.has_moved_recently:
            self.slider_label.set_text(
                str(int(self.test_slider.get_current_value())))
Пример #6
0
class MapEditor:
    def __init__(self, tiled_level, hud_rect, all_square_sprites, ui_manager):
        self.editing_layer = 0
        self.tiled_level = tiled_level
        self.hud_rect = hud_rect
        self.all_square_sprites = all_square_sprites
        self.ui_manager = ui_manager

        self.current_levels = [
            file for file in os.listdir("data/levels/")
            if os.path.isfile(os.path.join("data/levels/", file))
        ]

        self.left_mouse_held = False
        self.right_mouse_held = False

        self.need_to_refresh_tiles = True

        self.default_tile = [
            pygame.Rect(0, 0, 0, 0), self.tiled_level.tile_map[0][0],
            "grass_tile", True, None
        ]
        self.held_tile_data = self.default_tile

        self.held_ai_spawn = None
        self.held_turret_square = None

        self.rect_of_tile = None
        self.hovered_rec = None

        self.rotate_selected_tile_left = False
        self.rotate_selected_tile_right = False

        self.all_palette_tile_sprites = pygame.sprite.Group()
        self.all_ai_spawn_sprites = pygame.sprite.Group()

        self.palette_page = 0
        self.should_increase_palette_page = False
        self.should_decrease_palette_page = False

        self.remove_turret_square_icon = None
        self.place_turret_square_icon = None
        self.remove_waypoint_icon = None
        self.place_waypoint_icon = None
        self.right_click_mode = "place_tile"

        self.palette_tiles = []
        self.palette_ai_spawns = []
        self.num_ai_spawns = 3
        self.tiles_per_page = 26
        all_tiles_and_ai = len(
            self.tiled_level.all_tile_data.keys()) + self.num_ai_spawns
        self.max_pages = int(math.ceil(all_tiles_and_ai / self.tiles_per_page))

        self.refresh_palette_tiles()

        self.left_scroll_held = False
        self.right_scroll_held = False
        self.up_scroll_held = False
        self.down_scroll_held = False

        self.map_scroll_speed = 256.0

        self.map_start_pos = self.tiled_level.find_player_start()
        self.map_position = [self.map_start_pos[0], self.map_start_pos[1]]

        # self.map_editor_instructions = MapEditorInstructionsWindow([362, 100, 300, 250], fonts)
        instructions_message = (
            "Arrow keys to scroll map <br>"
            "Left mouse click to select tile from palette<br>"
            "Right mouse click to place tile<br>"
            "'>' and '<' to rotate selected tile<br>"
            "F5 or quit to save map<br>")
        self.instruction_message_window = UIMessageWindow(
            pygame.Rect((362, 100), (300, 250)), "Instructions",
            instructions_message, self.ui_manager)

        self.level_name_label = UILabel(pygame.Rect((462, 8), (100, 34)),
                                        self.tiled_level.level_name,
                                        self.ui_manager,
                                        object_id="#screen_text")

        self.make_new_button = UIButton(
            pygame.Rect(870, self.hud_rect[1] + 24, 100, 20), "Make New",
            self.ui_manager)

        self.tile_set_button = UIButton(
            pygame.Rect(870, self.hud_rect[1] + 49, 100, 20), "Switch Tiles",
            self.ui_manager)

        self.playable_area_display = PlayableAreaDisplay()

        self.visible_way_point_circles = []
        self.refresh_visible_waypoint_circles()

    def end(self):
        if self.tile_set_button is not None:
            self.tile_set_button.kill()
            self.tile_set_button = None

        if self.make_new_button is not None:
            self.make_new_button.kill()
            self.make_new_button = None

        if self.level_name_label is not None:
            self.level_name_label.kill()
            self.level_name_label = None

        if self.instruction_message_window is not None:
            self.instruction_message_window.kill()
            self.instruction_message_window = None

        for circle in self.visible_way_point_circles:
            circle.kill()

    def refresh_visible_waypoint_circles(self):
        for circle in self.visible_way_point_circles:
            circle.kill()
            del circle
        self.visible_way_point_circles[:] = []
        traversal_order = 1
        if self.tiled_level.monster_walk_path.start_waypoint is not None:
            self.visible_way_point_circles.append(
                DrawableWaypointCircle(
                    self.tiled_level.monster_walk_path.waypoint_radius,
                    self.tiled_level.monster_walk_path.start_waypoint,
                    self.ui_manager, traversal_order))
            traversal_order += 1
        for waypoint in self.tiled_level.monster_walk_path.waypoints:
            self.visible_way_point_circles.append(
                DrawableWaypointCircle(
                    self.tiled_level.monster_walk_path.waypoint_radius,
                    waypoint, self.ui_manager, traversal_order))
            traversal_order += 1

    def display_turret_placement_squares(self, screen):
        self.all_square_sprites.draw(screen)

    def increase_palette_pos(self, x_pos, y_pos):
        x_pos += self.tiled_level.tile_size[0] + 8
        if x_pos > 800:
            x_pos = 40
            y_pos += self.tiled_level.tile_size[1] + 8
        return x_pos, y_pos

    def refresh_palette_tiles(self):
        self.all_palette_tile_sprites.empty()
        self.palette_tiles[:] = []
        self.palette_ai_spawns[:] = []
        x_pos = 40
        y_pos = 40

        sorted_tile_keys = sorted(self.tiled_level.all_tile_data.keys())
        display_tile = self.palette_page * self.tiles_per_page

        max_tile = (self.palette_page *
                    self.tiles_per_page) + self.tiles_per_page
        min_tile = len(sorted_tile_keys) + self.num_ai_spawns
        while display_tile < min_tile and display_tile < max_tile:
            if display_tile < len(sorted_tile_keys):
                tile_data = sorted_tile_keys[display_tile]
                self.palette_tiles.append(
                    Tile([self.hud_rect[0] + x_pos, self.hud_rect[1] + y_pos],
                         0, self.tiled_level.all_tile_data[tile_data],
                         self.editing_layer))
                display_tile += 1
            else:
                self.remove_turret_square_icon = RemoveTurretSquareIcon(
                    [self.hud_rect[0] + x_pos, self.hud_rect[1] + y_pos],
                    self.all_palette_tile_sprites)
                x_pos, y_pos = self.increase_palette_pos(x_pos, y_pos)
                display_tile += 1

                self.place_turret_square_icon = PlaceTurretSquareIcon(
                    [self.hud_rect[0] + x_pos, self.hud_rect[1] + y_pos],
                    self.all_palette_tile_sprites)
                x_pos, y_pos = self.increase_palette_pos(x_pos, y_pos)
                display_tile += 1

                self.remove_waypoint_icon = RemoveWaypointIcon(
                    [self.hud_rect[0] + x_pos, self.hud_rect[1] + y_pos],
                    self.all_palette_tile_sprites)
                x_pos, y_pos = self.increase_palette_pos(x_pos, y_pos)
                display_tile += 1

                self.place_waypoint_icon = PlaceWaypointIcon(
                    [self.hud_rect[0] + x_pos, self.hud_rect[1] + y_pos],
                    self.all_palette_tile_sprites)
                x_pos, y_pos = self.increase_palette_pos(x_pos, y_pos)
                display_tile += 1

                display_tile += self.num_ai_spawns

            x_pos, y_pos = self.increase_palette_pos(x_pos, y_pos)

        for tile in self.palette_tiles:
            self.all_palette_tile_sprites.add(tile)

        # for aiSpawn in self.paletteAISpawns:
        #    self.allPaletteTileSprites.add(aiSpawn.sprite)

    def run(self, screen, background, all_tile_sprites, hud_rect, time_delta):
        running = True
        for event in pygame.event.get():
            self.ui_manager.process_events(event)

            if event.type == USEREVENT:
                if event.user_type == "ui_button_pressed":
                    if event.ui_element == self.make_new_button:
                        new_level_num = len(self.current_levels) + 1
                        new_level_name = "Level " + str(new_level_num)
                        self.tiled_level.change_level_name_and_save(
                            new_level_name)
                        self.level_name_label.set_text(
                            self.tiled_level.level_name)
                    elif event.ui_element == self.tile_set_button:
                        self.tiled_level.toggle_tile_map()
                        for tile in self.palette_tiles:
                            tile.reload_tile_image_from_data(
                                self.tiled_level.all_tile_data)

            if event.type == QUIT:
                self.tiled_level.save_tiles()
                running = False
            if event.type == MOUSEBUTTONDOWN:
                if event.button == 1:
                    self.left_mouse_held = True
                if event.button == 3:
                    self.right_mouse_held = True
            if event.type == MOUSEBUTTONUP:
                if event.button == 1:
                    self.left_mouse_held = False
                if event.button == 3:
                    self.right_mouse_held = False
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    self.tiled_level.save_tiles()
                    running = False
                if event.key == K_F5:
                    self.tiled_level.save_tiles()
                if event.key == K_PERIOD:
                    self.rotate_selected_tile_right = True
                if event.key == K_COMMA:
                    self.rotate_selected_tile_left = True
                if event.key == K_UP:
                    self.up_scroll_held = True
                if event.key == K_DOWN:
                    self.down_scroll_held = True
                if event.key == K_LEFT:
                    self.left_scroll_held = True
                if event.key == K_RIGHT:
                    self.right_scroll_held = True
                if event.key == K_1:
                    self.editing_layer = 1
                if event.key == K_0:
                    self.editing_layer = 0
                if event.key == K_RIGHTBRACKET:
                    self.should_increase_palette_page = True
                if event.key == K_LEFTBRACKET:
                    self.should_decrease_palette_page = True
            if event.type == KEYUP:
                if event.key == K_UP:
                    self.up_scroll_held = False
                if event.key == K_DOWN:
                    self.down_scroll_held = False
                if event.key == K_LEFT:
                    self.left_scroll_held = False
                if event.key == K_RIGHT:
                    self.right_scroll_held = False

        self.ui_manager.update(time_delta)

        if self.should_increase_palette_page:
            self.should_increase_palette_page = False
            if self.palette_page < self.max_pages - 1:
                self.palette_page += 1
            else:
                self.palette_page = 0  # loop back round
            self.refresh_palette_tiles()

        if self.should_decrease_palette_page:
            self.should_decrease_palette_page = False
            if self.palette_page > 0:
                self.palette_page -= 1
            else:
                self.palette_page = self.max_pages - 1  # loop back round
            self.refresh_palette_tiles()

        if self.up_scroll_held:
            self.map_position[1] -= self.map_scroll_speed * time_delta
            if self.map_position[1] < self.tiled_level.initial_screen_offset[1]:
                self.map_position[1] = self.tiled_level.initial_screen_offset[
                    1]
        if self.down_scroll_held:
            self.map_position[1] += self.map_scroll_speed * time_delta
            y_limit = self.tiled_level.level_pixel_size[
                1] - self.tiled_level.initial_screen_offset[1] + self.hud_rect[
                    1]
            if self.map_position[1] > y_limit:
                self.map_position[1] = y_limit

        if self.left_scroll_held:
            self.map_position[0] -= self.map_scroll_speed * time_delta
            if self.map_position[0] < self.tiled_level.initial_screen_offset[0]:
                self.map_position[0] = self.tiled_level.initial_screen_offset[
                    0]
        if self.right_scroll_held:
            self.map_position[0] += self.map_scroll_speed * time_delta
            max_x = self.tiled_level.level_pixel_size[
                0] - self.tiled_level.initial_screen_offset[0]
            if self.map_position[0] > max_x:
                self.map_position[0] = max_x

        if self.rotate_selected_tile_right and self.held_tile_data[
                4] is not None:
            self.rotate_selected_tile_right = False
            self.held_tile_data[4].rotate_tile_right()
            self.need_to_refresh_tiles = True

        if self.rotate_selected_tile_left and self.held_tile_data[
                4] is not None:
            self.rotate_selected_tile_left = False
            self.held_tile_data[4].rotate_tile_left()
            self.need_to_refresh_tiles = True

        if self.left_mouse_held:
            click_pos = pygame.mouse.get_pos()
            if self.is_inside_hud(click_pos, hud_rect):
                self.held_tile_data = self.get_palette_tile_data_at_pos(
                    click_pos)
                if self.held_tile_data is None:
                    if self.remove_turret_square_icon.is_inside(click_pos):
                        self.right_click_mode = "remove_turret_square"
                    elif self.place_turret_square_icon.is_inside(click_pos):
                        self.right_click_mode = "place_turret_square"
                    elif self.remove_waypoint_icon.is_inside(click_pos):
                        self.right_click_mode = "remove_waypoint"
                    elif self.place_waypoint_icon.is_inside(click_pos):
                        self.right_click_mode = "place_waypoint"
                else:
                    self.right_click_mode = "place_tile"

            else:
                self.held_tile_data = self.tiled_level.get_tile_data_at_pos(
                    click_pos, self.editing_layer)

        if self.right_mouse_held:
            click_pos = pygame.mouse.get_pos()

            if self.is_inside_hud(click_pos, hud_rect):
                pass
            else:
                angle = 0
                if self.right_click_mode == "place_tile" and self.held_tile_data is not None:
                    if self.held_tile_data[4] is not None:
                        angle = self.held_tile_data[4].angle
                    self.rect_of_tile = self.tiled_level.set_tile_at_pos(
                        click_pos, self.held_tile_data[2], angle,
                        self.editing_layer)
                elif self.right_click_mode == "place_ai" and self.held_ai_spawn is not None:
                    self.tiled_level.add_ai_spawn_at_pos(
                        click_pos, self.held_ai_spawn)
                elif self.right_click_mode == "remove_ai":
                    self.tiled_level.remove_ai_spawn_at_pos(click_pos)
                elif self.right_click_mode == "remove_turret_square":
                    self.tiled_level.remove_turret_square_at_pos(click_pos)
                elif self.right_click_mode == "place_turret_square":
                    self.tiled_level.place_turret_square_at_pos(click_pos)
                elif self.right_click_mode == "remove_waypoint":
                    self.tiled_level.remove_waypoint_at_pos(click_pos)
                    self.refresh_visible_waypoint_circles()
                elif self.right_click_mode == "place_waypoint":
                    if self.tiled_level.place_waypoint_at_pos(click_pos):
                        self.refresh_visible_waypoint_circles()

        if self.tiled_level.update_offset_position(self.map_position,
                                                   all_tile_sprites):
            self.need_to_refresh_tiles = True

        self.all_ai_spawn_sprites.empty()
        for ai_spawn in self.tiled_level.ai_spawns:
            self.all_ai_spawn_sprites.add(ai_spawn)

        self.hovered_rec = self.tiled_level.get_tile_data_at_pos(
            pygame.mouse.get_pos(), self.editing_layer)[0]

        screen.blit(background, (0, 0))  # draw the background
        all_tile_sprites.draw(screen)
        self.all_ai_spawn_sprites.draw(screen)

        self.playable_area_display.draw(screen,
                                        self.tiled_level.position_offset)

        self.display_turret_placement_squares(screen)

        for waypoint_circles in self.visible_way_point_circles:
            waypoint_circles.update_offset_position(
                self.tiled_level.position_offset)
            waypoint_circles.draw(screen)

        if self.held_tile_data is not None:
            if not self.held_tile_data[3]:
                pygame.draw.rect(screen, pygame.Color("#FF6464"),
                                 self.held_tile_data[0], 1)
        if self.hovered_rec is not None:
            pygame.draw.rect(screen, pygame.Color("#FFE164"), self.hovered_rec,
                             1)
        # draw the hud
        pygame.draw.rect(screen, pygame.Color("#3C3C3C"), hud_rect, 0)
        self.all_palette_tile_sprites.draw(screen)
        if self.held_tile_data is not None:
            if self.held_tile_data[3]:
                pygame.draw.rect(screen, pygame.Color("#FF6464"),
                                 self.held_tile_data[0], 1)

        self.ui_manager.draw_ui(screen)

        return running

    @staticmethod
    def is_inside_hud(pos, hud_rect):
        if hud_rect[0] <= pos[0] and hud_rect[1] <= pos[1]:
            if hud_rect[0] + hud_rect[2] > pos[
                    0] and hud_rect[1] + hud_rect[3] > pos[1]:
                return True
        return False

    def get_palette_tile_data_at_pos(self, click_pos):
        for tile in self.palette_tiles:
            x_min = tile.rect[0]
            x_max = tile.rect[0] + tile.rect[2]
            y_min = tile.rect[1]
            y_max = tile.rect[1] + tile.rect[3]
            if x_min <= click_pos[0] < x_max:
                if y_min <= click_pos[1] < y_max:
                    return [tile.rect, tile.image, tile.tile_id, True, None]
        return None

    def get_ai_spawn_data_at_pos(self, click_pos):
        for ai_spawn in self.palette_ai_spawns:
            x_min = ai_spawn.rect[0]
            x_max = ai_spawn.rect[0] + ai_spawn.rect[2]
            y_min = ai_spawn.rect[1]
            y_max = ai_spawn.rect[1] + ai_spawn.rect[3]
            if x_min <= click_pos[0] < x_max:
                if y_min <= click_pos[1] < y_max:
                    return ai_spawn
        return None
Пример #7
0
class OptionsUIApp:
    def __init__(self):
        pygame.init()
        pygame.display.set_caption("Options UI")
        self.options = Options()
        if self.options.fullscreen:
            self.window_surface = pygame.display.set_mode(
                self.options.resolution, pygame.FULLSCREEN)
        else:
            self.window_surface = pygame.display.set_mode(
                self.options.resolution)

        self.background_surface = None

        self.ui_manager = UIManager(
            self.options.resolution,
            PackageResource(package='data.themes', resource='theme_2.json'))
        self.ui_manager.preload_fonts([{
            'name': 'fira_code',
            'point_size': 10,
            'style': 'bold'
        }, {
            'name': 'fira_code',
            'point_size': 10,
            'style': 'regular'
        }, {
            'name': 'fira_code',
            'point_size': 10,
            'style': 'italic'
        }, {
            'name': 'fira_code',
            'point_size': 14,
            'style': 'italic'
        }, {
            'name': 'fira_code',
            'point_size': 14,
            'style': 'bold'
        }])

        self.test_button = None
        self.test_button_2 = None
        self.test_button_3 = None
        self.test_slider = None
        self.test_text_entry = None
        self.test_drop_down = None
        self.test_drop_down_2 = None
        self.panel = None
        self.fps_counter = None
        self.frame_timer = None
        self.disable_toggle = None
        self.hide_toggle = None

        self.message_window = None

        self.recreate_ui()

        self.clock = pygame.time.Clock()
        self.time_delta_stack = deque([])

        self.button_response_timer = pygame.time.Clock()
        self.running = True
        self.debug_mode = False

        self.all_enabled = True
        self.all_shown = True

    def recreate_ui(self):
        self.ui_manager.set_window_resolution(self.options.resolution)
        self.ui_manager.clear_and_reset()

        self.background_surface = pygame.Surface(self.options.resolution)
        self.background_surface.fill(
            self.ui_manager.get_theme().get_colour('dark_bg'))

        self.test_button = UIButton(
            pygame.Rect((int(self.options.resolution[0] / 2),
                         int(self.options.resolution[1] * 0.90)), (100, 40)),
            '',
            self.ui_manager,
            tool_tip_text="<font face=fira_code color=normal_text size=2>"
            "<b><u>Test Tool Tip</u></b>"
            "<br><br>"
            "A little <i>test</i> of the "
            "<font color=#FFFFFF><b>tool tip</b></font>"
            " functionality."
            "<br><br>"
            "Unleash the Kraken!"
            "</font>",
            object_id='#hover_me_button')

        self.test_button_2 = UIButton(pygame.Rect(
            (int(self.options.resolution[0] / 3),
             int(self.options.resolution[1] * 0.90)), (100, 40)),
                                      'EVERYTHING',
                                      self.ui_manager,
                                      object_id='#everything_button')

        self.test_button_3 = UIButton(pygame.Rect(
            (int(self.options.resolution[0] / 6),
             int(self.options.resolution[1] * 0.90)), (100, 40)),
                                      'Scaling?',
                                      self.ui_manager,
                                      object_id='#scaling_button')

        self.test_slider = UIHorizontalSlider(pygame.Rect(
            (int(self.options.resolution[0] / 2),
             int(self.options.resolution[1] * 0.70)), (240, 25)),
                                              25.0, (0.0, 100.0),
                                              self.ui_manager,
                                              object_id='#cool_slider')

        self.test_text_entry = UITextEntryLine(pygame.Rect(
            (int(self.options.resolution[0] / 2),
             int(self.options.resolution[1] * 0.50)), (200, -1)),
                                               self.ui_manager,
                                               object_id='#main_text_entry')

        current_resolution_string = (str(self.options.resolution[0]) + 'x' +
                                     str(self.options.resolution[1]))
        self.test_drop_down = UIDropDownMenu(
            ['640x480', '800x600', '1024x768'], current_resolution_string,
            pygame.Rect((int(self.options.resolution[0] / 2),
                         int(self.options.resolution[1] * 0.3)),
                        (200, 25)), self.ui_manager)

        self.test_drop_down_2 = UIDropDownMenu(
            ['Another', 'drop down', 'menu', 'testing', 'overlaps'], 'Another',
            pygame.Rect((int(self.options.resolution[0] / 2),
                         int(self.options.resolution[1] * 0.25)),
                        (200, 25)), self.ui_manager)

        self.panel = UIPanel(pygame.Rect(50, 50, 200, 300),
                             starting_layer_height=4,
                             manager=self.ui_manager)

        UIButton(pygame.Rect(10, 10, 174, 30),
                 'Panel Button',
                 manager=self.ui_manager,
                 container=self.panel)

        UISelectionList(pygame.Rect(10, 50, 174, 200),
                        item_list=[
                            'Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5',
                            'Item 6', 'Item 7', 'Item 8', 'Item 9', 'Item 10',
                            'Item 11', 'Item 12', 'Item 13', 'Item 14',
                            'Item 15', 'Item 16', 'Item 17', 'Item 18',
                            'Item 19', 'Item 20'
                        ],
                        manager=self.ui_manager,
                        container=self.panel,
                        allow_multi_select=True)

        self.fps_counter = UILabel(pygame.Rect(
            self.options.resolution[0] - 250, 20, 230, 44),
                                   "FPS: 0",
                                   self.ui_manager,
                                   object_id='#fps_counter')

        self.frame_timer = UILabel(pygame.Rect(
            self.options.resolution[0] - 250, 64, 230, 24),
                                   "Frame time: 0",
                                   self.ui_manager,
                                   object_id='#frame_timer')

        self.disable_toggle = UIButton(pygame.Rect(
            (int(self.options.resolution[0] * 0.85),
             int(self.options.resolution[1] * 0.90)), (100, 30)),
                                       'Disable',
                                       self.ui_manager,
                                       object_id='#disable_button')

        self.hide_toggle = UIButton(pygame.Rect(
            (int(self.options.resolution[0] * 0.85),
             int(self.options.resolution[1] * 0.85)), (100, 30)),
                                    'Hide',
                                    self.ui_manager,
                                    object_id='#hide_button')

    def create_message_window(self):
        self.button_response_timer.tick()
        self.message_window = UIMessageWindow(
            rect=pygame.Rect(
                (random.randint(0, self.options.resolution[0] - 300),
                 random.randint(0, self.options.resolution[1] - 200)),
                (300, 250)),
            window_title='Test Message Window',
            html_message='<font color=normal_text>'
            'This is a <a href="test">test</a> message to see if '
            'this box <a href=actually_link>actually</a> works.'
            ''
            'In <i>bibendum</i> orci et velit</b> gravida lacinia.<br><br><br> '
            'In hac a habitasse to platea dictumst.<br>'
            ' <font color=#4CD656 size=4>Vivamus I interdum mollis lacus nec '
            'porttitor.<br> Morbi'
            ' accumsan, lectus at'
            ' tincidunt to dictum, neque <font color=#879AF6>erat tristique'
            ' blob</font>,'
            ' sed a tempus for <b>nunc</b> dolor in nibh.<br>'
            ' Suspendisse in viverra dui <i>fringilla dolor laoreet</i>, sit amet '
            'on pharetra a ante'
            ' sollicitudin.</font>'
            '<br><br>'
            'In <i>bibendum</i> orci et velit</b> gravida lacinia.<br><br><br> '
            'In hac a habitasse to platea dictumst.<br>'
            ' <font color=#4CD656 size=4>Vivamus I interdum mollis lacus nec '
            'porttitor.<br> Morbi'
            ' accumsan, lectus at'
            ' tincidunt to dictum, neque <font color=#879AF6>erat tristique '
            'erat</font>,'
            ' sed a tempus for <b>nunc</b> dolor in nibh.<br>'
            ' Suspendisse in viverra dui <i>fringilla dolor laoreet</i>, sit amet '
            'on pharetra a ante'
            ' sollicitudin.</font>'
            '<br><br>'
            'In <i>bibendum</i> orci et velit</b> gravida lacinia.<br><br><br> '
            'In hac a habitasse to platea dictumst.<br>'
            ' <font color=#4CD656 size=4>Vivamus I interdum mollis lacus nec '
            'porttitor.<br> Morbi'
            ' accumsan, lectus at'
            ' tincidunt to dictum, neque <font color=#879AF6>erat tristique '
            'erat</font>,'
            ' sed a tempus for <b>nunc</b> dolor in nibh.<br>'
            ' Suspendisse in viverra dui <i>fringilla dolor laoreet</i>, '
            'sit amet on pharetra a ante'
            ' sollicitudin.</font>'
            '</font>',
            manager=self.ui_manager)
        time_taken = self.button_response_timer.tick() / 1000.0
        # currently taking about 0.35 seconds down from 0.55 to create
        # an elaborately themed message window.
        # still feels a little slow but it's better than it was.
        print("Time taken to create message window: " + str(time_taken))

    def check_resolution_changed(self):
        resolution_string = self.test_drop_down.selected_option.split('x')
        resolution_width = int(resolution_string[0])
        resolution_height = int(resolution_string[1])
        if (resolution_width != self.options.resolution[0]
                or resolution_height != self.options.resolution[1]):
            self.options.resolution = (resolution_width, resolution_height)
            self.window_surface = pygame.display.set_mode(
                self.options.resolution)
            self.recreate_ui()

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

            self.ui_manager.process_events(event)

            if event.type == pygame.KEYDOWN and event.key == pygame.K_d:
                self.debug_mode = False if self.debug_mode else True
                self.ui_manager.set_visual_debug_mode(self.debug_mode)

            if event.type == pygame.KEYDOWN and event.key == pygame.K_f:
                print("self.ui_manager.focused_set:",
                      self.ui_manager.focused_set)

            if event.type == pygame.USEREVENT:
                if (event.user_type == pygame_gui.UI_TEXT_ENTRY_FINISHED
                        and event.ui_object_id == '#main_text_entry'):
                    print(event.text)

                if event.user_type == pygame_gui.UI_TEXT_BOX_LINK_CLICKED:
                    if event.link_target == 'test':
                        print("clicked test link")
                    elif event.link_target == 'actually_link':
                        print("clicked actually link")

                if event.user_type == pygame_gui.UI_BUTTON_PRESSED:
                    if event.ui_element == self.test_button:
                        self.test_button.set_text(
                            random.choice(
                                ['', 'Hover me!', 'Click this.', 'A Button']))
                        self.create_message_window()

                    if event.ui_element == self.test_button_3:
                        ScalingWindow(pygame.Rect((50, 50), (224, 224)),
                                      self.ui_manager)
                    if event.ui_element == self.test_button_2:
                        EverythingWindow(pygame.Rect((10, 10), (640, 480)),
                                         self.ui_manager)

                    if event.ui_element == self.disable_toggle:
                        if self.all_enabled:
                            self.disable_toggle.set_text('Enable')
                            self.all_enabled = False
                            self.ui_manager.root_container.disable()
                            self.disable_toggle.enable()
                        else:
                            self.disable_toggle.set_text('Disable')
                            self.all_enabled = True
                            self.ui_manager.root_container.enable()

                    if event.ui_element == self.hide_toggle:
                        if self.all_shown:
                            self.hide_toggle.set_text('Show')
                            self.all_shown = False
                            self.ui_manager.root_container.hide()
                            self.hide_toggle.show()
                        else:
                            self.hide_toggle.set_text('Hide')
                            self.all_shown = True
                            self.ui_manager.root_container.show()

                if (event.user_type == pygame_gui.UI_DROP_DOWN_MENU_CHANGED
                        and event.ui_element == self.test_drop_down):
                    self.check_resolution_changed()

    def run(self):
        while self.running:
            time_delta = self.clock.tick() / 1000.0
            self.time_delta_stack.append(time_delta)
            if len(self.time_delta_stack) > 2000:
                self.time_delta_stack.popleft()

            # check for input
            self.process_events()

            # respond to input
            self.ui_manager.update(time_delta)

            if len(self.time_delta_stack) == 2000:
                self.fps_counter.set_text(
                    f'FPS: {min(999.0, 1.0/max(sum(self.time_delta_stack)/2000.0, 0.0000001)):.2f}'
                )
                self.frame_timer.set_text(
                    f'frame_time: {sum(self.time_delta_stack)/2000.0:.4f}')

            # draw graphics
            self.window_surface.blit(self.background_surface, (0, 0))
            self.ui_manager.draw_ui(self.window_surface)

            pygame.display.update()
Пример #8
0
class Game:
    def __init__(self, session):
        self.manager = UIManager((800, 600), 'themes/game.json')
        image = pygame.image.load('assets/background.png')

        self.background = UIImage(relative_rect=pygame.Rect(0, 0, 800, 600),
                                  manager=self.manager,
                                  image_surface=image)

        self.session = session
        self.allPlayers = pygame.sprite.Group()
        self.player = Perso(self, self.session)
        self.allPlayers.add(self.player)
        self.pressed = {}
        self.allEnemy = pygame.sprite.Group()
        self.addScore = 100
        self.score = 0
        self.level = Niveau(self, self.score)

        self.panelTop = UIPanel(relative_rect=pygame.Rect(0, 0, 800, 20),
                                starting_layer_height=2,
                                manager=self.manager,
                                object_id="#panel-top")

        self.labelHealthTitle = UILabel(relative_rect=pygame.Rect(
            0, 0, 50, 20),
                                        text="Vie :",
                                        manager=self.manager,
                                        object_id="#label-score",
                                        container=self.panelTop)

        self.labelHealth = UILabel(relative_rect=pygame.Rect(30, 0, 50, 20),
                                   text=str(self.player.health),
                                   manager=self.manager,
                                   object_id="#label-score",
                                   container=self.panelTop)

        self.labelAsset = UILabel(relative_rect=pygame.Rect(
            800 - 100, 0, 50, 20),
                                  text=str(self.level.assetIsActive[2]),
                                  manager=self.manager,
                                  object_id="#label-score",
                                  container=self.panelTop)

        self.labelScore = UILabel(relative_rect=pygame.Rect(
            0, 600 - 50, 200, 50),
                                  text=str(self.score),
                                  manager=self.manager,
                                  object_id="#label-score")

        self.playerImage = UIImage(relative_rect=pygame.Rect(
            (self.player.rect.x, self.player.rect.y), (50, 50)),
                                   manager=self.manager,
                                   image_surface=self.player.image)

        self.panel = UIPanel(relative_rect=pygame.Rect((0, 0), (0, 0)),
                             starting_layer_height=3,
                             manager=self.manager,
                             object_id="#panel-game-over")

        self.labelGameOver = UILabel(relative_rect=pygame.Rect(
            400 - 100, 300 - 50, 200, 50),
                                     text="Game Over",
                                     manager=self.manager,
                                     object_id="#label-game-over",
                                     container=self.panel)

        self.buttonMenu = UIButton(relative_rect=pygame.Rect(
            400 - 100, 300 + 50, 200, 50),
                                   text='Quitter',
                                   manager=self.manager,
                                   container=self.panel)

        self.buttonParty = UIButton(relative_rect=pygame.Rect(
            (400 - 100, 300 + 50 + 80), (200, 50)),
                                    text='Recommencer',
                                    manager=self.manager,
                                    container=self.panel)

        self.panelPause = UIPanel(relative_rect=pygame.Rect((0, 0), (0, 0)),
                                  starting_layer_height=3,
                                  manager=self.manager,
                                  object_id="#panel-game-over")

        self.labelPause = UILabel(relative_rect=pygame.Rect(
            400 - 100, 300 - 50, 200, 50),
                                  text="Pause",
                                  manager=self.manager,
                                  object_id="#label-game-over",
                                  container=self.panelPause)

        self.buttonSave = UIButton(relative_rect=pygame.Rect(
            400 - 100, 300 + 50, 200, 50),
                                   text='Sauvegarder et quitter',
                                   manager=self.manager,
                                   container=self.panelPause)

        self.buttonQuit = UIButton(relative_rect=pygame.Rect(
            (400 - 100, 300 + 50 + 80), (200, 50)),
                                   text='Quitter',
                                   manager=self.manager,
                                   container=self.panelPause)

        self.panelAsset = UIPanel(relative_rect=pygame.Rect((0, 0), (0, 0)),
                                  starting_layer_height=3,
                                  manager=self.manager,
                                  object_id="#panel-game-over")

        self.labelEquipment = UILabel(relative_rect=pygame.Rect(
            400 - 100, 50, 200, 50),
                                      text="Pause",
                                      manager=self.manager,
                                      object_id="#label-game-over",
                                      container=self.panelAsset)

        self.button1 = UIButton(relative_rect=pygame.Rect(
            400 - 100, 50 + 50, 200, 50),
                                text="Double l'attaque 10C",
                                manager=self.manager,
                                container=self.panelAsset)

        self.button2 = UIButton(relative_rect=pygame.Rect(
            (400 - 100, 120 + 50), (200, 50)),
                                text='3 Missiles 100C',
                                manager=self.manager,
                                container=self.panelAsset)

        self.button3 = UIButton(relative_rect=pygame.Rect(
            (400 - 100, 190 + 50), (200, 50)),
                                text='Double Score 20C',
                                manager=self.manager,
                                container=self.panelAsset)

        self.button4 = UIButton(relative_rect=pygame.Rect(
            (400 - 100, 260 + 50), (200, 50)),
                                text="Temps d'apparition 50C",
                                manager=self.manager,
                                container=self.panelAsset)

        self.labelCredit = UILabel(relative_rect=pygame.Rect(
            400 - 100, 330 + 50, 200, 50),
                                   text=str(self.player.credit),
                                   manager=self.manager,
                                   object_id="#label-game-over",
                                   container=self.panelAsset)

        self.pause = True

    def menuGameOver(self):
        self.panel.set_dimensions((800, 600))

    def setLabelHealth(self):
        self.labelHealth.set_text(str(self.player.health))

    def setLabelScore(self):
        self.labelScore.set_text(str(self.score))

    def setLabelAsset(self):
        self.labelAsset.set_text(str(self.level.assetIsActive[2]))

    def setLabelCredit(self):
        self.player.credit += 1
        self.labelCredit.set_text(str(self.player.credit))

    def getManager(self):
        return self.manager

    def updatePosPlayer(self):
        self.playerImage.set_relative_position(
            (self.player.rect.x, self.player.rect.y))

    def getPause(self):
        return self.pause

    def getEvent(self, event):
        if not self.player.isDead():
            if event.type == pygame.USEREVENT:
                if event.user_type == pygame_gui.UI_BUTTON_PRESSED:
                    if event.ui_element == self.buttonQuit:
                        pygame.quit()
                    elif event.ui_element == self.buttonSave:
                        self.session.setCredit(self.player.credit)
                        self.session.setScore(self.score)
                        pygame.quit()

                    elif event.ui_element == self.button1:
                        if self.player.credit >= 10 and self.level.assetIsActive[
                                0] == False:
                            self.player.credit -= 10
                            self.player.getSurprise("damage")

                            self.panelAsset.set_dimensions((0, 0))

                            self.pause = True
                    elif event.ui_element == self.button2:
                        if self.player.credit >= 100 and self.level.assetIsActive[
                                0] == False:
                            self.player.credit -= 100
                            self.player.getSurprise("attack")

                            self.panelAsset.set_dimensions((0, 0))
                            self.pause = True
                    elif event.ui_element == self.button3:
                        if self.player.credit >= 20 and self.level.assetIsActive[
                                0] == False:
                            self.player.credit -= 20
                            self.player.getSurprise("score")

                            self.panelAsset.set_dimensions((0, 0))
                            self.pause = True
                    elif event.ui_element == self.button4:
                        if self.player.credit >= 50 and self.level.assetIsActive[
                                0] == False:
                            self.player.credit -= 50
                            self.player.getSurprise("reload")

                            self.panelAsset.set_dimensions((0, 0))
                            self.pause = True

            if event.type == KEYDOWN:
                if event.key == pygame.K_ESCAPE:

                    if self.pause:
                        self.panelPause.set_dimensions((800, 600))
                        self.pause = False

                    else:
                        self.panelPause.set_dimensions((0, 0))
                        self.pause = True

                    return self.pause

                if event.key == pygame.K_RETURN:

                    if self.pause:
                        self.panelAsset.set_dimensions((800, 600))
                        self.pause = False

                    else:
                        self.panelAsset.set_dimensions((0, 0))
                        self.pause = True

                    return self.pause

                if event.key == pygame.K_SPACE:
                    self.player.attack(self.manager)

                self.pressed[event.key] = True
            elif event.type == KEYUP:
                self.pressed[event.key] = False
            return None
        else:
            if event.type == pygame.USEREVENT:
                if event.user_type == pygame_gui.UI_BUTTON_PRESSED:
                    if event.ui_element == self.buttonParty:
                        return "restart"
                    elif event.ui_element == self.buttonMenu:
                        pygame.quit()

    def updatePosEnemy(self, enemy, x, y):
        enemy.ennemyImage.set_relative_position((x, y))

    def spawnEnemy(self, health, x, asset):
        enemy = Enemy(health, self.manager, x, self, asset)
        self.updatePosEnemy(enemy, enemy.rect.x, enemy.rect.y)
        self.allEnemy.add(enemy)

    def checkColision(self, sprite, group):
        return pygame.sprite.spritecollide(sprite, group, False,
                                           pygame.sprite.collide_mask)

    def run(self):
        self.level.generate()
        self.level.setScore(self.score)
Пример #9
0
class HUDPanel(UIWindow):
    def __init__(self, rect: pygame.Rect,
                 manager: 'pygame_gui.ui_manager.UIManager',
                 player_resources: PlayerResources, turret_costs: TurretCosts):
        super().__init__(rect, manager, 'hud_panel')
        self.player_resources = player_resources
        self.turret_costs = turret_costs

        # create top edge shadow
        top_edge_shadow_size = 4
        border_size = 1
        background_surface = pygame.Surface(
            (self.rect.width, self.rect.height - top_edge_shadow_size))
        background_surface.fill(pygame.Color("#808080"))
        background_surface.fill(
            pygame.Color("#646464"),
            pygame.Rect(
                (border_size, border_size),
                (self.rect.width - (border_size * 2), self.rect.height -
                 (border_size * 2) - top_edge_shadow_size)))
        shadow = self.ui_manager.get_shadow(
            (self.rect.width + 48, self.rect.height))
        self.image = pygame.Surface(self.rect.size, flags=pygame.SRCALPHA)
        self.image.blit(shadow, (0, 0),
                        area=pygame.Rect((24, 0), self.rect.size))
        self.image.blit(background_surface, (0, top_edge_shadow_size))

        self.get_container().relative_rect.width = self.rect.width
        self.get_container(
        ).relative_rect.height = self.rect.height - top_edge_shadow_size
        self.get_container().relative_rect.x = self.get_container(
        ).relative_rect.x
        self.get_container().relative_rect.y = self.get_container(
        ).relative_rect.y + top_edge_shadow_size
        self.get_container().update_containing_rect_position()

        self.health_label = UILabel(
            pygame.Rect((900, 30), (100, 40)),
            "Health: " +
            "{:,}".format(self.player_resources.current_base_health),
            manager=self.ui_manager,
            container=self.get_container(),
            object_id="#screen_text")

        self.cash_label = UILabel(
            pygame.Rect((900, 60), (100, 40)),
            "£" + "{:,}".format(self.player_resources.current_cash),
            manager=self.ui_manager,
            container=self.get_container(),
            object_id="#screen_text")

        self.clearable_hud_elements = []

    def update(self, time_delta: float):
        self.cash_label.set_text(
            "£" + "{:,}".format(self.player_resources.current_cash))
        self.health_label.set_text(
            "Health: " +
            "{:,}".format(self.player_resources.current_base_health))

    def display_normal_hud(self):

        for element in self.clearable_hud_elements:
            element.kill()

        self.clearable_hud_elements.clear()

        self.clearable_hud_elements.append(
            UIButton(
                pygame.Rect(32, 32, 66, 66),
                "",
                manager=self.ui_manager,
                container=self.get_container(),
                object_id="#gun_turret_button",
                tool_tip_text="<font size=2><b>Gun Turret</b><br><br>"
                "A turret that fires a pair of low damage bullets at enemies in range. Has a"
                " fairly rapid rate of fire.</font>"))
        self.clearable_hud_elements.append(
            UIButton(
                pygame.Rect(128, 32, 66, 66),
                "",
                manager=self.ui_manager,
                container=self.get_container(),
                object_id="#missile_turret_button",
                tool_tip_text="<font size=2><b>Missile Turret</b><br><br>"
                "A slow firing, large range turret that launches homing missiles. Missiles do high "
                "damage.</font>"))
        self.clearable_hud_elements.append(
            UIButton(
                pygame.Rect(224, 32, 66, 66),
                "",
                manager=self.ui_manager,
                container=self.get_container(),
                object_id="#flame_turret_button",
                tool_tip_text="<font size=2><b>Flame Turret</b><br><br>"
                "Short range turret that fires a continuous cone of flame."
                " The flames do damage while an enemy is within the cone. "
                "Works well when enemies have to walk directly at the "
                "turret.</font>"))
        self.clearable_hud_elements.append(
            UIButton(
                pygame.Rect(320, 32, 66, 66),
                "",
                manager=self.ui_manager,
                container=self.get_container(),
                object_id="#slow_turret_button",
                tool_tip_text="<font size=2><b>Slow Turret</b><br><br>"
                "This turret uses time warping fields to slow down"
                " all enemies within its radius. Works "
                "well to multiply the damage done by nearby turrets.</font>"))
        self.clearable_hud_elements.append(
            UIButton(
                pygame.Rect(416, 32, 66, 66),
                "",
                manager=self.ui_manager,
                container=self.get_container(),
                object_id="#laser_turret_button",
                tool_tip_text="<font size=2><b>Laser Turret</b><br><br>"
                "This turret fires a continuous laser beam at a single target."
                " Useful for dealing with armoured targets that resist other "
                "types of damage.</font>"))
        self.clearable_hud_elements.append(
            UILabel(pygame.Rect((32, 96), (64, 32)),
                    "£ " + str(self.turret_costs.gun),
                    manager=self.ui_manager,
                    container=self.get_container(),
                    object_id="#small_screen_text"))
        self.clearable_hud_elements.append(
            UILabel(pygame.Rect((128, 96), (64, 32)),
                    "£ " + str(self.turret_costs.missile),
                    manager=self.ui_manager,
                    container=self.get_container(),
                    object_id="#small_screen_text"))
        self.clearable_hud_elements.append(
            UILabel(pygame.Rect((224, 96), (64, 32)),
                    "£ " + str(self.turret_costs.flamer),
                    manager=self.ui_manager,
                    container=self.get_container(),
                    object_id="#small_screen_text"))
        self.clearable_hud_elements.append(
            UILabel(pygame.Rect((320, 96), (64, 32)),
                    "£ " + str(self.turret_costs.slow),
                    manager=self.ui_manager,
                    container=self.get_container(),
                    object_id="#small_screen_text"))
        self.clearable_hud_elements.append(
            UILabel(pygame.Rect((416, 96), (64, 32)),
                    "£ " + str(self.turret_costs.laser),
                    manager=self.ui_manager,
                    container=self.get_container(),
                    object_id="#small_screen_text"))

    def display_upgrade_hud(self, upgrade_turret):

        for element in self.clearable_hud_elements:
            element.kill()

        self.clearable_hud_elements.clear()

        self.clearable_hud_elements.append(
            UIButton(pygame.Rect(32, 32, 66, 66),
                     "",
                     manager=self.ui_manager,
                     container=self.get_container(),
                     object_id="#upgrade_button",
                     tool_tip_text="<font size=2><b>Upgrade Turret</b><br><br>"
                     "Upgrades the selected turret to the next level."
                     " Turrets have three levels.</font>"))
        self.clearable_hud_elements.append(
            UIButton(
                pygame.Rect(128, 32, 66, 66),
                "",
                manager=self.ui_manager,
                container=self.get_container(),
                object_id="#sell_button",
                tool_tip_text="<font size=2><b>Sell Turret</b><br><br>"
                "Sells the selected turret for half of the cost of building it.</font>"
            ))
        self.clearable_hud_elements.append(
            UILabel(pygame.Rect((32, 96), (64, 32)),
                    "£ " + str(upgrade_turret.get_upgrade_cost()),
                    manager=self.ui_manager,
                    container=self.get_container(),
                    object_id="#small_screen_text"))
        self.clearable_hud_elements.append(
            UILabel(pygame.Rect((128, 96), (64, 32)),
                    "£ " + str(upgrade_turret.get_sell_value()),
                    manager=self.ui_manager,
                    container=self.get_container(),
                    object_id="#small_screen_text"))
Пример #10
0
class GameState(BaseAppState):
    def __init__(self, ui_manager: pygame_gui.UIManager, screen_surface,
                 screen_data, state_manger):
        super().__init__('game', 'main_menu', state_manger)

        self.ui_manager = ui_manager
        self.screen_surface = screen_surface
        self.screen_data = screen_data

        self.background = None

        self.level_to_load_path = None
        self.level_to_load = None

        # objects that do stuff
        self.collision_grid = None
        self.tiled_level = None
        self.monster_wave_spawner = None
        self.splat_loader = None
        self.player_resources = None

        self.should_redraw_static_sprites = False

        # game sub state booleans
        self.is_play_game = False
        self.restart_game = False
        self.is_setup = False
        self.is_game_over = False
        self.should_show_count_down_message = False
        self.upgrade_hud_active = False

        self.hud_panel = None

        # labels
        self.fps_counter_label = None
        self.wave_display_label = None
        self.count_down_message_label = None
        self.health_label = None
        self.cash_label = None
        self.win_message_label = None
        self.play_again_message_label = None

        self.frame_rates = deque([])

        # turrets
        self.active_upgrade_turret = None
        self.mouse_active_turret = None

        # lists of things
        self.explosions = []
        self.new_explosions = []
        self.bullets = []
        self.turrets = []
        self.monsters = []
        self.hud_buttons = []

        # sprite groups
        self.static_sprite_surface = None
        self.all_tile_sprites = None
        self.all_square_sprites = None
        self.all_monster_sprites = None
        self.all_turret_sprites = None
        self.all_bullet_sprites = None
        self.all_explosion_sprites = None
        self.splat_sprites = None

        # images
        self.explosions_sprite_sheet = None
        self.image_atlas = None

        self.turret_costs = TurretCosts()

        self.count_down_message = ""
        self.win_message = ""

        # timer
        self.setup_time = 10.0
        self.setup_accumulator = 0.0

        self.hud_rect = None

    def start(self):
        self.hud_rect = pygame.Rect(0, self.screen_data.screen_size[1] - 128,
                                    self.screen_data.screen_size[0], 128)

        self.player_resources = PlayerResources()

        self.background = pygame.Surface(self.screen_surface.get_size())
        self.background = self.background.convert(self.screen_surface)
        self.background.fill((95, 140, 95))

        self.should_redraw_static_sprites = True
        self.static_sprite_surface = pygame.Surface(
            self.screen_surface.get_size())
        self.all_tile_sprites = pygame.sprite.Group()
        self.all_square_sprites = pygame.sprite.Group()
        self.all_monster_sprites = pygame.sprite.Group()
        self.all_turret_sprites = pygame.sprite.Group()
        self.all_bullet_sprites = pygame.sprite.Group()
        self.all_explosion_sprites = pygame.sprite.Group()
        self.splat_sprites = pygame.sprite.Group()

        self.explosions_sprite_sheet = pygame.image.load(
            "images/explosions.png").convert_alpha()
        self.image_atlas = pygame.image.load(
            "images/image_atlas.png").convert_alpha()
        self.splat_loader = SplatLoader()

        self.level_to_load_path = self.incoming_transition_data[
            'selected_level_path']

        self.fps_counter_label = UILabel(pygame.Rect((900, 10), (100, 40)),
                                         "0 FPS",
                                         manager=self.ui_manager,
                                         object_id="#screen_text")

        self.wave_display_label = None

        grid_size = 64
        screen_filling_number_of_grid_squares = [
            int(self.screen_data.screen_size[0] / grid_size),
            int(self.screen_data.screen_size[1] / grid_size)
        ]
        self.collision_grid = CollisionGrid(
            screen_filling_number_of_grid_squares, grid_size)

        # clear level
        self.tiled_level = TiledLevel(
            self.level_to_load_path, [40, 21], self.all_tile_sprites,
            self.all_monster_sprites, self.all_square_sprites,
            self.image_atlas, self.monsters, self.screen_data,
            self.explosions_sprite_sheet)
        self.tiled_level.load_tiles()
        self.tiled_level.update_offset_position(
            self.tiled_level.find_player_start(), self.all_tile_sprites)
        self.monster_wave_spawner = MonsterWaveSpawner(
            self.monsters, self.tiled_level.monster_walk_path, 10,
            self.all_monster_sprites, self.image_atlas, self.collision_grid,
            self.splat_loader, self.ui_manager)

        self.is_play_game = True
        self.restart_game = True
        self.should_redraw_static_sprites = True

        self.hud_panel = HUDPanel(self.hud_rect, self.ui_manager,
                                  self.player_resources, self.turret_costs)

    def end(self):
        if self.fps_counter_label is not None:
            self.fps_counter_label.kill()
            self.fps_counter_label = None

        if self.count_down_message_label is not None:
            self.count_down_message_label.kill()
            self.count_down_message_label = None

        if self.wave_display_label is not None:
            self.wave_display_label.kill()
            self.wave_display_label = None

        if self.hud_panel is not None:
            self.hud_panel.kill()
            self.hud_panel = None

        if self.win_message_label is not None:
            self.win_message_label.kill()
            self.win_message_label = None

        if self.play_again_message_label is not None:
            self.play_again_message_label.kill()
            self.play_again_message_label = None

        for sprite in self.all_monster_sprites.sprites():
            sprite.kill()

        self.all_monster_sprites.empty()
        self.all_turret_sprites.empty()
        self.all_bullet_sprites.empty()
        self.all_explosion_sprites.empty()

    def run(self, surface, time_delta):

        if not self.restart_game and self.is_setup:
            if self.setup_accumulator >= self.setup_time:
                self.is_setup = False
                self.setup_accumulator = 0.0
            elif self.setup_accumulator >= (self.setup_time - 6.0):
                seconds_string = str(
                    int(self.setup_time - self.setup_accumulator))
                self.count_down_message = "First wave in " + seconds_string + " seconds"
                self.should_show_count_down_message = True
                self.setup_accumulator += time_delta

                if self.count_down_message_label is None:
                    count_down_message_label_rect = pygame.Rect((400, 10),
                                                                (250, 40))
                    count_down_message_label_rect.centerx = self.screen_data.screen_size[
                        0] / 2
                    count_down_message_label_rect.centery = 24
                    self.count_down_message_label = UILabel(
                        count_down_message_label_rect,
                        self.count_down_message,
                        manager=self.ui_manager,
                        object_id="#screen_text")
            else:
                self.setup_accumulator += time_delta
                remaining_time = str(
                    int(self.setup_time - self.setup_accumulator))
                self.count_down_message = "Setup Time remaining: " + remaining_time + " seconds"
                self.should_show_count_down_message = True

                if self.count_down_message_label is None:
                    count_down_message_label_rect = pygame.Rect((400, 10),
                                                                (250, 40))
                    count_down_message_label_rect.centerx = self.screen_data.screen_size[
                        0] / 2
                    count_down_message_label_rect.centery = 24
                    self.count_down_message_label = UILabel(
                        count_down_message_label_rect,
                        self.count_down_message,
                        manager=self.ui_manager,
                        object_id="#screen_text")
        elif self.restart_game:
            self.restart_game = False

            # clear all stuff
            self.explosions[:] = []
            self.new_explosions[:] = []
            self.bullets[:] = []
            self.turrets[:] = []
            self.monsters[:] = []
            self.hud_buttons[:] = []

            self.all_monster_sprites.empty()
            self.all_turret_sprites.empty()
            self.all_bullet_sprites.empty()
            self.all_explosion_sprites.empty()

            self.tiled_level.reset_squares()

            # reset player resources
            self.player_resources = PlayerResources()
            self.hud_panel.player_resources = self.player_resources

            self.is_game_over = False
            self.is_setup = True
            self.setup_accumulator = 0.0
            self.monster_wave_spawner = MonsterWaveSpawner(
                self.monsters, self.tiled_level.monster_walk_path, 10,
                self.all_monster_sprites, self.image_atlas,
                self.collision_grid, self.splat_loader, self.ui_manager)
            self.mouse_active_turret = None
            self.active_upgrade_turret = None
            self.upgrade_hud_active = False
            self.should_show_count_down_message = False
            if self.count_down_message_label is not None:
                self.count_down_message_label.kill()
                self.count_down_message_label = None

            if self.wave_display_label is not None:
                self.wave_display_label.kill()
                self.wave_display_label = None

            if self.win_message_label is not None:
                self.win_message_label.kill()
                self.win_message_label = None

            if self.play_again_message_label is not None:
                self.play_again_message_label.kill()
                self.play_again_message_label = None

            self.hud_panel.display_normal_hud()

        elif self.is_game_over:
            self.should_show_count_down_message = False
            if self.count_down_message_label is not None:
                self.count_down_message_label.kill()
                self.count_down_message_label = None
        else:
            self.monster_wave_spawner.update(time_delta,
                                             self.tiled_level.position_offset)
            if self.wave_display_label is not None:
                self.wave_display_label.kill()
                self.wave_display_label = None

            if self.monster_wave_spawner.should_show_wave_countdown:
                self.should_show_count_down_message = True
                self.count_down_message = self.monster_wave_spawner.count_down_message

                if self.count_down_message_label is None:
                    count_down_message_label_rect = pygame.Rect((400, 10),
                                                                (250, 40))
                    count_down_message_label_rect.centerx = self.screen_data.screen_size[
                        0] / 2
                    count_down_message_label_rect.centery = 24
                    self.count_down_message_label = UILabel(
                        count_down_message_label_rect,
                        self.count_down_message,
                        manager=self.ui_manager,
                        object_id="#screen_text")
            else:
                self.should_show_count_down_message = False
                if self.count_down_message_label is not None:
                    self.count_down_message_label.kill()
                    self.count_down_message_label = None

                if self.wave_display_label is None:
                    current_wave = str(
                        self.monster_wave_spawner.current_wave_number)
                    max_wave = str(
                        self.monster_wave_spawner.maximum_wave_number)
                    wave_display_label_rect = pygame.Rect((400, 10), (100, 40))
                    wave_display_label_rect.centerx = self.screen_data.screen_size[
                        0] / 2
                    wave_display_label_rect.centery = 24
                    self.wave_display_label = UILabel(wave_display_label_rect,
                                                      "Wave " + current_wave +
                                                      "/" + max_wave,
                                                      manager=self.ui_manager,
                                                      object_id="#screen_text")

        if not self.is_game_over and self.player_resources.current_base_health <= 0:
            self.is_game_over = True
            self.win_message = "You have been defeated!"
            self.win_message_label = UILabel(pygame.Rect((347, 200),
                                                         (330, 70)),
                                             self.win_message,
                                             manager=self.ui_manager,
                                             object_id="#win_message_text")

            self.play_again_message_label = UILabel(
                pygame.Rect((362, 250), (300, 70)),
                "Play Again? Press 'Y' to restart",
                manager=self.ui_manager,
                object_id="#screen_text")

        on_final_wave = self.monster_wave_spawner.current_wave_number == self.monster_wave_spawner.maximum_wave_number
        if not self.is_game_over and on_final_wave and len(self.monsters) == 0:
            self.is_game_over = True
            self.win_message = "You are victorious!"
            self.win_message_label = UILabel(pygame.Rect((347, 200),
                                                         (330, 70)),
                                             self.win_message,
                                             manager=self.ui_manager,
                                             object_id="#win_message_text")

            self.play_again_message_label = UILabel(
                pygame.Rect((362, 250), (300, 70)),
                "Play Again? Press 'Y' to restart",
                manager=self.ui_manager,
                object_id="#screen_text")

        self.all_turret_sprites.empty()
        self.all_bullet_sprites.empty()
        self.all_explosion_sprites.empty()

        # handle UI and inout events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.trigger_transition()

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.trigger_transition()
                if event.key == pygame.K_g:
                    self.monster_wave_spawner.wave_points = 1000
                    self.monster_wave_spawner.wave_time_accumulator = 5.0
                if event.key == pygame.K_y:
                    if self.is_game_over:
                        self.restart_game = True

            self.ui_manager.process_events(event)

            if event.type == pygame.USEREVENT:
                if event.user_type == "ui_button_pressed":
                    if event.ui_object_id == "#gun_turret_button":
                        if self.turret_costs.gun <= self.player_resources.current_cash:
                            new_turret = GunTurret(
                                pygame.mouse.get_pos(), self.turret_costs.gun,
                                self.explosions_sprite_sheet, self.image_atlas,
                                self.collision_grid)
                            self.mouse_active_turret = new_turret
                            self.turrets.append(new_turret)
                    elif event.ui_object_id == "#flame_turret_button":
                        if self.turret_costs.flamer <= self.player_resources.current_cash:
                            new_turret = FlameTurret(
                                pygame.mouse.get_pos(),
                                self.turret_costs.flamer,
                                self.explosions_sprite_sheet, self.image_atlas,
                                self.collision_grid)
                            self.mouse_active_turret = new_turret
                            self.turrets.append(new_turret)
                    elif event.ui_object_id == "#missile_turret_button":
                        if self.turret_costs.missile <= self.player_resources.current_cash:
                            new_turret = MissileTurret(
                                pygame.mouse.get_pos(),
                                self.turret_costs.missile,
                                self.explosions_sprite_sheet, self.image_atlas,
                                self.collision_grid)
                            self.mouse_active_turret = new_turret
                            self.turrets.append(new_turret)
                    elif event.ui_object_id == "#slow_turret_button":
                        if self.turret_costs.slow <= self.player_resources.current_cash:
                            new_turret = SlowTurret(pygame.mouse.get_pos(),
                                                    self.turret_costs.slow,
                                                    self.image_atlas)
                            self.mouse_active_turret = new_turret
                            self.turrets.append(new_turret)
                    elif event.ui_object_id == "#laser_turret_button":
                        if self.turret_costs.laser <= self.player_resources.current_cash:
                            new_turret = LaserTurret(pygame.mouse.get_pos(),
                                                     self.turret_costs.laser,
                                                     self.image_atlas)
                            self.mouse_active_turret = new_turret
                            self.turrets.append(new_turret)
                    elif event.ui_object_id == "#upgrade_button":
                        if self.active_upgrade_turret is not None:
                            if self.player_resources.current_cash >= self.active_upgrade_turret.get_upgrade_cost(
                            ):
                                self.player_resources.current_cash -= self.active_upgrade_turret.get_upgrade_cost(
                                )
                                self.active_upgrade_turret.upgrade()
                                self.upgrade_hud_active = False
                                self.active_upgrade_turret = None
                                self.hud_panel.display_normal_hud()
                    elif event.ui_object_id == "#sell_button":
                        if self.active_upgrade_turret is not None:
                            self.player_resources.current_cash += self.active_upgrade_turret.get_sell_value(
                            )
                            for square in self.tiled_level.turret_squares:
                                if square.rect.collidepoint(
                                        self.active_upgrade_turret.position):
                                    square.occupied = False
                            self.turrets.remove(self.active_upgrade_turret)
                            self.upgrade_hud_active = False
                            self.active_upgrade_turret = None
                            self.hud_panel.display_normal_hud()

            if not self.is_game_over and event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 3:
                    if self.mouse_active_turret is not None:
                        self.turrets[:] = [
                            turret for turret in self.turrets
                            if turret is not self.mouse_active_turret
                        ]
                        self.mouse_active_turret = None
                    if self.upgrade_hud_active:
                        self.upgrade_hud_active = False
                        self.hud_panel.display_normal_hud()
                if event.button == 1:
                    if self.mouse_active_turret is not None:
                        placed_turret = False
                        for square in self.tiled_level.turret_squares:
                            if self.mouse_active_turret is not None:
                                if square.rect.collidepoint(
                                        pygame.mouse.get_pos(
                                        )) and not square.occupied:
                                    self.mouse_active_turret.set_position(
                                        square.position)
                                    placed_turret = True
                                    square.occupied = True
                                    self.player_resources.current_cash -= self.mouse_active_turret.build_cost
                                    self.mouse_active_turret.placed = True
                                    self.mouse_active_turret = None
                        if not placed_turret:
                            self.turrets[:] = [
                                turret for turret in self.turrets
                                if turret is not self.mouse_active_turret
                            ]
                            self.mouse_active_turret = None
                    else:
                        for turret in self.turrets:
                            if turret.rect.collidepoint(
                                    pygame.mouse.get_pos()):
                                if turret.get_level() < turret.get_max_level():
                                    self.upgrade_hud_active = True
                                    self.active_upgrade_turret = turret
                                    self.hud_panel.display_upgrade_hud(
                                        self.active_upgrade_turret)

        if not self.is_game_over and self.mouse_active_turret is not None:
            is_over_square = False
            for square in self.tiled_level.turret_squares:
                if square.rect.collidepoint(
                        pygame.mouse.get_pos()) and not square.occupied:
                    self.mouse_active_turret.set_position(square.position)
                    self.mouse_active_turret.show_radius = True
                    is_over_square = True
            if not is_over_square:
                self.mouse_active_turret.set_position(pygame.mouse.get_pos())
                self.mouse_active_turret.show_radius = False

        for bullet in self.bullets:
            self.all_bullet_sprites = bullet.update_sprite(
                self.all_bullet_sprites)
            bullet.update_movement_and_collision(self.monsters, time_delta,
                                                 self.new_explosions,
                                                 self.explosions)
        self.bullets[:] = [
            bullet for bullet in self.bullets if not bullet.should_die
        ]

        for monster in self.monsters:
            monster.update_movement_and_collision(
                time_delta, self.player_resources,
                self.tiled_level.position_offset, self.splat_sprites)
            monster.update_sprite()
        self.monsters[:] = [
            monster for monster in self.monsters if not monster.should_die
        ]
        self.new_explosions[:] = []

        for turret in self.turrets:
            turret.update_movement_and_collision(time_delta, self.monsters,
                                                 self.bullets,
                                                 pygame.mouse.get_pos())
            self.all_turret_sprites = turret.update_sprite(
                self.all_turret_sprites)

        for explosion in self.explosions:
            self.all_explosion_sprites = explosion.update_sprite(
                self.all_explosion_sprites, time_delta)
        self.explosions[:] = [
            explosion for explosion in self.explosions
            if not explosion.should_die
        ]

        self.splat_sprites.update(time_delta)

        self.collision_grid.update_shape_grid_positions()
        self.collision_grid.check_collisions()

        self.ui_manager.update(time_delta)

        for collided_shape in self.collision_grid.shapes_collided_this_frame:
            if collided_shape.owner is not None:
                collided_shape.owner.react_to_collision()

        if self.should_redraw_static_sprites:
            self.should_redraw_static_sprites = False
            self.static_sprite_surface.blit(self.background,
                                            (0, 0))  # draw the background
            self.all_tile_sprites.draw(self.static_sprite_surface)

        surface.blit(self.static_sprite_surface, (0, 0))
        self.splat_sprites.draw(surface)
        if self.mouse_active_turret is not None:
            self.all_square_sprites.draw(surface)
        self.all_monster_sprites.draw(surface)
        self.all_turret_sprites.draw(surface)
        self.all_bullet_sprites.draw(surface)
        self.all_explosion_sprites.draw(surface)

        # collision debug
        # for monster in monsters:
        #     monster.draw_collision_circle(screen)
        # for bullet in bullets:
        #     bullet.draw_collision_rect(screen)

        for turret in self.turrets:
            if turret.show_radius:
                turret.draw_radius_circle(surface)

        if time_delta > 0.0 and self.fps_counter_label is not None:
            if len(self.frame_rates) < 300:
                self.frame_rates.append(1.0 / time_delta)
            else:
                self.frame_rates.popleft()
                self.frame_rates.append(1.0 / time_delta)

            fps = sum(self.frame_rates) / len(self.frame_rates)

            self.fps_counter_label.set_text("FPS: {:.2f}".format(fps))

        if self.should_show_count_down_message and self.count_down_message_label is not None:
            self.count_down_message_label.set_text(self.count_down_message)

        if self.wave_display_label is not None and self.monster_wave_spawner.has_changed_wave:
            current_wave = str(self.monster_wave_spawner.current_wave_number)
            max_wave = str(self.monster_wave_spawner.maximum_wave_number)
            self.wave_display_label.set_text("Wave " + current_wave + "/" +
                                             max_wave)

        self.ui_manager.draw_ui(surface)