def __init__(self): super().__init__() self.image, self.rect = load_png('edge_top') self._image_sequence = { DOOR_TOP_LEFT: load_png_sequence(DOOR_TOP_LEFT), DOOR_TOP_RIGHT: load_png_sequence(DOOR_TOP_RIGHT) } self._door_open_animation = None self._door_close_animation = None self._open_queue = [] self._open_until = 0 self._update_count = 0 self.visible = True
def __init__(self, game, brick, png_prefix, speed=DEFAULT_FALL_SPEED): """ Initialise a new PowerUp. Args: game: The current game instance. brick: The brick that triggered the powerup to drop. png_prefix: The png file prefix that will be used to load the image sequence for the powerup animation. speed: Optional speed at which the powerup drops. Default 3 pixels per frame. """ super().__init__() self.game = game self._speed = speed self._animation = itertools.cycle( image for image, _ in load_png_sequence(png_prefix)) self._animation_start = 0 self.image = None # Position the powerup by the position of the brick which contained it. self.rect = pygame.Rect(brick.rect.bottomleft, (brick.rect.width, brick.rect.height)) # The area within which the powerup falls. screen = pygame.display.get_surface() self._area = screen.get_rect() # Visibility toggle. self.visible = True
def _load_animation_sequence(self, filename_prefix): sequence = load_png_sequence(filename_prefix) max_width, max_height = 0, 0 for image, rect in sequence: if rect.width > max_width: max_width = rect.width if rect.height > max_height: max_height = rect.height return itertools.cycle(sequence), max_width, max_height
def __init__(self, game, brick, png_prefix, speed = DEFAULT_FALL_SPEED): super().__init__() self.game = game self._speed = speed self._animation = itertools.cycle(image for image, _ in load_png_sequence(png_prefix)) self._animation_start = 0 self.image = None self.rect = pygame.Rect(brick.rect.bottomleft, (brick.rect.width, brick.rect.height)) screen = pygame.display.get_surface() self._area = screen.get_rect() self.visible = True
def __init__(self, on_start, sensor): self._sensor = sensor self._on_start = on_start # callback ptr self._screen = pygame.display.get_surface() self._init = False self._powerups = ((itertools.cycle(load_png_sequence('powerup_laser')), 'laser', 'enables the vaus\nto fire a laser'), (itertools.cycle(load_png_sequence('powerup_slow')), 'slow', 'slow down the\nenergy ball'), (itertools.cycle(load_png_sequence('powerup_life')), 'extra life', 'gain an additional\nvaus'), (itertools.cycle( load_png_sequence('powerup_expand')), 'expand', 'expands the vaus'), (itertools.cycle(load_png_sequence('powerup_catch')), 'catch', 'catches the energy\nball'), (itertools.cycle( load_png_sequence('powerup_duplicate')), 'duplicate', 'duplicates the energy\nball')) self._registered = False self._text_colors_1 = itertools.cycle([(255, 255, 255), (255, 255, 0)]) self._text_color_1 = None self._text_colors_2 = itertools.cycle([(255, 255, 0), (255, 0, 0)]) self._text_color_2 = None self._user_input = '' self._user_input_pos = None self._display_count = 0
def __init__(self, paddle, image_sequence_name): """Initialise with the name of the image sequence corresponding to each pulsating paddle frame. Args: paddle: The paddle. image_sequence_name: The name of theimage sequence representing each pulsating frame. """ self._paddle = paddle self._image_sequence = load_png_sequence(image_sequence_name) self._animation = None self._update_count = 0
def __init__(self, paddle): super().__init__(paddle) # Load the images/rects required for the expanding animation. self._image_sequence = load_png_sequence('paddle_wide') self._animation = iter(self._image_sequence) # The pulsating animation. self._pulsator = _PaddlePulsator(paddle, 'paddle_wide_pulsate') # Whether we're to expand or to shrink. self._expand, self._shrink = True, False # Exit callback. self._on_exit = None
def __init__(self, on_start): """Initialise the start screen. Args: on_start: Callback invoked when a player starts a new game. The callback should accept a single argument: the round number that the game will start at. """ self._on_start = on_start self._screen = pygame.display.get_surface() # Whether we've reinitialised the screen. self._init = False # The key for the powerups - their images with names and descriptions. self._powerups = ((itertools.cycle(load_png_sequence('powerup_laser')), 'laser', 'enables the vaus\nto fire a laser'), (itertools.cycle(load_png_sequence('powerup_slow')), 'slow', 'slow down the\nenergy ball'), (itertools.cycle(load_png_sequence('powerup_life')), 'extra life', 'gain an additional\nvaus'), ( itertools.cycle(load_png_sequence('powerup_expand')), 'expand', 'expands the vaus'), (itertools.cycle(load_png_sequence('powerup_catch')), 'catch', 'catches the energy\nball'), (itertools.cycle(load_png_sequence( 'powerup_duplicate')), 'duplicate', 'duplicates the energy\nball')) # Whether the event listeners have been registered. self._registered = False self._text_colors_1 = itertools.cycle([(255, 255, 255), (255, 255, 0)]) self._text_color_1 = None self._text_colors_2 = itertools.cycle([(255, 255, 0), (255, 0, 0)]) self._text_color_2 = None # The text entered by the user. self._user_input = '' self._user_input_pos = None # Keep track of display count for animation purposes. self._display_count = 0
def __init__(self, paddle, game): super().__init__(paddle) self._game = game # Load the images/rects for converting to a laser paddle. self._image_sequence = load_png_sequence('paddle_laser') self._laser_anim = iter(self._image_sequence) # Whether we're converting to or from a laser paddle. self._to_laser, self._from_laser = True, False # The pulsating animation. self._pulsator = _PaddlePulsator(paddle, 'paddle_laser_pulsate') # Track the number of laser bullets currently in the air. self._bullets = [] # Exit callback. self._on_exit = None
def __init__(self, paddle, on_exploded): """Initialise a new ExplodingState with the paddle and a no-args callback which gets called once the exploding animation is complete. Args: paddle: The paddle instance. on_exploded: The no-args callback used to notify the caller when the animation is complete. """ super().__init__(paddle) # Set up the exploding images. self._exploding_animation = iter(load_png_sequence('paddle_explode')) # The notification callback. self._on_explode_complete = on_exploded self._rect_orig = None # Keep track of update cycles for animation purposes. self._update_count = 0
def _load_animation_sequence(self, filename_prefix): """Load and return the image sequence for the animated sprite, and with it, the maximum width and height of the images in the sequence. Args: filename_prefix: The prefix of the image sequence. Returns: A 3-element tuple: the itertools.cycle object representing the animated sequence, the maximum width, the maximum height. """ sequence = load_png_sequence(filename_prefix) max_width, max_height = 0, 0 for image, rect in sequence: if rect.width > max_width: max_width = rect.width if rect.height > max_height: max_height = rect.height return itertools.cycle(sequence), max_width, max_height
def __init__(self, brick_colour, round_no, powerup_cls=None): super().__init__() self.colour = brick_colour self.image, self.rect = load_png('brick_{}'.format(brick_colour.name)) self._image_sequence = [ image for image, _ in load_png_sequence('brick_{}'.format( brick_colour.name)) ] self._animation = None self.collision_count = 0 self.powerup_cls = powerup_cls if brick_colour == BrickColour.silver: self.value = brick_colour.value * round_no else: self.value = brick_colour.value if brick_colour == BrickColour.silver: self._destroy_after = 3 elif brick_colour == BrickColour.gold: #self._destroy_after = -1 self._destroy_after = 5 #---- kong ---- else: self._destroy_after = 1
def explode(self): """Trigger an explosion of the enemy sprite.""" if not self._explode_animation: self._explode_animation = iter( load_png_sequence('enemy_explosion'))
def __init__(self, paddle): super().__init__(paddle) self._animation = iter(load_png_sequence('paddle_materialize')) self._update_count = 0
def __init__(self, brick_colour, round_no, powerup_cls=None): """Initialise a new Brick using the specified BrickColour enum. When a brick is initialised with the specified BrickColour, a file named 'brick_<colour>.png' will be loaded from the graphics folder - where <colour> corresponds to the name attribute of the BrickColour enum. That file must exist. In addition, the initialiser will also attempt to load an image sequence named 'brick_<colour>_N.png' from the graphics folder which will be used to animate the brick when Brick.animate() is called. This image sequence is optional, and if the files do not exist, then triggering Brick.animate() will have no effect. The round number must also be supplied which is used to generate the score value for certain brcks. Lastly, optionally specify the class of a powerup which will fall from the brick when the brick is struck by the ball - via the powerup_cls attribute. Args: brick_colour: A BrickColour enum instance. A png file named 'brick_<colour>.png' must exist in the graphics folder where <colour> corresponds to the enum name attribute. round_no: The current round number used to generate the brick score value. powerup_cls: Optional class of a PowerUp that will be used when the ball strikes this brick (default None). """ super().__init__() self.colour = brick_colour # Load the brick graphic. self.image, self.rect = load_png('brick_{}'.format(brick_colour.name)) # Load the images/rects required for any animation. self._image_sequence = [image for image, _ in load_png_sequence( 'brick_{}'.format(brick_colour.name))] self._animation = None # The number of ball collisions with this brick. self.collision_count = 0 # The class of the powerup. self.powerup_cls = powerup_cls # The score value for this brick. if brick_colour == BrickColour.silver: # The score for silver bricks is a product of the brick value # and round number. self.value = brick_colour.value * round_no else: self.value = brick_colour.value # The number of collisions before the brick gets destroyed. if brick_colour == BrickColour.silver: self._destroy_after = 2 elif brick_colour == BrickColour.gold: # Gold bricks are never destroyed. self._destroy_after = -1 else: self._destroy_after = 1
def __init__(self, brick_colour, round_no, powerup_cls=None): """Initialise a new Brick using the specified BrickColour enum. When a brick is initialised with the specified BrickColour, a file named 'brick_<colour>.png' will be loaded from the graphics folder - where <colour> corresponds to the name attribute of the BrickColour enum. That file must exist. In addition, the initialiser will also attempt to load an image sequence named 'brick_<colour>_N.png' from the graphics folder which will be used to animate the brick when Brick.animate() is called. This image sequence is optional, and if the files do not exist, then triggering Brick.animate() will have no effect. The round number must also be supplied which is used to generate the score value for certain brcks. Lastly, optionally specify the class of a powerup which will fall from the brick when the brick is struck by the ball - via the powerup_cls attribute. Args: brick_colour: A BrickColour enum instance. A png file named 'brick_<colour>.png' must exist in the graphics folder where <colour> corresponds to the enum name attribute. round_no: The current round number used to generate the brick score value. powerup_cls: Optional class of a PowerUp that will be used when the ball strikes this brick (default None). """ super().__init__() self.colour = brick_colour # Load the brick graphic. self.image, self.rect = load_png('brick_{}'.format(brick_colour.name)) # Load the images/rects required for any animation. self._image_sequence = [ image for image, _ in load_png_sequence('brick_{}'.format( brick_colour.name)) ] self._animation = None # The number of ball collisions with this brick. self.collision_count = 0 # The class of the powerup. self.powerup_cls = powerup_cls # The score value for this brick. if brick_colour == BrickColour.silver: # The score for silver bricks is a product of the brick value # and round number. self.value = brick_colour.value * round_no else: self.value = brick_colour.value # The number of collisions before the brick gets destroyed. if brick_colour == BrickColour.silver: self._destroy_after = 2 elif brick_colour == BrickColour.gold: # Gold bricks are never destroyed. self._destroy_after = -1 else: self._destroy_after = 1
def explode(self): if not self._explode_animation: self._explode_animation = iter( load_png_sequence('enemy_explosion'))