コード例 #1
0
 def get_wall_binary(self, node: PVector) -> str:
     """
     Get surrounding tiles and check if they are walls.
     :param node:
     :return:
     """
     surrounding = ''
     # Left
     if self.is_wall(node + PVector(-1, 0)):
         surrounding += '1'
     else:
         surrounding += '0'
     # Right
     if self.is_wall(node + PVector(1, 0)):
         surrounding += '1'
     else:
         surrounding += '0'
     # Up
     if self.is_wall(node + PVector(0, -1)):
         surrounding += '1'
     else:
         surrounding += '0'
     # Down
     if self.is_wall(node + PVector(0, 1)):
         surrounding += '1'
     else:
         surrounding += '0'
     return surrounding
コード例 #2
0
ファイル: game.py プロジェクト: Raragyay/Pacman
 def vert_offset_middle(self, surf: pygame.Surface, offset: PVector):
     """
     Get Top Left but with vertical offset option
     :param surf:
     :param offset:
     :return:
     """
     return PVector.to_tuple(
         PVector.from_tuple(self.get_top_left(surf)) + offset)
コード例 #3
0
    def write_attr(self, information) -> int:
        """
        Writes an attribute of the map to the level.
        :param information: An array of strings, taken from the file.
        :return: None
        """
        attr = information[1]

        if attr == 'lvlwidth':  # Set the level width
            self.level_width = int(information[2])
        elif attr == 'lvlheight':  # Set the level height
            self.level_height = int(information[2])
        elif 'colour' in attr:  # Set one of the colour attributes
            red = int(information[2])
            green = int(information[3])
            blue = int(information[4])
            colour_tup = (red, green, blue, 255)

            if attr == 'edgecolour':
                self.edge_light_colour = colour_tup
                self.edge_shadow_colour = colour_tup
            elif attr == 'edgelightcolour':
                self.edge_light_colour = colour_tup
            elif attr == 'edgeshadowcolour':
                self.edge_shadow_colour = colour_tup
            elif attr == 'fillcolour':
                self.fill_colour = colour_tup
            elif attr == 'pelletcolour':
                self.pellet_colour = colour_tup
            elif attr == 'bgcolour':
                self.bg_colour = colour_tup
            else:
                return -1  # An error has occurred

        elif 'ghost' in attr:  # Add ghost corners for scatter mode
            corner_1 = PVector(int(information[2]), int(information[3]))
            corner_2 = PVector(int(information[4]), int(information[5]))
            if 'blinky' in attr:
                self.blinky_start.add_corners(corner_1, corner_2)
            if 'pinky' in attr:
                self.pinky_start.add_corners(corner_1, corner_2)
            if 'inky' in attr:
                self.inky_start.add_corners(corner_1, corner_2)
            if 'clyde' in attr:
                self.clyde_start.add_corners(corner_1, corner_2)
        elif attr == 'fruittype':  # Add fruit type for point values
            self.fruit_id = int(information[2])
        elif attr == 'startleveldata':
            logging.debug('Now reading level data.')
            return 1  # Toggles is_reading_level_data and sets row_num to 0.
        elif attr == 'endleveldata':
            logging.debug('Level data has been read.')
            return 2
        else:  # An error has occurred
            return -1
        return 0  # No problems
コード例 #4
0
ファイル: game.py プロジェクト: Raragyay/Pacman
 def get_top_left(self, surf: pygame.Surface):
     """
     Utility
     :param surf:
     :return:
     """
     surf_half_size = PVector.from_tuple(surf.get_size()) / 2  # Center
     screen_center = PVector.from_tuple(
         self.screen.get_size()) / 2  # Center
     return PVector.to_tuple(screen_center - surf_half_size)  # Offset
コード例 #5
0
ファイル: ghost.py プロジェクト: Raragyay/Pacman
 def adjust_speed(self):
     """
     Try to speed up if we are on the correct increment to ensure that we land on the node perfectly.
     :return:
     """
     if self.pos % 4 == PVector(0, 0):
         # Quadruple Speed
         self.speed = 4
     elif self.pos % 2 == PVector(0, 0):
         # Double Speed
         self.speed = 2
     elif self.pos % 1 == PVector(0, 0):
         # Normal Speed
         self.speed = 1
     else:  # Half speed, continue
         pass
コード例 #6
0
ファイル: game.py プロジェクト: Raragyay/Pacman
 def draw_pacman_logo(self):
     """
     Utility
     :return:
     """
     logo = self.level.get_logo()
     self.screen.blit(logo, self.vert_offset_middle(logo, PVector(0, -100)))
コード例 #7
0
ファイル: game.py プロジェクト: Raragyay/Pacman
 def draw_query(self):
     """
     Draw query for text box entry
     :return:
     """
     text_surf = self.render_text("PLEASE ENTER YOUR NAME:")
     self.screen.blit(text_surf,
                      self.vert_offset_middle(text_surf, PVector(0, -26)))
コード例 #8
0
ファイル: game.py プロジェクト: Raragyay/Pacman
 def draw_begin_prompt(self):
     """
     Draw Prompt to begin
     :return:
     """
     font = self.create_font(16)
     text = self.render_text('Press any key to begin', font)
     self.screen.blit(text, self.vert_offset_middle(text, PVector(0, 100)))
コード例 #9
0
ファイル: game.py プロジェクト: Raragyay/Pacman
 def draw_quit_hint(self):
     """
     Draw quit hint
     :return:
     """
     text_surf = self.render_text("Press q to quit, r to try again",
                                  self.create_font(16))
     self.screen.blit(text_surf,
                      self.vert_offset_middle(text_surf, PVector(0, 150)))
コード例 #10
0
ファイル: game.py プロジェクト: Raragyay/Pacman
 def draw_level(self):
     """
     Draws each tile in the level
     :return:
     """
     for row in range(self.level.height()):
         for col in range(self.level.width()):
             surf = self.level.get_tile_surf(PVector(col, row))
             self.screen.blit(surf, (col * 16, row * 16))
コード例 #11
0
 def update_surf(self):
     """
     Update surfs based on Pacman's direction
     :return:
     """
     self.increment_frame_num()
     if self.direc == PVector(self.speed, 0):
         self.surf = self.right_surf[self.anim_num]
         return
     if self.direc == PVector(-self.speed, 0):
         self.surf = self.left_surf[self.anim_num]
         return
     if self.direc == PVector(0, self.speed):
         self.surf = self.down_surf[self.anim_num]
         return
     if self.direc == PVector(0, -self.speed):
         self.surf = self.up_surf[self.anim_num]
         return
コード例 #12
0
 def check_node(self):
     """
     Makes sure that we don't crash into a wall.
     :return:
     """
     if self.is_on_node():
         self.check_teleport()
         if not self.level.is_safe(self.nearest_node + self.direc):  # If it isn't safe anymore
             self.direc = PVector(0, 0)
コード例 #13
0
    def calc_teleport(self, node: PVector) -> PVector:
        """
        Calculate the destination teleport
        :param node: PVector
        :return: Destination
        """
        assert node.x == 0 or node.x == self.level_width - 1 or node.y == 0 or node.y == self.level_height - 1
        # Make sure it is on the edge of the map
        # Horizontal teleport
        if node.x == 0:
            return PVector(self.level_width - 1, node.y)
        if node.x == self.level_width - 1:
            return PVector(0, node.y)

        # Vertical Teleport
        if node.y == 0:
            return PVector(node.x, self.level_height - 1)
        if node.y == self.level_height - 1:
            return PVector(node.x, 0)
コード例 #14
0
 def get_key_strokes(self) -> None:
     """
     Get pressed keys and try to turn in each of the directions.
     Only one key is processed at one time to prevent phasing through walls.
     :return:
     """
     keys_pressed = pygame.key.get_pressed()
     if any(keys_pressed[key] for key in [pygame.K_d, pygame.K_RIGHT]):  # Right
         self.try_to_turn(PVector(DEFAULT_SPEED, 0))
         return
     if any(keys_pressed[key] for key in [pygame.K_a, pygame.K_LEFT]):  # Left
         self.try_to_turn(PVector(-DEFAULT_SPEED, 0))
         return
     if any(keys_pressed[key] for key in [pygame.K_w, pygame.K_UP]):  # Up
         self.try_to_turn(PVector(0, -DEFAULT_SPEED))
         return
     if any(keys_pressed[key] for key in [pygame.K_s, pygame.K_DOWN]):  # Down
         self.try_to_turn(PVector(0, DEFAULT_SPEED))
         return
コード例 #15
0
ファイル: clyde.py プロジェクト: Raragyay/Pacman
    def update_direc(self) -> None:
        """
        Chases pacman if far away but runs away to corner if too close.
        :return:
        """

        if abs(self.nearest_node - self.pacman.nearest_node) < PVector(
                8, 8):  # If Clyde is too close, he runs away
            self.scatter()
        else:
            self.direc = self.path_to(
                self.pacman.nearest_node)  # Otherwise he behaves like blinky
コード例 #16
0
    def try_to_turn(self, direc: PVector) -> None:  # BUG TESTED
        """
        Turns orthogonally if we're directly on the node
        Tries to cut the corner if possible
        :param direc:
        :return:
        """
        if self.level.is_safe(self.nearest_node + direc) and self.is_on_grid_line():
            if self.is_on_node():
                self.direc = direc  # Right angle turn
            elif self.is_turning(direc):
                if abs(self.pos % 16) < PVector(MAX_CUT, MAX_CUT):  # If we can cut

                    self.diagonal_move = self.direc + direc  # Move in both directions at once
                    self.cut_corner = True
                    self.direc = direc
コード例 #17
0
 def get_surrounding_accessibles(self, node: PVector) -> set:
     """
     Gets surrounding nodes that are safe
     :param node:
     :return: set of safe nodes to be added to edges dictionary
     """
     safe_nodes = set()
     # Left
     if self.is_safe(node + PVector(1, 0)):
         safe_nodes.add(node + PVector(1, 0))
     # Right
     if self.is_safe(node + PVector(-1, 0)):
         safe_nodes.add(node + PVector(-1, 0))
     # Down
     if self.is_safe(node + PVector(0, 1)):
         safe_nodes.add(node + PVector(0, 1))
     # Up
     if self.is_safe(node + PVector(0, -1)):
         safe_nodes.add(node + PVector(0, -1))
     return safe_nodes
コード例 #18
0
ファイル: ghost.py プロジェクト: Raragyay/Pacman
 def enter_box(self):
     """
     Just like exit_box, but is the opposite.
     :return:
     """
     if self.nearest_node == self.start:  # We can now switch states.
         self.direc = PVector(0, 0)
         self.increment_cycle()
     elif self.nearest_node == self.level.ghost_door:  # We're on the door, now to get in
         exit_node, = tuple(self.level.edges[self.level.ghost_door])
         opposite_direc = self.direc_to(
             exit_node) * -1  # Move in the opposite direction as the exit
         self.direc = opposite_direc
     elif self.in_ghost_box():  # Move to start location
         self.direc = self.direc_to(self.start)
     elif self.nearest_node in self.level.edges[
             self.level.ghost_door]:  # We're right outside the ghost door
         self.direc = self.direc_to(self.level.ghost_door)
     else:  # Make our way to the ghost door
         self.direc = self.closest_direction(self.level.ghost_door)
コード例 #19
0
    def load_map(self, level_num):
        """
        Resets the level class and loads a new map
        :param level_num: The level number
        """
        self.reset()

        f = open(
            os.path.join(LEVEL_FOLDER, r'level_' + str(level_num) + '.txt'),
            'r')
        logging.info('Level {} successfully opened'.format(level_num))  # log

        line_num = 0
        row_num = 0
        use_line = False
        is_reading_level_data = False

        for line in f:
            line_num += 1

            str_split_by_space = line.strip().split(
                ' ')  # Read line and get identifier

            identifier = str_split_by_space[0]

            if not identifier or identifier == "'":
                logging.debug('Skipping empty line')
                use_line = False
            elif identifier == '#':
                logging.debug('This is a divider or attribute line.')
                use_line = False
                status = self.write_attr(str_split_by_space)  # Add attribute.
                if status == -1:  # Check for errors
                    logging.warning(
                        'Received unknown data at line {}: {}'.format(
                            line_num, ' '.join(str_split_by_space)))
                elif status > 0:  # Check for level reading. Toggle and start reading if it tells object to.
                    is_reading_level_data = not is_reading_level_data
                    if status == 1:
                        row_num = 0
            elif not is_reading_level_data:
                logging.warning('Received unknown data at line {}: {}'.format(
                    line_num, ' '.join(str_split_by_space)))
            else:  # This means that we are reading the level data.
                use_line = True

            if use_line:
                logging.debug('{} tiles in row {}'.format(
                    len(str_split_by_space), row_num))

                assert len(str_split_by_space) == self.level_width, \
                    'width of row {} is different from width described in file, {}'.format(
                        len(str_split_by_space), self.level_width)
                # Make sure that the number of tiles in row is correct, to avoid empty spaces.

                for col in range(self.level_width):
                    self.init_tile(PVector(col, row_num),
                                   str_split_by_space[col])
                    # Create the tile vals. Tile objects will be added later

                row_num += 1

        self.cross_ref.load_cross_refs(
            self.edge_light_colour, self.fill_colour, self.edge_shadow_colour,
            self.pellet_colour
        )  # Now that we have the colours, we can create the tiles.
        self.attach_tiles()  # Add tile objects
        self.build_ghost_box()
        # Create ghost box for ghosts to check if they should exit the box,
        # since ghost door is technically a wall.
        f.close()  # Close file
        self.assert_start_positions(
        )  # Make sure that all required positions are there.