Beispiel #1
0
 def create_ai_at_random_position(self):
     for x in range(self._game_grid.grid_size.x):
         for y in range(self._game_grid.grid_size.y):
             if self._game_grid.cells[x][
                     y].walkable and self._game_grid.explosions[x][
                         y] is False:
                 if Vector2(x, y).mahattan_distance(
                         self._player_controller._grid_pos
                 ) > self._game_grid.grid_size.x / 2:
                     self.add_AI(Vector2(x, y))
                     return
Beispiel #2
0
 def compute_world_position(self, grid_position: Vector2) -> Vector2:
     offset = self._grid.transform.position - (self._grid.dimensions / 2)
     world_position = Vector2(0, 0)
     world_position.x = grid_position.x * self._cell_size.x
     world_position.y = grid_position.y * self._cell_size.y
     world_position += offset
     world_position += self._cell_size / 2
     return world_position
Beispiel #3
0
 def find_lowest_f_cost_node(
         nodes: Dict[Vector2, AIAgent.ASNode]) -> AIAgent.ASNode:
     lowest_f_cost_node: AIAgent.ASNode = AIAgent.ASNode(
         Vector2(0, 0), None, 5000, 5000)
     for node in nodes.values():
         if node.f_cost < lowest_f_cost_node.f_cost:
             lowest_f_cost_node = node
     return lowest_f_cost_node
Beispiel #4
0
 def __init__(self, source: pygame.Surface, row_count: int,
              column_count: int):
     self.__source = source
     self.__sprite_size = Vector2(source.get_width() / column_count,
                                  source.get_height() / row_count)
     self.__sprite_matrix: List[List[pygame.Surface]] = list()
     self.__row_count = row_count
     self.__column_count = column_count
     self.__generate_sprite_matrix()
Beispiel #5
0
 def on_init(self):
     self._sprite_renderer: core.core_components.SpriteRenderer = self.owner.get_component(
         core.core_components.SpriteRenderer)
     self._movement_disabled: bool = False
     self._target_position: Vector2 = Vector2(0, 0)
     self._mov_delta: Vector2 = Vector2(0, 0)
     self._fire_power = 5
     self._max_bombs = 3
     self._bomb_count = 0
     self._mov_delta_factor = 10
     self._movement_duration = (1 / 60) * self._mov_delta_factor
     self._frame_duration = self._movement_duration / 7
     self._play_anim = False
     self._current_anim_frame: int = 0
     self._last_frame_tp: float = 0
     self._direction: Direction = Direction.SOUTH
     self._anim_type: int = 0
     self.event_system.listen("bomb_exploded",
                              self.return_bomb,
                              sender=self)
     self.sheet = "player"
Beispiel #6
0
    def __find_path_to_safety(self) -> AIAgent.ASNode:
        open_nodes: List[AIAgent.ASNode] = list()
        closed_nodes: Dict[Vector2, AIAgent.ASNode] = dict()
        open_nodes.append(AIAgent.ASNode(self._grid_pos, None, 0, 0))
        danger_grid = self.__expand_bombs()

        if danger_grid[self._grid_pos.x][self._grid_pos.y] is False:
            return open_nodes[0]
        while open_nodes:
            q = open_nodes.pop(0)
            closed_nodes[q.position] = q
            successors: List[AIAgent.ASNode] = list()

            temp_pos = q.position + Vector2(0, 1)
            if temp_pos.y < self._grid_size.y and self._grid.cells[temp_pos.x][
                    temp_pos.y].walkable and temp_pos not in closed_nodes:
                successors.append(AIAgent.ASNode(temp_pos, q, 0, 0))

            temp_pos = q.position + Vector2(0, -1)
            if temp_pos.y >= 0 and self._grid.cells[temp_pos.x][
                    temp_pos.y].walkable and temp_pos not in closed_nodes:
                successors.append(AIAgent.ASNode(temp_pos, q, 0, 0))

            temp_pos = q.position + Vector2(1, 0)
            if temp_pos.x < self._grid_size.y and self._grid.cells[temp_pos.x][
                    temp_pos.y].walkable and temp_pos not in closed_nodes:
                successors.append(AIAgent.ASNode(temp_pos, q, 0, 0))

            temp_pos = q.position + Vector2(-1, 0)
            if temp_pos.x >= 0 and self._grid.cells[temp_pos.x][
                    temp_pos.y].walkable and temp_pos not in closed_nodes:
                successors.append(AIAgent.ASNode(temp_pos, q, 0, 0))

            open_nodes.extend(successors)

            for succ in successors:
                if danger_grid[succ.position.x][succ.position.y] is False:
                    return succ
Beispiel #7
0
    def update(self):
        self.transform.position += self._mov_delta
        if (self._play_anim):
            if (time.perf_counter() - self._last_frame_tp >=
                    self._frame_duration):
                self._last_frame_tp = time.perf_counter()
                self._sprite_renderer.sprite = self.app.image_loader.get_sheet(
                    self.sheet)[0][self._anim_type]
                self._current_anim_frame += 1

        if (self.transform.position -
                self._target_position).squared_mag <= 0.15:
            self._play_anim = False
            self._current_anim_frame = 0
            self.transform.position = self._target_position
            self._movement_disabled = False
            self._mov_delta = Vector2(0, 0)
            self.__set_end_sprite()

        if (self._grid.explosions[self._grid_pos.x][self._grid_pos.y]):
            self.world.mark_entity_for_deletion(self.owner)
            self.on_death()
Beispiel #8
0
    def start_game(self):
        self._menu_canvas.hide()
        self._game_over_canvas.hide()
        self._game_grid_entity = self.world.add_entity()
        self._game_grid_entity.add_component(
            core.core_components.SpriteRenderer)
        self._game_grid: GameGrid = self._game_grid_entity.add_component(
            GameGrid)
        self._game_grid.generate_grid(Vector2(17, 17), Vector2(32, 32))

        self._player_entity = self.world.add_entity()
        self._player_entity.add_component(core.core_components.SpriteRenderer)
        self._player_controller: Player = self._player_entity.add_component(
            Player)
        self._player_controller.set_grid(self._game_grid, Vector2(0, 0))

        self.add_AI(Vector2(0, 16))
        self.add_AI(Vector2(16, 0))
        self.add_AI(Vector2(16, 16))
Beispiel #9
0
 def dimensions(self) -> Vector2:
     return Vector2(self.__grid_size.x * self.__cell_size.x,
                    self.__grid_size.y * self.__cell_size.y)
Beispiel #10
0
 def _move_down(self, *args):
     self.move(Vector2(0, 1))
Beispiel #11
0
    def generate_grid(self, grid_size: Vector2, cell_size: Vector2):
        self.__grid_size = grid_size
        self.__cell_size = cell_size
        self.__grid_cells: List[List[GridCell]] = list()
        self.__grid_image: pygame.Surface = pygame.Surface(
            (grid_size.x * cell_size.x, grid_size.y * cell_size.y))
        self.__grid_bombs: List[List[Optional[Bomb]]] = list()
        self.__grid_explosions: List[List[bool]] = list()

        for x in range(self.__grid_size.x):
            column: List[GridCell] = list()
            bomb_column: List[Optional[Bomb]] = list()
            explosion_column: List[bool] = list()
            for y in range(self.__grid_size.y):
                if (x + 1) % 2 == 0 and (y + 1) % 2 == 0:
                    cell = GridCell(self.app.image_loader.get_image("ob"),
                                    Vector2(x, y), self.event_system, False,
                                    False)
                else:
                    cell = GridCell(self.app.image_loader.get_image("wall"),
                                    Vector2(x, y), self.event_system, False,
                                    True)

                self.event_system.listen("cell_img_changed",
                                         self.update_grid_img,
                                         sender=cell)
                column.append(cell)
                bomb_column.append(None)
                explosion_column.append(False)

            self.__grid_cells.append(column)
            self.__grid_bombs.append(bomb_column)
            self.__grid_explosions.append(explosion_column)
        self.__grid_cells[0][0].image = self.app.image_loader.get_image("dirt")
        self.__grid_cells[0][1].image = self.app.image_loader.get_image("dirt")
        self.__grid_cells[1][0].image = self.app.image_loader.get_image("dirt")
        self.__grid_cells[0][0].walkable = True
        self.__grid_cells[0][1].walkable = True
        self.__grid_cells[1][0].walkable = True
        self.__grid_cells[0][0].destructible = False
        self.__grid_cells[0][1].destructible = False
        self.__grid_cells[1][0].destructible = False

        self.__grid_cells[self.__grid_size.x -
                          1][self.__grid_size.y -
                             1].image = self.app.image_loader.get_image("dirt")
        self.__grid_cells[self.__grid_size.x -
                          2][self.__grid_size.y -
                             1].image = self.app.image_loader.get_image("dirt")
        self.__grid_cells[self.__grid_size.x -
                          1][self.__grid_size.y -
                             2].image = self.app.image_loader.get_image("dirt")
        self.__grid_cells[self.__grid_size.x - 1][self.__grid_size.y -
                                                  1].walkable = True
        self.__grid_cells[self.__grid_size.x - 2][self.__grid_size.y -
                                                  1].walkable = True
        self.__grid_cells[self.__grid_size.x - 1][self.__grid_size.y -
                                                  2].walkable = True

        self.__grid_cells[self.__grid_size.x - 1][self.__grid_size.y -
                                                  1].destructible = False
        self.__grid_cells[self.__grid_size.x - 2][self.__grid_size.y -
                                                  1].destructible = False
        self.__grid_cells[self.__grid_size.x - 1][self.__grid_size.y -
                                                  2].destructible = False

        self.__grid_cells[self.__grid_size.x -
                          1][0].image = self.app.image_loader.get_image("dirt")
        self.__grid_cells[self.__grid_size.x -
                          2][0].image = self.app.image_loader.get_image("dirt")
        self.__grid_cells[self.__grid_size.x -
                          1][1].image = self.app.image_loader.get_image("dirt")
        self.__grid_cells[self.__grid_size.x - 1][0].walkable = True
        self.__grid_cells[self.__grid_size.x - 2][0].walkable = True
        self.__grid_cells[self.__grid_size.x - 1][1].walkable = True

        self.__grid_cells[self.__grid_size.x - 1][0].destructible = False
        self.__grid_cells[self.__grid_size.x - 2][0].destructible = False
        self.__grid_cells[self.__grid_size.x - 1][1].destructible = False

        self.__grid_cells[0][self.__grid_size.y -
                             1].image = self.app.image_loader.get_image("dirt")
        self.__grid_cells[1][self.__grid_size.y -
                             1].image = self.app.image_loader.get_image("dirt")
        self.__grid_cells[0][self.__grid_size.y -
                             2].image = self.app.image_loader.get_image("dirt")
        self.__grid_cells[0][self.__grid_size.y - 1].walkable = True
        self.__grid_cells[1][self.__grid_size.y - 1].walkable = True
        self.__grid_cells[0][self.__grid_size.y - 2].walkable = True

        self.__grid_cells[0][self.__grid_size.y - 1].destructible = False
        self.__grid_cells[1][self.__grid_size.y - 1].destructible = False
        self.__grid_cells[0][self.__grid_size.y - 2].destructible = False

        self.generate_grid_image()
        self.centralize_grid_in_screen()
Beispiel #12
0
    def find_path(self,
                  end_pos: Vector2,
                  ignore_walkability: bool = False,
                  ignore_danger: bool = False):
        open_nodes: Dict[Vector2, AIAgent.ASNode] = dict()
        closed_nodes: Dict[Vector2, AIAgent.ASNode] = dict()
        open_nodes[self._grid_pos] = AIAgent.ASNode(self._grid_pos, None, 0, 0)
        danger_grid: List[List[bool]] = self.__expand_bombs()
        if end_pos == self._grid_pos:
            return

        def find_lowest_f_cost_node(
                nodes: Dict[Vector2, AIAgent.ASNode]) -> AIAgent.ASNode:
            lowest_f_cost_node: AIAgent.ASNode = AIAgent.ASNode(
                Vector2(0, 0), None, 5000, 5000)
            for node in nodes.values():
                if node.f_cost < lowest_f_cost_node.f_cost:
                    lowest_f_cost_node = node
            return lowest_f_cost_node

        while open_nodes:
            q: AIAgent.ASNode = find_lowest_f_cost_node(open_nodes)
            del open_nodes[q.position]
            successsors: List[AIAgent.ASNode] = list()

            temp_pos = q.position + Vector2(0, 1)

            if temp_pos.y < self._grid_size.y and (
                    self._grid.cells[temp_pos.x][temp_pos.y].walkable or
                (ignore_walkability and
                 self._grid.cells[temp_pos.x][temp_pos.y].destructible)) and (
                     (self._grid.explosions[temp_pos.x][temp_pos.y] is False
                      and danger_grid[temp_pos.x][temp_pos.y] is False)
                     or ignore_danger):
                successsors.append(
                    AIAgent.ASNode(temp_pos, q, q.g_cost + 1,
                                   temp_pos.mahattan_distance(end_pos)))

            temp_pos = q.position + Vector2(0, -1)
            if temp_pos.y >= 0 and (
                    self._grid.cells[temp_pos.x][temp_pos.y].walkable or
                (ignore_walkability and
                 self._grid.cells[temp_pos.x][temp_pos.y].destructible)) and (
                     (self._grid.explosions[temp_pos.x][temp_pos.y] is False
                      and danger_grid[temp_pos.x][temp_pos.y] is False)
                     or ignore_danger):
                successsors.append(
                    AIAgent.ASNode(temp_pos, q, q.g_cost + 1,
                                   temp_pos.mahattan_distance(end_pos)))

            temp_pos = q.position + Vector2(1, 0)
            if temp_pos.x < self._grid_size.x and (
                    self._grid.cells[temp_pos.x][temp_pos.y].walkable or
                (ignore_walkability and
                 self._grid.cells[temp_pos.x][temp_pos.y].destructible)) and (
                     (self._grid.explosions[temp_pos.x][temp_pos.y] is False
                      and danger_grid[temp_pos.x][temp_pos.y] is False)
                     or ignore_danger):
                successsors.append(
                    AIAgent.ASNode(temp_pos, q, q.g_cost + 1,
                                   temp_pos.mahattan_distance(end_pos)))

            temp_pos = q.position + Vector2(-1, 0)
            if temp_pos.x >= 0 and (
                    self._grid.cells[temp_pos.x][temp_pos.y].walkable or
                (ignore_walkability and
                 self._grid.cells[temp_pos.x][temp_pos.y].destructible)) and (
                     (self._grid.explosions[temp_pos.x][temp_pos.y] is False
                      and danger_grid[temp_pos.x][temp_pos.y] is False)
                     or ignore_danger):
                successsors.append(
                    AIAgent.ASNode(temp_pos, q, q.g_cost + 1,
                                   temp_pos.mahattan_distance(end_pos)))

            for succ in successsors:
                if succ.position == end_pos:
                    return succ

                if succ.position in open_nodes:
                    if open_nodes[succ.position].f_cost < succ.f_cost:
                        continue
                elif succ.position in closed_nodes:
                    if closed_nodes[succ.position].f_cost < succ.f_cost:
                        continue
                else:
                    open_nodes[succ.position] = succ

            closed_nodes[q.position] = q
Beispiel #13
0
 def _move_left(self, *args):
     self.move(Vector2(-1, 0))
Beispiel #14
0
    def on_explode(self, incoming_direction: Optional[Direction] = None):
        self.event_system.broadcast("bomb_exploded", sender=self.__owner)
        self._grid.cells[self._grid_pos.x][self._grid_pos.y].walkable = True
        self._grid.bombs[self._grid_pos.x][self._grid_pos.y] = None
        self.world.mark_entity_for_deletion(self.owner)
        firepower = self.__owner.firepower

        expand_east: bool = True if incoming_direction != Direction.EAST else False
        expand_west: bool = True if incoming_direction != Direction.WEST else False
        expand_north: bool = True if incoming_direction != Direction.NORTH else False
        expand_south: bool = True if incoming_direction != Direction.SOUTH else False

        if incoming_direction is None:
            self.app.sound_loader.play_sound("explosion")

        self.create_explosion(Direction.CENTER, self._grid_pos)

        for val in range(1, firepower + 1):
            final_iteration = val == firepower
            if expand_west:
                target_x = self._grid_pos.x - val
                if target_x >= 0:
                    target_cell: GridCell = self._grid.cells[target_x][
                        self._grid_pos.y]
                    target_bomb: Bomb = self._grid.bombs[target_x][
                        self._grid_pos.y]
                    if target_cell.destructible:
                        target_cell.destructible = False
                        target_cell.walkable = True
                        target_cell.image = self.app.image_loader.get_image(
                            "dirt")
                        self.create_explosion(Direction.WEST,
                                              Vector2(target_x,
                                                      self._grid_pos.y),
                                              end=True)
                        expand_west = False
                    elif target_bomb is not None:
                        target_bomb.on_explode(Direction.EAST)
                        expand_west = False
                    elif target_cell.walkable:
                        self.create_explosion(Direction.WEST,
                                              Vector2(target_x,
                                                      self._grid_pos.y),
                                              end=(target_x == 0
                                                   or final_iteration))
                    else:
                        expand_west = False

            if expand_east:
                target_x = self._grid_pos.x + val
                if target_x < self._grid_size.x:
                    target_cell: GridCell = self._grid.cells[target_x][
                        self._grid_pos.y]
                    target_bomb: Bomb = self._grid.bombs[target_x][
                        self._grid_pos.y]
                    if target_cell.destructible:
                        target_cell.destructible = False
                        target_cell.walkable = True
                        target_cell.image = self.app.image_loader.get_image(
                            "dirt")
                        self.create_explosion(Direction.EAST,
                                              Vector2(target_x,
                                                      self._grid_pos.y),
                                              end=True)
                        expand_east = False
                    elif target_bomb is not None:
                        target_bomb.on_explode(Direction.WEST)
                        expand_east = False
                    elif target_cell.walkable:
                        self.create_explosion(
                            Direction.EAST,
                            Vector2(target_x, self._grid_pos.y),
                            end=(target_x == self._grid_size.x - 1
                                 or final_iteration))
                    else:
                        expand_east = False

            if expand_north:
                target_y = self._grid_pos.y - val
                if target_y >= 0:
                    target_cell: GridCell = self._grid.cells[
                        self._grid_pos.x][target_y]
                    target_bomb: Bomb = self._grid.bombs[
                        self._grid_pos.x][target_y]
                    if target_cell.destructible:
                        target_cell.destructible = False
                        target_cell.walkable = True
                        target_cell.image = self.app.image_loader.get_image(
                            "dirt")
                        self.create_explosion(Direction.NORTH,
                                              Vector2(self._grid_pos.x,
                                                      target_y),
                                              end=True)
                        expand_north = False
                    elif target_bomb is not None:
                        target_bomb.on_explode(Direction.SOUTH)
                        expand_north = False
                    elif target_cell.walkable:
                        self.create_explosion(Direction.NORTH,
                                              Vector2(self._grid_pos.x,
                                                      target_y),
                                              end=(target_y == 0
                                                   or final_iteration))
                    else:
                        expand_north = False

            if expand_south:
                target_y = self._grid_pos.y + val
                if target_y < self._grid_size.y:
                    target_cell: GridCell = self._grid.cells[
                        self._grid_pos.x][target_y]
                    target_bomb: Bomb = self._grid.bombs[
                        self._grid_pos.x][target_y]
                    if target_cell.destructible:
                        target_cell.destructible = False
                        target_cell.walkable = True
                        target_cell.image = self.app.image_loader.get_image(
                            "dirt")
                        self.create_explosion(Direction.SOUTH,
                                              Vector2(self._grid_pos.x,
                                                      target_y),
                                              end=True)
                        expand_south = False
                    elif target_bomb is not None:
                        target_bomb.on_explode(Direction.NORTH)
                        expand_south = False
                    elif target_cell.walkable:
                        self.create_explosion(
                            Direction.SOUTH,
                            Vector2(self._grid_pos.x, target_y),
                            end=(target_y == self._grid_size.y - 1
                                 or final_iteration))
                    else:
                        expand_south = False

            if not expand_east and not expand_west and not expand_south and not expand_north:
                break
Beispiel #15
0
 def _move_right(self, *args):
     self.move(Vector2(1, 0))
Beispiel #16
0
 def _move_up(self, *args):
     self.move(Vector2(0, -1))
Beispiel #17
0
 def centralize_grid_in_screen(self):
     self.transform.position = Vector2(self.app.display.get_width() / 2,
                                       self.app.display.get_height() / 2)
Beispiel #18
0
    def on_init(self):
        self._menu_canvas: core.core_components.Canvas = self.owner.add_component(
            core.core_components.Canvas)
        self._play_button = core.core_components.Button(
            Vector2(600, 200), self._menu_canvas)
        self._play_button.text = "JOGAR"
        self._play_button.foreground_color = (0, 210, 210, 255)

        self._quit_button = core.core_components.Button(
            Vector2(600, 350), self._menu_canvas)
        self._quit_button.text = "SAIR"
        self._quit_button.foreground_color = (0, 210, 210, 255)

        self._main_text = core.core_components.Button(Vector2(600, 50),
                                                      self._menu_canvas)
        self._main_text.text = "py-BOMBERMAN"
        self._main_text.font_size = 50
        self._main_text.foreground_color = (0, 0, 0, 0)
        self._main_text.size = (600, 300)

        self._play_button.on_click = self.start_game
        self._quit_button.on_click = lambda: exit(0)

        self._game_over_canvas: core.core_components.Canvas = self.owner.add_component(
            core.core_components.Canvas)
        self._retry_button = core.core_components.Button(
            Vector2(600, 200), self._game_over_canvas)
        self._retry_button.foreground_color = (0, 210, 210, 255)
        self._retry_button.text = "TENTAR NOVAMENTE"
        self._retry_button.on_click = self.start_game

        self._main_menu_button = core.core_components.Button(
            Vector2(600, 350), self._game_over_canvas)
        self._main_menu_button.foreground_color = (0, 210, 210, 255)
        self._main_menu_button.text = "VOLTAR PARA O MENU PRINCIPAL"

        self._main_menu_button.on_click = self._game_over_to_main_menu

        self._game_over_text = core.core_components.Button(
            Vector2(600, 50), self._game_over_canvas)
        self._game_over_text.text = "GAME OVER"
        self._game_over_text.font_size = 30
        self._game_over_text.foreground_color = (0, 0, 0, 0)

        self._final_score_text = core.core_components.Button(
            Vector2(600, 450), self._game_over_canvas)
        self._final_score_text.foreground_color = (0, 0, 0, 0)
        self._highest_score_text = core.core_components.Button(
            Vector2(600, 500), self._game_over_canvas)
        self._highest_score_text.foreground_color = (0, 0, 0, 0)

        self._new_record_text = core.core_components.Button(
            Vector2(600, 650), self._game_over_canvas)
        self._new_record_text.text = ""
        self._new_record_text.foreground_color = (0, 0, 0, 0)

        self._game_over_canvas.hide()

        self._ai_count = 0
        self._ai_list: List[core.entity_system.Entity] = list()

        self.event_system.listen("ai_death", self.on_ai_death)
        self.event_system.listen("player_death", self.on_player_death)
        self._actions: List[Tuple[Callable, float]] = list()
        self._highest_score = 0
        self.load_highest_score()
        self._current_score = 0
        pygame.display.set_icon(self.app.image_loader.get_image("bomb"))