Exemplo n.º 1
0
class ScreenEffect(Effect):
    def __init__(self, layer, rect):
        super(ScreenEffect, self).__init__()
        self.rect = rect

        self.sprite = Sprite(None)
        self.sprite.image = pygame.Surface(rect.size).convert_alpha()
        self.sprite.move_to(*rect.topleft)

        if layer:
            layer.add(self.sprite)
Exemplo n.º 2
0
class Volcano(object):
    BASE_CAVERN_RECT = pygame.Rect(0, 310, 600, 57)

    def __init__(self):
        self.lava_pool = TiledSprite('65000000bc/lava_pool', 4, 1)
        self.lava_pool.lethal = True

        self.lava_puddle = Sprite('65000000bc/volcano_lava_puddle')
        self.lava_puddle.collidable = False

        self.lava_puddle_blocker = Box(10, self.BASE_CAVERN_RECT.height,
                                       (0, 0, 0))

        self.top_sprite = Sprite('65000000bc/volcano_top')
        self.top_sprite.use_pixel_collisions = True
        self.top_sprite.update_image()

        self.bottom_sprite = Sprite('65000000bc/volcano_bottom')
        self.bottom_sprite.update_image()

        self.cavern_blocker = Box(self.bottom_sprite.rect.width / 2,
                                  self.BASE_CAVERN_RECT.height, (0, 0, 0))

        self.column_sprite = Sprite('65000000bc/volcano_column')
        self.column_sprite.use_pixel_collisions = True
        self.column_sprite.update_image()

        self.cover_sprite = Sprite('65000000bc/volcano_cover')
        self.cover_sprite.collidable = False

        self.rect = pygame.Rect(0, 0, self.bottom_sprite.rect.width,
                                self.top_sprite.rect.height +
                                self.BASE_CAVERN_RECT.height +
                                self.bottom_sprite.rect.height)

    def add_to(self, area):
        self.eventbox = EventBox(area)
        self.eventbox.object_entered.connect(
            lambda x: self.cover_sprite.hide())
        self.eventbox.object_exited.connect(
            lambda x: self.cover_sprite.show())
        self.eventbox.watch_object_moves(area.engine.player)

        area.main_layer.add(self.lava_puddle_blocker)
        area.main_layer.add(self.cavern_blocker)
        area.main_layer.add(self.lava_puddle)
        area.main_layer.add(self.lava_pool)
        area.main_layer.add(self.top_sprite)
        area.main_layer.add(self.bottom_sprite)
        area.main_layer.add(self.column_sprite)
        area.fg_layer.add(self.cover_sprite)

    def move_to(self, x, y):
        self.rect.left = x
        self.rect.top = y

        self.lava_pool.move_to(x + 360, y + 10)
        self.top_sprite.move_to(x, y)
        self.column_sprite.move_to(
            x + 578, y + self.rect.height - self.column_sprite.rect.height)
        self.bottom_sprite.move_to(
            x, y + self.rect.height - self.bottom_sprite.rect.height)
        self.lava_puddle.move_to(
            x + 574,
            self.bottom_sprite.rect.top - self.lava_puddle.rect.height + 4)
        self.lava_puddle_blocker.move_to(
            self.lava_puddle.rect.right - 10,
            self.lava_puddle.rect.bottom - self.lava_puddle_blocker.rect.height)
        self.cavern_blocker.move_to(
            self.column_sprite.rect.right,
            self.bottom_sprite.rect.top - self.cavern_blocker.rect.height)
        self.cover_sprite.move_to(
            x, y + self.rect.height - self.cover_sprite.rect.height)

        self.eventbox.rects.append(
            pygame.Rect(x, y + self.BASE_CAVERN_RECT.top,
                        self.rect.width, self.BASE_CAVERN_RECT.height))
        self.eventbox.rects.append(self.column_sprite.rect)

    def clear_passage(self):
        self.column_sprite.remove()
        self.lava_puddle.remove()
        self.lava_puddle_blocker.remove()
        self.cavern_blocker.remove()
Exemplo n.º 3
0
class Mountain(object):
    LEFT_OFFSETS = [0, 90, 189, 239, 313]
    RIGHT_OFFSETS = [1427, 1236, 1208, 1121, 940]

    def __init__(self):
        self.bg_sprite = Sprite('mountain_bg')

        self.cover_sprite = Sprite('mountain_cover')
        self.cover_sprite.collidable = False

        self.bottom_sprite = Sprite('mountain_bottom')
        self.bottom_sprite.use_pixel_collisions = True
        self.bottom_sprite.update_image()

        self.top_sprite = Sprite('mountain_top')
        self.top_sprite.use_pixel_collisions = True
        self.top_sprite.update_image()

        self.left_sprites = []
        self.right_sprites = []

        for i in range(1, 6):
            sprite = Sprite('mountain_left_%s' % i)

            if i != 3:
                # Sort of a hack. We need a blocker so you can't
                # climb the mountain.
                sprite.use_pixel_collisions = True

            sprite.update_image()
            self.left_sprites.append(sprite)

            sprite = Sprite('mountain_right_%s' % i)
            sprite.use_pixel_collisions = True
            sprite.update_image()
            self.right_sprites.append(sprite)

        self.rect = pygame.Rect(
            0, 0, self.bottom_sprite.rect.width,
            sum([sprite.rect.height for sprite in self.right_sprites]) +
            self.top_sprite.rect.height + self.bottom_sprite.rect.height)

    def add_to(self, area):
        area.bg_layer.add(self.bg_sprite)
        area.main_layer.add(self.bottom_sprite)
        area.main_layer.add(self.top_sprite)
        area.fg_layer.add(self.cover_sprite)

        for sprite in self.left_sprites:
            area.main_layer.add(sprite)

        for sprite in self.right_sprites:
            area.main_layer.add(sprite)

        self.cave_eventbox = EventBox(area)
        self.cave_eventbox.object_moved.connect(
            self.on_cave_eventbox_moved)
        self.cave_eventbox.watch_object_moves(area.engine.player)

        self.floor_eventbox = EventBox(area)
        self.floor_eventbox.object_entered.connect(
            lambda x: self.cover_sprite.hide())
        self.floor_eventbox.watch_object_moves(area.engine.player)

    def move_to(self, x, y):
        self.rect.left = x
        self.rect.top = y

        self.cover_sprite.move_to(x, y)
        self.bg_sprite.move_to(x, y)
        self.top_sprite.move_to(x + 485, y)
        self.bottom_sprite.move_to(
            x, y + self.rect.height - self.bottom_sprite.rect.height)

        new_y = self.bottom_sprite.rect.top

        for i, sprite in enumerate(self.left_sprites):
            new_y = new_y - sprite.rect.height
            sprite.move_to(x + self.LEFT_OFFSETS[i], new_y)

        new_y = self.bottom_sprite.rect.top

        for i, sprite in enumerate(self.right_sprites):
            new_y = new_y - sprite.rect.height
            sprite.move_to(x + self.RIGHT_OFFSETS[i], new_y)

        self.cave_eventbox.rects.append(
            pygame.Rect(x + 382, y + 110, 157, 110))
        self.floor_eventbox.rects.append(
            pygame.Rect(x + 30, self.bottom_sprite.rect.top - 30,
                        self.rect.width - 60, 30))

    def on_cave_eventbox_moved(self, player):
        if player.rect.centerx <= self.cave_eventbox.rects[0].centerx:
            self.cover_sprite.show()
        else:
            self.cover_sprite.hide()
Exemplo n.º 4
0
class Mountain(object):
    LEFT_OFFSETS = [0, 90, 189, 239, 313]
    RIGHT_OFFSETS = [1427, 1236, 1208, 1121, 940]

    def __init__(self):
        self.bg_sprite = Sprite('mountain_bg')

        self.cover_sprite = Sprite('mountain_cover')
        self.cover_sprite.collidable = False

        self.bottom_sprite = Sprite('mountain_bottom')
        self.bottom_sprite.use_pixel_collisions = True
        self.bottom_sprite.update_image()

        self.top_sprite = Sprite('mountain_top')
        self.top_sprite.use_pixel_collisions = True
        self.top_sprite.update_image()

        self.left_sprites = []
        self.right_sprites = []

        for i in range(1, 6):
            sprite = Sprite('mountain_left_%s' % i)

            if i != 3:
                # Sort of a hack. We need a blocker so you can't
                # climb the mountain.
                sprite.use_pixel_collisions = True

            sprite.update_image()
            self.left_sprites.append(sprite)

            sprite = Sprite('mountain_right_%s' % i)
            sprite.use_pixel_collisions = True
            sprite.update_image()
            self.right_sprites.append(sprite)

        self.rect = pygame.Rect(
            0, 0, self.bottom_sprite.rect.width,
            sum([sprite.rect.height for sprite in self.right_sprites]) +
            self.top_sprite.rect.height + self.bottom_sprite.rect.height)

    def add_to(self, area):
        area.bg_layer.add(self.bg_sprite)
        area.main_layer.add(self.bottom_sprite)
        area.main_layer.add(self.top_sprite)
        area.fg_layer.add(self.cover_sprite)

        for sprite in self.left_sprites:
            area.main_layer.add(sprite)

        for sprite in self.right_sprites:
            area.main_layer.add(sprite)

        self.cave_eventbox = EventBox(area)
        self.cave_eventbox.object_moved.connect(self.on_cave_eventbox_moved)
        self.cave_eventbox.watch_object_moves(area.engine.player)

        self.floor_eventbox = EventBox(area)
        self.floor_eventbox.object_entered.connect(
            lambda x: self.cover_sprite.hide())
        self.floor_eventbox.watch_object_moves(area.engine.player)

    def move_to(self, x, y):
        self.rect.left = x
        self.rect.top = y

        self.cover_sprite.move_to(x, y)
        self.bg_sprite.move_to(x, y)
        self.top_sprite.move_to(x + 485, y)
        self.bottom_sprite.move_to(
            x, y + self.rect.height - self.bottom_sprite.rect.height)

        new_y = self.bottom_sprite.rect.top

        for i, sprite in enumerate(self.left_sprites):
            new_y = new_y - sprite.rect.height
            sprite.move_to(x + self.LEFT_OFFSETS[i], new_y)

        new_y = self.bottom_sprite.rect.top

        for i, sprite in enumerate(self.right_sprites):
            new_y = new_y - sprite.rect.height
            sprite.move_to(x + self.RIGHT_OFFSETS[i], new_y)

        self.cave_eventbox.rects.append(pygame.Rect(x + 382, y + 110, 157,
                                                    110))
        self.floor_eventbox.rects.append(
            pygame.Rect(x + 30, self.bottom_sprite.rect.top - 30,
                        self.rect.width - 60, 30))

    def on_cave_eventbox_moved(self, player):
        if player.rect.centerx <= self.cave_eventbox.rects[0].centerx:
            self.cover_sprite.show()
        else:
            self.cover_sprite.hide()
Exemplo n.º 5
0
class Player(Sprite):
    MOVE_SPEED = 6
    JUMP_SPEED = 6
    MAX_JUMP_HEIGHT = 100
    HOVER_TIME_MS = 1000

    MAX_HEALTH = 3
    MAX_LIVES = 3

    PROPULSION_BELOW_OFFSET = 8

    def __init__(self):
        super(Player, self).__init__('player', flip_image=True,
                                     obey_gravity=True)
        self.engine = get_engine()
        self.should_check_collisions = True

        # Sprites
        self.propulsion_below = Sprite("propulsion_below", flip_image=True)
        self.propulsion_below.collidable = False
        self.propulsion_below.visible = 0
        self.tractor_beam = TractorBeam(self)

        # State
        self.jumping = False
        self.hovering = False
        self.block_events = False
        self.jump_origin = None
        self.hover_time_ms = 0
        self.health = self.MAX_HEALTH
        self.lives = self.MAX_LIVES
        self.last_safe_spot = None
        self.vehicle = None
        self.vehicle_move_cnx = None

        # Signals
        self.health_changed = Signal()
        self.lives_changed = Signal()

        self.direction_changed.connect(self.on_direction_changed)
        self.reverse_gravity_changed.connect(self.on_reverse_gravity_changed)

    def handle_event(self, event):
        if self.block_events:
            return

        if event.type == KEYDOWN:
            if event.key == K_RIGHT:
                self.move_right()
            elif event.key == K_LEFT:
                self.move_left()
            elif event.key == K_SPACE:
                self.jump()
            elif event.key in (K_LSHIFT, K_RSHIFT):
                self.start_tractor_beam()
        elif event.type == KEYUP:
            if event.key == K_LEFT:
                if self.velocity[0] < 0:
                    self.velocity = (0, self.velocity[1])
            elif event.key == K_RIGHT:
                if self.velocity[0] > 0:
                    self.velocity = (0, self.velocity[1])
            elif event.key == K_SPACE:
                self.fall()
            elif event.key in (K_LSHIFT, K_RSHIFT):
                self.stop_tractor_beam()

    def move_right(self):
        self.velocity = (self.MOVE_SPEED, self.velocity[1])

        if self.direction != Direction.RIGHT:
            self.direction = Direction.RIGHT
            self.tractor_beam.direction = Direction.RIGHT
            self.update_image()

    def move_left(self):
        self.velocity = (-self.MOVE_SPEED, self.velocity[1])

        if self.direction != Direction.LEFT:
            self.direction = Direction.LEFT
            self.tractor_beam.direction = Direction.LEFT
            self.update_image()

    def start_tractor_beam(self):
        self.tractor_beam.show()
        self.tractor_beam.update_position(self)
        self.calculate_collision_rects()

    def stop_tractor_beam(self):
        self.tractor_beam.ungrab()
        self.tractor_beam.hide()
        self.calculate_collision_rects()

    def ride(self, vehicle):
        self.vehicle = vehicle
        self.velocity = (self.velocity[0], 0)
        self.vehicle_moved_cnx = \
            self.vehicle.moved.connect(self.on_vehicle_moved)
        self.calculate_collision_rects()

    def jump(self):
        if (self.falling and not self.engine.god_mode) or self.jumping:
            return

        self.jump_origin = (self.rect.left, self.rect.top)
        self.jumping = True
        self.falling = False

        if self.reverse_gravity:
            self.velocity = (self.velocity[0], self.JUMP_SPEED)
        else:
            self.velocity = (self.velocity[0], -self.JUMP_SPEED)

        self.propulsion_below.show()
        self.stop_riding()

    def reset_gravity(self):
        if self.reverse_gravity:
            self.reverse_gravity = False

            if self.falling:
                # Reset the fall
                self.falling = False
                self.fall()

            self.update_image()

    def stop_riding(self):
        if self.vehicle:
            self.vehicle_moved_cnx.disconnect()
            self.vehicle = None
            self.calculate_collision_rects()

    def fall(self):
        if self.falling:
            return

        self.propulsion_below.hide()
        self.jumping = False
        self.hovering = False
        super(Player, self).fall()

    def hover(self):
        if self.hovering:
            return

        self.propulsion_below.show()
        self.jumping = False
        self.hovering = True
        self.hover_time_ms = 0
        self.velocity = (self.velocity[0], 0)

    def calculate_collision_rects(self):
        self.collision_masks = []
        self.collision_rects = [self.rect]

        if self.tractor_beam.item:
            self.collision_rects.append(self.tractor_beam.item.rect)

        if self.vehicle:
            self.collision_rects.append(self.vehicle.rect)

    def check_collisions(self, *args, **kwargs):
        super(Player, self).check_collisions(*args, **kwargs)

    def should_adjust_position_with(self, obj, dx, dy):
        from foreverend.sprites.common import FloatingSprite

        return (obj != self.vehicle and
                (dx == 0 or not isinstance(obj, FloatingSprite)))

    def tick(self):
        if self.hovering:
            self.hover_time_ms += 1.0 / self.engine.FPS * 1000

            if self.hover_time_ms >= self.HOVER_TIME_MS:
                self.fall()

        super(Player, self).tick()

    def on_added(self, layer):
        for obj in (self.propulsion_below, self.tractor_beam, self.vehicle):
            if obj:
                layer.add(obj)

    def on_removed(self, layer):
        for obj in (self.propulsion_below, self.tractor_beam, self.vehicle):
            if obj:
                layer.remove(obj)

    def on_moved(self, dx, dy):
        if not self.last_safe_spot:
            self.last_safe_spot = self.rect.topleft

        self.rect.top = max(self.rect.top, 0)

        if self.rect.top > self.layer.area.size[1]:
            self.on_dead()
            return

        if (self.jumping and
            not self.engine.god_mode and
            ((not self.reverse_gravity and
              self.jump_origin[1] - self.rect.top >= self.MAX_JUMP_HEIGHT) or
             (self.reverse_gravity and
              self.rect.top - self.jump_origin[1] >= self.MAX_JUMP_HEIGHT))):
            self.hover()

        if self.propulsion_below.visible:
            if self.direction == Direction.RIGHT:
                offset = self.PROPULSION_BELOW_OFFSET
            if self.direction == Direction.LEFT:
                offset = self.rect.width - self.propulsion_below.rect.width - \
                         self.PROPULSION_BELOW_OFFSET

            if self.reverse_gravity:
                y = self.rect.top - self.propulsion_below.rect.height
            else:
                y = self.rect.bottom

            self.propulsion_below.move_to(self.rect.left + offset, y)

        if self.tractor_beam.visible:
            self.tractor_beam.update_position(self)

        if self.vehicle and dx != 0:
            self.vehicle.move_to(
                self.rect.left -
                (self.vehicle.rect.width - self.rect.width) / 2,
                self.vehicle.rect.top)

        self.calculate_collision_rects()

        super(Player, self).on_moved(dx, dy)

    def on_collision(self, dx, dy, obj, self_rect, obj_rect):
        if obj.lethal and not self.engine.god_mode and self_rect == self.rect:
            self.on_hit()
            return

        self.last_safe_spot = self.rect.topleft

        if self.tractor_beam.item and self_rect == self.tractor_beam.item.rect:
            move_player = True

            if self.tractor_beam.adjust_item_position(obj_rect):
                move_player = False

            if move_player:
                if self.direction == Direction.LEFT:
                    self.move_to(obj_rect.right +
                                 (self.rect.left -
                                  self.tractor_beam.item.rect.left),
                                 self.rect.top)
                elif self.direction == Direction.RIGHT:
                    self.move_to(obj_rect.left -
                                 (self.tractor_beam.item.rect.right -
                                  self.rect.left),
                                 self.rect.top)

        if dy > 0 and not self.vehicle and isinstance(obj, Vehicle):
            self.ride(obj)

        if self.jumping and dy < 0:
            self.fall()
        else:
            super(Player, self).on_collision(dx, dy, obj, self_rect, obj_rect)

    def on_direction_changed(self):
        if self.vehicle:
            self.vehicle.direction = self.direction

    def on_reverse_gravity_changed(self):
        self.propulsion_below.set_reverse_gravity(self.reverse_gravity)
        self.tractor_beam.set_reverse_gravity(self.reverse_gravity)

        if self.tractor_beam.item:
            self.tractor_beam.item.set_reverse_gravity(self.reverse_gravity)

        self.fall()

    def on_vehicle_moved(self, dx, dy):
        if dy != 0:
            self.move_by(0, dy)

    def on_hit(self):
        self.health -= 1
        self.health_changed.emit()

        if self.health == 0:
            self.on_dead()
        else:
            self.move_to(*self.last_safe_spot)
            self.velocity = (0, 0)
            self.falling = False
            self.fall()

    def on_dead(self):
        self.lives -= 1
        self.lives_changed.emit()
        self.velocity = (0, 0)

        if self.lives == 0:
            self.engine.game_over()
        else:
            self.health = self.MAX_HEALTH
            self.health_changed.emit()
            self.engine.dead()