Пример #1
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)
Пример #2
0
    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)
Пример #3
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
Пример #4
0
    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
Пример #5
0
    def on_artifact_grabbed(self):
        if self.artifact.grabbed:
            player = self.engine.player
            player.block_events = True
            player.velocity = (0, 0)
            player.fall()

            timer = Timer(1000, self.engine.next_level, one_shot=True)
            timer.start()
Пример #6
0
    def on_container_removed(self):
        self.container.collidable = False

        # Go collect the artifact!
        player = self.level.engine.player
        player.jump()

        timer = Timer(200, self.hop_onto_platform, one_shot=True)
        timer.start()
Пример #7
0
    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)
Пример #8
0
    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()
Пример #9
0
    def on_container_added(self):
        player = self.level.engine.player
        self.questionmark = Sprite('questionmark')
        self.questionmark.collidable = False
        self.main_layer.add(self.questionmark)
        self.questionmark.move_to(
            player.rect.left +
            (player.rect.width - self.questionmark.rect.width) / 2,
            player.rect.top - self.questionmark.rect.height - 10)

        timer = Timer(300, self.hide_questionmark, one_shot=True)
        timer.start()
Пример #10
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()
Пример #11
0
    def show_container(self):
        player = self.level.engine.player
        player.velocity = (0, player.velocity[1])
        player.fall()

        show_effect = SlideShowEffect(self.container)
        show_effect.direction = Direction.UP
        show_effect.timer_ms = 30
        show_effect.total_time_ms = 500
        show_effect.stopped.connect(self.on_container_added)
        timer = Timer(700, show_effect.start, one_shot=True)
        timer.start()
Пример #12
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()
Пример #13
0
    def next_level(self):
        def on_timeout():
            widget.close()
            unload_images()
            self.switch_level(next_level)

        next_level = self.levels.index(self.active_level) + 1
        widget = self.ui_manager.show_textbox([
            'You got the artifact! %s left to go.'
            % (len(self.levels) - next_level),
        ])

        timer = Timer(2000, on_timeout, one_shot=True)
        timer.start()
Пример #14
0
    def next_level(self):
        def on_timeout():
            widget.close()
            unload_images()
            self.switch_level(next_level)

        next_level = self.levels.index(self.active_level) + 1
        widget = self.ui_manager.show_textbox([
            'You got the artifact! %s left to go.' %
            (len(self.levels) - next_level),
        ])

        timer = Timer(2000, on_timeout, one_shot=True)
        timer.start()
Пример #15
0
    def show_level(self, level):
        timeline_attrs = {"font": self.small_font, "padding_top": 20}

        widget = self.show_textbox(
            [
                ({"padding_top": 10}, level.name),
                [(timeline_attrs, time_period.name) for time_period in level.time_periods],
            ],
            line_spacing=0,
        )

        timer = Timer(2000, lambda: self.close(widget), one_shot=True)
        timer.start()

        return widget
Пример #16
0
    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
Пример #17
0
    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)
Пример #18
0
    def show_level(self, level):
        timeline_attrs = {
            'font': self.small_font,
            'padding_top': 20,
        }

        widget = self.show_textbox([({
            'padding_top': 10
        }, level.name),
                                    [(timeline_attrs, time_period.name)
                                     for time_period in level.time_periods]],
                                   line_spacing=0)

        timer = Timer(2000, lambda: self.close(widget), one_shot=True)
        timer.start()

        return widget
Пример #19
0
    def on_platforms_button_pressed(self):
        if self.platforms_on:
            return

        for platform in self.platforms:
            platform.power_on()

        self.platforms_on = True
        self.platforms_timer = Timer(self.PLATFORM_DELAY_TIME,
                                     self.next_platform)
Пример #20
0
    def prepare_launch(self):
        player = self.level.engine.player
        self.explosion = ExplosionParticleSystem(self)
        self.explosion.max_lifetime = 1
        self.explosion.min_lifetime = 0.5
        self.explosion.min_particles = 30
        self.explosion.max_particles = 40
        self.explosion.max_scale = 0.4
        self.explosion.min_angle = -(4 * math.pi) / 3
        self.explosion.max_angle = -(5 * math.pi) / 3
        self.explosion.repeat = True
        self.explosion.start(self.container.rect.centerx,
                             self.large_probe.rect.bottom)

        shake_effect = ShakeEffect(self.large_probe)
        shake_effect.start()

        timer = Timer(3000, self.launch_probe, one_shot=True)
        timer.start()
Пример #21
0
    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)
Пример #22
0
    def game_over(self):
        def on_timeout():
            widget.close()
            self._setup_game()
            #sys.exit(0)

        widget = self.ui_manager.show_textbox('Game Over')
        self.paused = True

        timer = Timer(2000, on_timeout, one_shot=True)
Пример #23
0
    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()
Пример #24
0
    def dead(self):
        def on_timeout():
            widget.close()
            self.restart_level()

        widget = self.ui_manager.show_textbox([
            "It's okay! You had another guy!",
            "%s lives left." % self.player.lives
        ])
        self.paused = True

        timer = Timer(2000, on_timeout, one_shot=True)
Пример #25
0
    def on_tick(self):
        if not self.engine.paused and self.engine.active_level == self:
            self.active_area.tick()

            if (len(self.time_periods) > 1 and
                len(self.crossovers) + len(self.pending_crossovers) <
                self.MAX_CROSSOVERS):
                crossover_id = self.next_crossover_id
                self.next_crossover_id += 1
                timer = Timer(
                    random.randint(*self.CROSSOVER_TIME_INTERVAL),
                    lambda: self.show_crossover(crossover_id),
                    one_shot=True)
                self.pending_crossovers[crossover_id] = timer
Пример #26
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)
Пример #27
0
    def show_crossover(self, crossover_id):
        def hide_crossover():
            crossover_sprite.remove()
            self.crossovers.remove((crossover_sprite, timer))

        self.pending_crossovers[crossover_id].stop()
        del self.pending_crossovers[crossover_id]

        key = self.active_area.key

        time_periods = [
            time_period.areas[key]
            for time_period in self.time_periods
            if (time_period != self.active_time_period and
                key in time_period.areas)
        ]

        if len(time_periods) - 1 <= 0:
            return

        i = random.randint(0, len(time_periods) - 1)


        crossover_sprite = Crossover(time_periods[i])
        crossover_sprite.rect = self.engine.camera.rect

        if random.randint(0, 5) <= 3:
            layer = self.active_area.bg_layer
        else:
            layer = self.active_area.main_layer

        layer.add(crossover_sprite)

        timer = Timer(500, hide_crossover, one_shot=True)
        timer.start()
        self.crossovers.append((crossover_sprite, timer))
Пример #28
0
    def open(self):
        self.name = self.platform_opening_name
        self.update_image()

        timer = Timer(self.OPENING_TIME, self.on_open_timeout, one_shot=True)
        timer.start()
Пример #29
0
    def close(self):
        self.name = self.platform_closing_name
        self.update_image()

        timer = Timer(self.CLOSING_TIME, self.on_close_timeout, one_shot=True)
        timer.start()
Пример #30
0
 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()
Пример #31
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()
Пример #32
0
    def launch_probe(self):
        self.large_probe.velocity = (0, -15)
        self.large_probe.moved.connect(self.move_explosion)

        timer = Timer(4000, self.probe_launched, one_shot=True)
        timer.start()
Пример #33
0
 def hop_onto_platform(self):
     player = self.level.engine.player
     player.velocity = (-player.MOVE_SPEED, player.velocity[1])
     timer = Timer(700, self.stop_moving, one_shot=True)
     timer.start()
Пример #34
0
 def start(self):
     self.timer = Timer(self.delay_ms, self.stop, one_shot=True)
Пример #35
0
 def stop_moving(self):
     timer = Timer(300, self.show_container, one_shot=True)
     timer.start()
Пример #36
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()
Пример #37
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()
Пример #38
0
 def start(self):
     self.timer = Timer(self.delay_ms, self.stop, one_shot=True)
Пример #39
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()
Пример #40
0
    def hide_questionmark(self):
        self.questionmark.remove()
        self.level.engine.player.direction = Direction.RIGHT

        timer = Timer(500, self.absorb_artifact, one_shot=True)
        timer.start()