示例#1
0
class Effect(object):
    def __init__(self):
        self.timer = None
        self.timer_ms = 150

        # Signals
        self.started = Signal()
        self.stopped = Signal()

    def pre_start(self):
        pass

    def pre_stop(self):
        pass

    def start(self):
        assert not self.timer
        self.pre_start()
        self.timer = Timer(self.timer_ms, self.on_tick)
        self.timer.start()
        self.started.emit()

    def stop(self):
        assert self.timer
        self.pre_stop()
        self.timer.stop()
        self.timer = None
        self.stopped.emit()

    def on_tick(self):
        pass
示例#2
0
class IceBoulder(Sprite):
    MELT_AMOUNT = 5

    def __init__(self, *args, **kwargs):
        super(IceBoulder, self).__init__('12000bc/ice_boulder', *args,
                                         **kwargs)
        #self.use_pixel_collisions = True
        self.melting = False

    def melt(self, x, y):
        self.explosion = FlameThrowerParticleSystem(self.layer.area)
        self.explosion.start(x, y)
        self.explosion.repeat = True

        self.timer = Timer(60, self.on_melt_timer)
        self.melting = True

    def on_melt_timer(self):
        new_height = self.image.get_height() - self.MELT_AMOUNT

        if new_height <= 0:
            self.timer.stop()
            self.explosion.stop()
            self.remove()
        else:
            self.image = self.image.subsurface(
                pygame.Rect(0, 0, self.image.get_width(), new_height))
            self.move_to(self.rect.left, self.rect.top + self.MELT_AMOUNT)

    def handle_collision(self, obj, *args, **kwargs):
        if (not self.melting and isinstance(obj, Player)
                and obj.tractor_beam.item
                and isinstance(obj.tractor_beam.item, FlameThrower)):
            flamethrower = obj.tractor_beam.item
            self.melt(flamethrower.rect.right, flamethrower.rect.centery)
示例#3
0
class DelayPage(Page):
    def __init__(self, delay_ms):
        super(DelayPage, self).__init__()
        self.delay_ms = delay_ms
        self.timer = None

    def start(self):
        self.timer = Timer(self.delay_ms, self.stop, one_shot=True)

    def stop(self):
        self.timer.stop()
        self.done.emit()
示例#4
0
class DelayPage(Page):
    def __init__(self, delay_ms):
        super(DelayPage, self).__init__()
        self.delay_ms = delay_ms
        self.timer = None

    def start(self):
        self.timer = Timer(self.delay_ms, self.stop, one_shot=True)

    def stop(self):
        self.timer.stop()
        self.done.emit()
示例#5
0
class IceBoulder(Sprite):
    MELT_AMOUNT = 5

    def __init__(self, *args, **kwargs):
        super(IceBoulder, self).__init__("12000bc/ice_boulder", *args, **kwargs)
        # self.use_pixel_collisions = True
        self.melting = False

    def melt(self, x, y):
        self.explosion = FlameThrowerParticleSystem(self.layer.area)
        self.explosion.start(x, y)
        self.explosion.repeat = True

        self.timer = Timer(60, self.on_melt_timer)
        self.melting = True

    def on_melt_timer(self):
        new_height = self.image.get_height() - self.MELT_AMOUNT

        if new_height <= 0:
            self.timer.stop()
            self.explosion.stop()
            self.remove()
        else:
            self.image = self.image.subsurface(pygame.Rect(0, 0, self.image.get_width(), new_height))
            self.move_to(self.rect.left, self.rect.top + self.MELT_AMOUNT)

    def handle_collision(self, obj, *args, **kwargs):
        if (
            not self.melting
            and isinstance(obj, Player)
            and obj.tractor_beam.item
            and isinstance(obj.tractor_beam.item, FlameThrower)
        ):
            flamethrower = obj.tractor_beam.item
            self.melt(flamethrower.rect.right, flamethrower.rect.centery)
示例#6
0
class Outside65000000BC(Level1Area):
    def draw_bg(self, surface):
        surface.fill((0, 0, 0))

    def setup(self):
        self.exploding = False
        self.exploded = False

        ground = TiledSprite("ground", self.size[0] / 32, 1)
        self.main_layer.add(ground)
        ground.move_to(0, self.size[1] - ground.rect.height)

        hills = Sprite("65000000bc/hills_1")
        self.bg_layer.add(hills)
        hills.move_to(0, ground.rect.top - hills.rect.height)

        # Volcano
        self.volcano = Volcano()
        self.volcano.add_to(self)
        self.volcano.move_to(1400, ground.rect.top - self.volcano.rect.height + 1)

        blocker = Box(150, self.size[1] - self.volcano.rect.height - 20, (0, 0, 0, 0))
        self.main_layer.add(blocker)
        blocker.move_to(self.volcano.lava_pool.rect.right - 100, 0)

        # Left-side lava pool
        lava_pool = TiledSprite("65000000bc/lava_pool", 5, 1)
        lava_pool.lethal = True
        self.main_layer.add(lava_pool)
        lava_pool.move_to(self.volcano.rect.left - lava_pool.rect.width - 100, ground.rect.top - 18)

        # Platforms
        platform = FloatingSprite("65000000bc/platform")
        self.main_layer.add(platform)
        platform.move_to(lava_pool.rect.left + 250, lava_pool.rect.top - 10)

        platform = FloatingSprite("65000000bc/platform")
        self.main_layer.add(platform)
        platform.move_to(lava_pool.rect.left + 500, lava_pool.rect.top - 8)

        platform = FloatingSprite("65000000bc/platform")
        self.main_layer.add(platform)
        platform.move_to(lava_pool.rect.left + 750, lava_pool.rect.top - 12)

        # Right-side lava pool
        lava_pool = TiledSprite("65000000bc/lava_pool", 3, 1)
        lava_pool.lethal = True
        self.main_layer.add(lava_pool)
        lava_pool.move_to(self.volcano.rect.right + 200, ground.rect.top - 18)

        # Dynamite explosion trigger
        explosion_box = EventBox(self)
        explosion_box.rects.append(
            pygame.Rect(
                self.volcano.lava_puddle.rect.x,
                self.volcano.lava_puddle.rect.bottom - 5,
                self.volcano.lava_puddle.rect.width,
                5,
            )
        )
        explosion_box.watch_object_moves(self.level.dynamite)
        explosion_box.object_entered.connect(self.on_dynamite_placed)

        # Artifact
        self.level.add_artifact(self, lava_pool.rect.right + 200, ground.rect.top)

    def on_dynamite_placed(self, obj):
        assert obj == self.level.dynamite

        if self.exploding or self.exploded:
            return

        self.level.dynamite.light()
        self.exploding = True

        self.detonate_timer = Timer(1000, self.start_explosion)

    def start_explosion(self):
        self.detonate_timer.stop()
        self.detonate_timer = None

        self.level.dynamite.remove()
        self.level.dynamite = None

        self.explosion = ExplosionParticleSystem(self)
        self.explosion.start(2040, 1500)

        self.explosion_timer = Timer(350, self.on_explosion_done)
        self.explosion_timer.start()

    def on_explosion_done(self):
        self.explosion_timer.stop()
        self.explosion_timer = None
        self.exploding = False
        self.exploded = True
        self.volcano.clear_passage()
示例#7
0
class Outside65000000BC(Level1Area):
    def draw_bg(self, surface):
        surface.fill((0, 0, 0))

    def setup(self):
        self.exploding = False
        self.exploded = False

        ground = TiledSprite('ground', self.size[0] / 32, 1)
        self.main_layer.add(ground)
        ground.move_to(0, self.size[1] - ground.rect.height)

        hills = Sprite('65000000bc/hills_1')
        self.bg_layer.add(hills)
        hills.move_to(0, ground.rect.top - hills.rect.height)

        # Volcano
        self.volcano = Volcano()
        self.volcano.add_to(self)
        self.volcano.move_to(
            1400, ground.rect.top - self.volcano.rect.height + 1)

        blocker = Box(150, self.size[1] - self.volcano.rect.height - 20,
                      (0, 0, 0, 0))
        self.main_layer.add(blocker)
        blocker.move_to(self.volcano.lava_pool.rect.right - 100, 0)

        # Left-side lava pool
        lava_pool = TiledSprite('65000000bc/lava_pool', 5, 1)
        lava_pool.lethal = True
        self.main_layer.add(lava_pool)
        lava_pool.move_to(self.volcano.rect.left - lava_pool.rect.width - 100,
                          ground.rect.top - 18)

        # Platforms
        platform = FloatingSprite('65000000bc/platform')
        self.main_layer.add(platform)
        platform.move_to(lava_pool.rect.left + 250, lava_pool.rect.top - 10)

        platform = FloatingSprite('65000000bc/platform')
        self.main_layer.add(platform)
        platform.move_to(lava_pool.rect.left + 500, lava_pool.rect.top - 8)

        platform = FloatingSprite('65000000bc/platform')
        self.main_layer.add(platform)
        platform.move_to(lava_pool.rect.left + 750, lava_pool.rect.top - 12)

        # Right-side lava pool
        lava_pool = TiledSprite('65000000bc/lava_pool', 3, 1)
        lava_pool.lethal = True
        self.main_layer.add(lava_pool)
        lava_pool.move_to(self.volcano.rect.right + 200,
                          ground.rect.top - 18)

        # Dynamite explosion trigger
        explosion_box = EventBox(self)
        explosion_box.rects.append(
            pygame.Rect(self.volcano.lava_puddle.rect.x,
                        self.volcano.lava_puddle.rect.bottom - 5,
                        self.volcano.lava_puddle.rect.width,
                        5))
        explosion_box.watch_object_moves(self.level.dynamite)
        explosion_box.object_entered.connect(self.on_dynamite_placed)

        # Artifact
        self.level.add_artifact(self, lava_pool.rect.right + 200,
                                ground.rect.top)

    def on_dynamite_placed(self, obj):
        assert obj == self.level.dynamite

        if self.exploding or self.exploded:
            return

        self.level.dynamite.light()
        self.exploding = True

        self.detonate_timer = Timer(1000, self.start_explosion)

    def start_explosion(self):
        self.detonate_timer.stop()
        self.detonate_timer = None

        self.level.dynamite.remove()
        self.level.dynamite = None

        self.explosion = ExplosionParticleSystem(self)
        self.explosion.start(2040, 1500)

        self.explosion_timer = Timer(350, self.on_explosion_done)
        self.explosion_timer.start()

    def on_explosion_done(self):
        self.explosion_timer.stop()
        self.explosion_timer = None
        self.exploding = False
        self.exploded = True
        self.volcano.clear_passage()
示例#8
0
class ParticleSystem(object):
    def __init__(self, area):
        # Settings
        self.particle_filename = None
        self.min_particles = 0
        self.max_particles = 0
        self.min_initial_speed = 0
        self.max_initial_speed = 0
        self.min_acceleration = 0
        self.max_acceleration = 0
        self.min_lifetime = 0
        self.max_lifetime = 0
        self.min_scale = 0
        self.max_scale = 0
        self.min_rotation_speed = 0
        self.max_rotation_speed = 0
        self.min_angle = 0
        self.max_angle = 2 * math.pi
        self.repeat = False

        # State
        self.area = area
        self.image = None
        self.particles = []
        self.free_particles = []
        self.pos = None

        self.timer = Timer(60, self.on_particle_update)

    def start(self, x, y):
        assert self.pos is None
        self.pos = (x, y)

        self.particles = []

        for i in range(self.max_particles):
            self.particles.append(Particle(self))

        self.free_particles = list(self.particles)

        if not self.image:
            self.image = load_image(self.particle_filename).convert_alpha()

        self.add_particles()
        self.area.particle_systems.append(self)
        self.timer.start()

    def add_particles(self):
        num_particles = random.randint(self.min_particles, self.max_particles)

        for i in range(num_particles):
            if self.free_particles:
                self.setup_particle(self.free_particles.pop())

    def stop(self):
        self.timer.stop()
        self.pos = None
        self.area.particle_systems.remove(self)
        self.particles = []
        self.free_particles = []

    def setup_particle(self, particle):
        direction = self.random_direction()

        velocity = self.random_float(self.min_initial_speed,
                                     self.max_initial_speed)
        particle.velocity = (velocity * direction[0],
                             velocity * direction[1])

        acceleration = self.random_float(self.min_acceleration,
                                         self.max_acceleration)
        particle.acceleration = (acceleration * direction[0],
                                 acceleration * direction[1])

        particle.lifetime = self.random_float(self.min_lifetime,
                                              self.max_lifetime)
        particle.scale = self.random_float(self.min_scale,
                                           self.max_scale)
        particle.rotation_speed = \
            self.random_float(self.min_rotation_speed,
                              self.max_rotation_speed)
        particle.pos = self.pos
        particle.elapsed_time = 0.0
        particle.rotation = self.random_float(0.0, 360.0)

    def random_direction(self):
        angle = self.random_float(self.min_angle, self.max_angle)
        return (math.cos(angle), math.sin(angle))

    def random_float(self, min_value, max_value):
        return min_value + random.random() * (max_value - min_value)

    def draw(self, surface):
        for particle in self.particles:
            if particle.active:
                particle.draw(surface)

    def on_particle_update(self):
        active_count = 0

        for particle in self.particles:
            if particle.active:
                active_count += 1
                particle.update(self.timer.ms / 1000.0)

                if not particle.active:
                    self.free_particles.append(particle)

        if not self.repeat and active_count == 0:
            self.stop()
        elif self.repeat:
            self.add_particles()
示例#9
0
class ParticleSystem(object):
    def __init__(self, area):
        # Settings
        self.particle_filename = None
        self.min_particles = 0
        self.max_particles = 0
        self.min_initial_speed = 0
        self.max_initial_speed = 0
        self.min_acceleration = 0
        self.max_acceleration = 0
        self.min_lifetime = 0
        self.max_lifetime = 0
        self.min_scale = 0
        self.max_scale = 0
        self.min_rotation_speed = 0
        self.max_rotation_speed = 0
        self.min_angle = 0
        self.max_angle = 2 * math.pi
        self.repeat = False

        # State
        self.area = area
        self.image = None
        self.particles = []
        self.free_particles = []
        self.pos = None

        self.timer = Timer(60, self.on_particle_update)

    def start(self, x, y):
        assert self.pos is None
        self.pos = (x, y)

        self.particles = []

        for i in range(self.max_particles):
            self.particles.append(Particle(self))

        self.free_particles = list(self.particles)

        if not self.image:
            self.image = load_image(self.particle_filename).convert_alpha()

        self.add_particles()
        self.area.particle_systems.append(self)
        self.timer.start()

    def add_particles(self):
        num_particles = random.randint(self.min_particles, self.max_particles)

        for i in range(num_particles):
            if self.free_particles:
                self.setup_particle(self.free_particles.pop())

    def stop(self):
        self.timer.stop()
        self.pos = None
        self.area.particle_systems.remove(self)
        self.particles = []
        self.free_particles = []

    def setup_particle(self, particle):
        direction = self.random_direction()

        velocity = self.random_float(self.min_initial_speed,
                                     self.max_initial_speed)
        particle.velocity = (velocity * direction[0], velocity * direction[1])

        acceleration = self.random_float(self.min_acceleration,
                                         self.max_acceleration)
        particle.acceleration = (acceleration * direction[0],
                                 acceleration * direction[1])

        particle.lifetime = self.random_float(self.min_lifetime,
                                              self.max_lifetime)
        particle.scale = self.random_float(self.min_scale, self.max_scale)
        particle.rotation_speed = \
            self.random_float(self.min_rotation_speed,
                              self.max_rotation_speed)
        particle.pos = self.pos
        particle.elapsed_time = 0.0
        particle.rotation = self.random_float(0.0, 360.0)

    def random_direction(self):
        angle = self.random_float(self.min_angle, self.max_angle)
        return (math.cos(angle), math.sin(angle))

    def random_float(self, min_value, max_value):
        return min_value + random.random() * (max_value - min_value)

    def draw(self, surface):
        for particle in self.particles:
            if particle.active:
                particle.draw(surface)

    def on_particle_update(self):
        active_count = 0

        for particle in self.particles:
            if particle.active:
                active_count += 1
                particle.update(self.timer.ms / 1000.0)

                if not particle.active:
                    self.free_particles.append(particle)

        if not self.repeat and active_count == 0:
            self.stop()
        elif self.repeat:
            self.add_particles()