Ejemplo n.º 1
0
class SimpleAnimation(pygame.sprite.Sprite):
    def __init__(self, screen, sprite_sheet, sheet_offsets, pos=(0, 0), resize=None,
                 detail=None, frame_delay=None, flip=False):
        super().__init__()
        self.screen = screen
        if not resize:
            resize = (self.screen.get_height() // 10, self.screen.get_height() // 10)
        self.image_manager = ImageManager(sprite_sheet, sheet=True, pos_offsets=sheet_offsets,
                                          resize=resize, animation_delay=frame_delay)
        if flip:
            self.image_manager.flip()
        self.image, self.rect = self.image_manager.get_image()
        if detail:
            self.detail_piece = ImageManager(detail, sheet=True, pos_offsets=sheet_offsets,
                                             resize=resize).all_images()[0]
            if flip:
                self.image_manager.flip()
            self.image.blit(self.detail_piece, (0, 0))
        else:
            self.detail_piece = None
        self.rect.centerx, self.rect.centery = pos

    def update(self):
        self.image = self.image_manager.next_image()
        if self.detail_piece:
            self.image.blit(self.detail_piece, (0, 0))     # combine detail

    def blit(self):
        self.screen.blit(self.image, self.rect)
Ejemplo n.º 2
0
class SimpleAnimation(pygame.sprite.Sprite):
    """A class for presenting a basic animation with little to no special logic"""
    def __init__(self,
                 screen,
                 sprite_sheet,
                 sheet_offsets,
                 pos=(0, 0),
                 resize=None,
                 detail=None,
                 frame_delay=None,
                 flip=False):
        super().__init__()
        self.screen = screen
        if not resize:
            resize = (self.screen.get_height() // 10,
                      self.screen.get_height() // 10)
        self.image_manager = ImageManager(sprite_sheet,
                                          sheet=True,
                                          pos_offsets=sheet_offsets,
                                          resize=resize,
                                          animation_delay=frame_delay)
        if flip:
            self.image_manager.flip()
        self.image, self.rect = self.image_manager.get_image()
        if detail:
            self.detail_piece = ImageManager(
                detail, sheet=True, pos_offsets=sheet_offsets,
                resize=resize).all_images()[
                    0]  # grab first image in detail sheet
            if flip:
                self.image_manager.flip()
            self.image.blit(self.detail_piece, (0, 0))  # combine detail
        else:
            self.detail_piece = None
        self.rect.centerx, self.rect.centery = pos

    def update(self):
        """Update to the next image in the animation"""
        self.image = self.image_manager.next_image()
        if self.detail_piece:
            self.image.blit(self.detail_piece, (0, 0))  # combine detail

    def blit(self):
        """Blit the current image to the screen"""
        self.screen.blit(self.image, self.rect)
Ejemplo n.º 3
0
class PacMan(pygame.sprite.Sprite):
    """Represents the player character 'PacMan' and its related logic/control"""
    PAC_YELLOW = (255, 255, 0)
    PAC_AUDIO_CHANNEL = 0

    def __init__(self, screen, maze):
        super().__init__()
        self.screen = screen
        self.radius = maze.block_size
        self.maze = maze
        self.sound_manager = SoundManager(sound_files=['pacman-pellet-eat.wav', 'Eaten1.wav',
                                                       'Eaten4.wav'],
                                          keys=['eat', 'fruit', 'dead'],
                                          channel=PacMan.PAC_AUDIO_CHANNEL)
        self.horizontal_images = ImageManager('pacman-horiz.png', sheet=True, pos_offsets=[(0, 0, 32, 32),
                                                                                           (32, 0, 32, 32),
                                                                                           (0, 32, 32, 32),
                                                                                           (32, 32, 32, 32),
                                                                                           (0, 64, 32, 32)],
                                              resize=(self.maze.block_size, self.maze.block_size),
                                              reversible=True)
        self.vertical_images = ImageManager('pacman-vert.png', sheet=True, pos_offsets=[(0, 0, 32, 32),
                                                                                        (32, 0, 32, 32),
                                                                                        (0, 32, 32, 32),
                                                                                        (32, 32, 32, 32),
                                                                                        (0, 64, 32, 32)],
                                            resize=(self.maze.block_size, self.maze.block_size),
                                            reversible=True)
        self.death_images = ImageManager('pacman-death.png', sheet=True, pos_offsets=[(0, 0, 32, 32),
                                                                                      (32, 0, 32, 32),
                                                                                      (0, 32, 32, 32),
                                                                                      (32, 32, 32, 32),
                                                                                      (0, 64, 32, 32),
                                                                                      (32, 64, 32, 32)],
                                         resize=(self.maze.block_size, self.maze.block_size),
                                         animation_delay=150, repeat=False)
        self.flip_status = {'use_horiz': True, 'h_flip': False, 'v_flip': False}
        self.spawn_info = self.maze.player_spawn[1]
        self.tile = self.maze.player_spawn[0]
        self.direction = None
        self.moving = False
        self.speed = maze.block_size // 7
        self.image, self.rect = self.horizontal_images.get_image()
        self.rect.centerx, self.rect.centery = self.spawn_info   # screen coordinates for spawn
        self.dead = False

        # Keyboard related events/actions/releases
        self.event_map = {pygame.KEYDOWN: self.perform_action, pygame.KEYUP: self.reset_direction}
        self.action_map = {pygame.K_UP: self.set_move_up, pygame.K_LEFT: self.set_move_left,
                           pygame.K_DOWN: self.set_move_down, pygame.K_RIGHT: self.set_move_right,
                           }




    def set_death(self):
        """Set the death flag for PacMan and begin the death animation"""
        self.sound_manager.play('dead')
        self.dead = True
        self.image, _ = self.death_images.get_image()

    def revive(self):
        """Set dead to False and give PacMan a default image"""
        self.dead = False
        self.image, _ = self.horizontal_images.get_image()
        self.death_images.image_index = 0

    def reset_position(self):
        """Reset position back to pre-define spawn location"""
        self.rect.centerx, self.rect.centery = self.spawn_info  # screen coordinates for spawn

    def reset_direction(self, event):
        """Reset the movement direction if key-up on movement keys"""
        if event.key in (pygame.K_UP, pygame.K_DOWN, pygame.K_LEFT, pygame.K_RIGHT):
            self.moving = False

    def perform_action(self, event):
        """Change direction based on the event key"""
        if event.key in self.action_map:
            self.action_map[event.key]()

    def set_move_up(self):
        """Set move direction up"""
        if self.direction != 'u':
            self.direction = 'u'
            if self.flip_status['v_flip']:
                self.vertical_images.flip(False, True)
                self.flip_status['v_flip'] = False
            self.flip_status['use_horiz'] = False
        self.moving = True

    def set_move_left(self):
        """Set move direction left"""
        if self.direction != 'l':
            self.direction = 'l'
            if not self.flip_status['h_flip']:
                self.horizontal_images.flip()
                self.flip_status['h_flip'] = True
            self.flip_status['use_horiz'] = True
        self.moving = True

    def set_move_down(self):
        """Set move direction down"""
        if self.direction != 'd':
            self.direction = 'd'
            if not self.flip_status['v_flip']:
                self.vertical_images.flip(x_bool=False, y_bool=True)
                self.flip_status['v_flip'] = True
            self.flip_status['use_horiz'] = False
        self.moving = True

    def set_move_right(self):
        """Set move direction to right"""
        if self.direction != 'r':
            self.direction = 'r'
            if self.flip_status['h_flip']:
                self.horizontal_images.flip()
                self.flip_status['h_flip'] = False
            self.flip_status['use_horiz'] = True
        self.moving = True

    def get_nearest_col(self):
        """Get the current column location on the maze map"""
        return (self.rect.x - (self.screen.get_width() // 5)) // self.maze.block_size

    def get_nearest_row(self):
        """Get the current row location on the maze map"""
        return (self.rect.y - (self.screen.get_height() // 12)) // self.maze.block_size

    def is_blocked(self):
        """Check if PacMan is blocked by any maze barriers, return True if blocked, False if clear"""
        result = False
        if self.direction is not None and self.moving:
            original_pos = self.rect
            if self.direction == 'u':
                test = self.rect.move((0, -self.speed))
            elif self.direction == 'l':
                test = self.rect.move((-self.speed, 0))
            elif self.direction == 'd':
                test = self.rect.move((0, self.speed))
            else:
                test = self.rect.move((self.speed, 0))
            self.rect = test    # temporarily move self

            # if any collision, result = True
            if pygame.sprite.spritecollideany(self, self.maze.maze_blocks):
                result = True
            elif pygame.sprite.spritecollideany(self, self.maze.shield_blocks):
                result = True
            self.rect = original_pos    # reset position
        return result

    def update(self):
        """Update PacMan's position in the maze if moving, and if not blocked"""
        if not self.dead:
            if self.direction and self.moving:
                if self.flip_status['use_horiz']:
                    self.image = self.horizontal_images.next_image()
                else:
                    self.image = self.vertical_images.next_image()
                if not self.is_blocked():
                    if self.direction == 'u':
                        self.rect.centery -= self.speed
                    elif self.direction == 'l':
                        self.rect.centerx -= self.speed
                    elif self.direction == 'd':
                        self.rect.centery += self.speed
                    elif self.direction == 'r':
                        self.rect.centerx += self.speed
                self.tile = (self.get_nearest_row(), self.get_nearest_col())
        else:
            self.image = self.death_images.next_image()

    def blit(self):
        """Blit the PacMan sprite to the screen"""
        self.screen.blit(self.image, self.rect)

    def eat(self):
        """Eat pellets from the maze and return the score accumulated"""
        score = 0
        fruit_count = 0
        power = None
        collision = pygame.sprite.spritecollideany(self, self.maze.pellets)
        if collision:
            collision.kill()
            score += 10
            self.sound_manager.play('eat')
        collision = pygame.sprite.spritecollideany(self, self.maze.fruits)
        if collision:
            collision.kill()
            score += 20
            fruit_count += 1
            self.sound_manager.play('fruit')
        collision = pygame.sprite.spritecollideany(self, self.maze.power_pellets)
        if collision:
            collision.kill()
            score += 20
            power = True
            self.sound_manager.play('eat')
        return score, fruit_count, power
Ejemplo n.º 4
0
class PacMan(pygame.sprite.Sprite):
    PAC_YELLOW = (255, 255, 0)
    PAC_AUDIO_CHANNEL = 0

    def __init__(self, screen, maze):
        super().__init__()
        self.screen = screen
        self.radius = maze.block_size // 5
        self.maze = maze
        self.sound_manager = SoundManager(sound_files=[
            'pacman-pellet-eat.wav', 'pacman-fruit-eat.wav',
            'pacman-killed.wav'
        ],
                                          keys=['eat', 'fruit', 'dead'],
                                          channel=PacMan.PAC_AUDIO_CHANNEL)
        self.horizontal_images = ImageManager('pacman-horiz.png',
                                              sheet=True,
                                              pos_offsets=[(0, 0, 32, 32),
                                                           (32, 0, 32, 32),
                                                           (0, 32, 32, 32),
                                                           (32, 32, 32, 32),
                                                           (0, 64, 32, 32)],
                                              resize=(self.maze.block_size,
                                                      self.maze.block_size),
                                              reversible=True)
        self.vertical_images = ImageManager('pacman-vert.png',
                                            sheet=True,
                                            pos_offsets=[(0, 0, 32, 32),
                                                         (32, 0, 32, 32),
                                                         (0, 32, 32, 32),
                                                         (32, 32, 32, 32),
                                                         (0, 64, 32, 32)],
                                            resize=(self.maze.block_size,
                                                    self.maze.block_size),
                                            reversible=True)
        self.death_images = ImageManager('pacman-death.png',
                                         sheet=True,
                                         pos_offsets=[(0, 0, 32, 32),
                                                      (32, 0, 32, 32),
                                                      (0, 32, 32, 32),
                                                      (32, 32, 32, 32),
                                                      (0, 64, 32, 32),
                                                      (32, 64, 32, 32)],
                                         resize=(self.maze.block_size,
                                                 self.maze.block_size),
                                         animation_delay=150,
                                         repeat=False)
        self.flip_status = {
            'use_horiz': True,
            'h_flip': False,
            'v_flip': False
        }
        self.spawn_info = self.maze.player_spawn[1]
        self.tile = self.maze.player_spawn[0]
        self.direction = None
        self.moving = False
        self.speed = maze.block_size // 7
        self.image, self.rect = self.horizontal_images.get_image()
        self.rect.centerx, self.rect.centery = self.spawn_info  # screen coordinates for spawn
        self.dead = False

        # Keyboard related events/actions/releases
        self.event_map = {
            pygame.KEYDOWN: self.perform_action,
            pygame.KEYUP: self.reset_direction
        }
        self.action_map = {
            pygame.K_UP: self.set_move_up,
            pygame.K_LEFT: self.set_move_left,
            pygame.K_DOWN: self.set_move_down,
            pygame.K_RIGHT: self.set_move_right
        }

    def set_death(self):
        self.sound_manager.play('dead')
        self.dead = True
        self.image, _ = self.death_images.get_image()

    def revive(self):
        self.dead = False
        self.image, _ = self.horizontal_images.get_image()
        self.death_images.image_index = 0

    def reset_position(self):
        self.rect.centerx, self.rect.centery = self.spawn_info  # screen coordinates for spawn

    def reset_direction(self, event):
        if event.key in (pygame.K_UP, pygame.K_DOWN, pygame.K_LEFT,
                         pygame.K_RIGHT):
            self.moving = False

    def perform_action(self, event):
        if event.key in self.action_map:
            self.action_map[event.key]()

    def set_move_up(self):
        if self.direction != 'u':
            self.direction = 'u'
            if self.flip_status['v_flip']:
                self.vertical_images.flip(False, True)
                self.flip_status['v_flip'] = False
            self.flip_status['use_horiz'] = False
        self.moving = True

    def set_move_left(self):
        if self.direction != 'l':
            self.direction = 'l'
            if not self.flip_status['h_flip']:
                self.horizontal_images.flip()
                self.flip_status['h_flip'] = True
            self.flip_status['use_horiz'] = True
        self.moving = True

    def set_move_down(self):
        if self.direction != 'd':
            self.direction = 'd'
            if not self.flip_status['v_flip']:
                self.vertical_images.flip(x_bool=False, y_bool=True)
                self.flip_status['v_flip'] = True
            self.flip_status['use_horiz'] = False
        self.moving = True

    def set_move_right(self):
        if self.direction != 'r':
            self.direction = 'r'
            if self.flip_status['h_flip']:
                self.horizontal_images.flip()
                self.flip_status['h_flip'] = False
            self.flip_status['use_horiz'] = True
        self.moving = True

    def get_nearest_col(self):
        return (self.rect.x -
                (self.screen.get_width() // 5)) // self.maze.block_size

    def get_nearest_row(self):
        return (self.rect.y -
                (self.screen.get_height() // 12)) // self.maze.block_size

    def is_blocked(self):
        result = False
        if self.direction is not None and self.moving:
            original_pos = self.rect
            if self.direction == 'u':
                test = self.rect.move((0, -self.speed))
            elif self.direction == 'l':
                test = self.rect.move((-self.speed, 0))
            elif self.direction == 'd':
                test = self.rect.move((0, self.speed))
            else:
                test = self.rect.move((self.speed, 0))
            self.rect = test

            if pygame.sprite.spritecollideany(self, self.maze.maze_blocks):
                result = True
            elif pygame.sprite.spritecollideany(self, self.maze.shield_blocks):
                result = True
            self.rect = original_pos
        return result

    def update(self):
        if not self.dead:
            if self.direction and self.moving:
                if self.flip_status['use_horiz']:
                    self.image = self.horizontal_images.next_image()
                else:
                    self.image = self.vertical_images.next_image()
                if not self.is_blocked():
                    if self.direction == 'u':
                        self.rect.centery -= self.speed
                    elif self.direction == 'l':
                        self.rect.centerx -= self.speed
                    elif self.direction == 'd':
                        self.rect.centery += self.speed
                    elif self.direction == 'r':
                        self.rect.centerx += self.speed
                self.tile = (self.get_nearest_row(), self.get_nearest_col())
        else:
            self.image = self.death_images.next_image()

    def blit(self):
        self.screen.blit(self.image, self.rect)

    def eat(self):
        score = 0
        fruit_count = 0
        power = None
        collision = pygame.sprite.spritecollideany(self, self.maze.pellets)
        if collision:
            collision.kill()
            score += 10
            self.sound_manager.play('eat')
        collision = pygame.sprite.spritecollideany(self, self.maze.fruits)
        if collision:
            collision.kill()
            score += 20
            fruit_count += 1
            self.sound_manager.play('fruit')
        collision = pygame.sprite.spritecollideany(self,
                                                   self.maze.power_pellets)
        if collision:
            collision.kill()
            score += 20
            power = True
            self.sound_manager.play('eat')
        return score, fruit_count, power