示例#1
0
 def on_button_pressed(self, ev: ButtonPressed, signal) -> bool:
     d = (self.position - ev.position).length
     if d < 1.0:
         self.smooshed = True
         self.smoosh_time = 0.0
         self.pressed_time = get_time()
     return d < 1.0
示例#2
0
    def on_pre_render(self, update, signal):
        t = get_time()
        d = update.time_delta
        self.last_frame = t
        clear = []

        for i, tween in enumerate(self.tweens):
            if tween.start_time > t:
                continue
            if tween.start_value is None:
                tween.start_value = getattr(tween.obj, tween.attr)
            tr = (t - tween.start_time) / (tween.end_time - tween.start_time)
            tr = min(1.0, max(0.0, tr))
            tr = EASING[tween.easing](tr)
            value = lerp(tween.start_value, tween.end_value, tr)
            setattr(tween.obj, tween.attr, value)
            if tr >= 1.0:
                clear.append(i)

        for i in reversed(clear):
            del self.tweens[i]

        if not self.is_tweening:
            callbacks = self.callbacks[:]
            self.callbacks.clear()
            for func in callbacks:
                func()
示例#3
0
 def on_idle(self, idle_event: events.Idle, signal):
     t = get_time()
     if t >= self.target_clock:
         signal(events.PreRender(t - self.last_frame))
         signal(events.Render())
         self.target_clock = t + self.target_frame_length
         self.last_frame = t
示例#4
0
def debounce(obj, marker, delay):
    v = getattr(obj, marker, 0.0)
    t = get_time()
    if v + delay < t:
        setattr(obj, marker, t)
        return True
    else:
        return False
示例#5
0
    def __init__(self,
                 resolution=DEFAULT_RESOLUTION,
                 window_title: str = "PursuedPyBear",
                 target_frame_rate: int = 30,
                 target_camera_width=25,
                 **kwargs):
        self.resolution = resolution
        self.window = None
        self.window_title = window_title
        self.scene_cameras = {}
        self.target_camera_width = target_camera_width
        self.target_frame_rate = target_frame_rate
        self.target_frame_length = 1 / self.target_frame_rate
        self.target_clock = get_time() + self.target_frame_length
        self.last_frame = get_time()

        self._texture_cache = ObjectSideData()
示例#6
0
 def on_pre_render(self, ev, signal):
     self.layer = pos_to_layer(self.position)
     t = get_time()
     if self.absorbing > t or self.growing:
         s = (cos((self.absorbing - t + 1.0) * pi) + 1.0) * 0.5 + 0.5
         o = round(64 * s)
         self.root.opacity = o
     elif self.root.opacity > 0:
         self.root.opacity -= 1
示例#7
0
 def on_button_pressed(self, ev: ButtonPressed, signal):
     clicked = super().on_button_pressed(ev, signal)
     if clicked:
         # TODO: This is pretty cludging and won't always match the visual clouds
         self.cloud_radius = 0.5
         self.cloud_id = int(get_time() * 1000)
         tweening.tween(self,
                        "cloud_radius",
                        C.SMOOSHROOM_CLOUD_RADIUS_MAX,
                        C.SMOOSHROOM_CLOUD_RADIUS_TIME,
                        easing='quad_out')
示例#8
0
def test_failer_timed():
    failer = testutil.Failer(fail=lambda e: False,
                             message="Should time out",
                             run_time=0.1,
                             engine=None)

    start_time = get_time()

    while True:
        try:
            failer.on_idle(Idle(0.0), lambda x: None)
        except AssertionError as e:
            if e.args[0] == "Test ran too long.":
                end_time = get_time()
                break
            else:
                raise

    run_time = end_time - start_time

    assert abs(run_time - 0.1) <= 0.011
示例#9
0
    def start(self):
        """
        Starts the engine.

        Called by :meth:`GameEngine.run` before :meth:`GameEngine.main_loop`.

        You shouldn't call this yourself unless you're embedding :mod:`ppb` in
        another event loop.
        """
        self.running = True
        self._last_idle_time = get_time()
        self.activate({"scene_class": self.first_scene,
                       "kwargs": self.scene_kwargs})
示例#10
0
 def on_viking_death(self, ev, signal):
     v = ev.viking.position
     d = (self.position - v).length
     if d < self.absorb_radius and not ev.claimed:
         self.absorbing = get_time() + 5.0
         signal(ParticleSpawnerCreate(
             source=(v + ppb.Vector(-1, -0.4), v),
             dest=(v + ppb.Vector(-0.9, 1.25), v + ppb.Vector(-0.1, 1)),
             color=COLOR['YELLOW'],
             lifespan=5.0,
         ))
         delay(5.0, lambda: signal(ScorePoints(1)))
         delay(5.0, lambda: signal(CreateFloatingNumber(1, ev.viking.position + ppb.Vector(0, 1), COLOR['YELLOW'])))
         ev.claimed = True
示例#11
0
    def on_update(self, ev: Update, signal):
        # If the mushroom is being smooshed and it has toxins to squish...
        if self.toxins and self.smooshed:

            # Set smoosh frame
            t = tweening.EASING['quad_out'](self.smoosh_time)
            assert 0.0 <= t <= 1.0
            i = tweening.lerp(0, 3, t)
            self.image = MUSHROOM_SPRITES[i]

            # Accumulate cloud counter from toxin counter
            self.smoosh_time = min(1.0, self.smoosh_time + ev.time_delta)
            self.toxins = max(0.0, self.toxins - ev.time_delta)
            signal(MeterUpdate(self, 'toxins', self.toxins))
            self.cloud = self.cloud + ev.time_delta

            # If the cloud accumulator reaches threashold,
            # emit clouds and clear the accumulator.
            if self.cloud >= C.SMOOSHROOM_TOXIN_DMG_RATE:
                signal(EmitCloud(self.position, self.cloud_id))
                self.pressed_time = get_time()
                self.cloud -= C.SMOOSHROOM_TOXIN_DMG_RATE

                for viking in ev.scene.get(tag='viking'):
                    d = (viking.position - self.position).length
                    if d <= self.cloud_radius + 0.5:
                        viking.on_mushroom_attack(
                            MushroomAttack(get_time(), viking, scene=ev.scene),
                            signal)

        # If the mushroom isn't being smooshed, increase toxin accumulator
        # and reset the cloud accumulator.
        elif not self.smooshed and self.toxins < 1.0:
            self.toxins = min(
                1.0, self.toxins + ev.time_delta * C.SMOOSHROOM_TOXIN_CHARGE)
            self.cloud = 0.0
            signal(MeterUpdate(self, 'toxins', self.toxins))
示例#12
0
    def loop_once(self):
        """
        Iterate once.

        If you're embedding :mod:`ppb` in an external event loop call once per
        loop.
        """
        if not self.entered:
            raise ValueError("Cannot run before things have started",
                             self.entered)
        now = get_time()
        self.signal(events.Idle(now - self._last_idle_time))
        self._last_idle_time = now
        while self.events:
            self.publish()
示例#13
0
    def on_viking_attack(self, ev, signal):
        super().on_viking_attack(ev, signal)
        if ev.target is self:
            self.smooshed = True

            self.cloud += C.SMOOSHROOM_TOXIN_DMG_RATE
            self.toxins -= C.SMOOSHROOM_TOXIN_DMG_RATE
            self.cloud_radius = 0.5
            self.cloud_id = int(get_time() * 1000)
            tweening.tween(self,
                           "cloud_radius",
                           C.SMOOSHROOM_CLOUD_RADIUS_MAX,
                           C.SMOOSHROOM_CLOUD_RADIUS_TIME,
                           easing='quad_out')

            delay(0.25, lambda: setattr(self, 'smooshed', False))
示例#14
0
 def on_idle(cls, idle, signal):
     clear = []
     for t in list(cls.timers):
         if t.clear:
             clear.append(t)
         else:
             now = get_time()
             if now >= t.end_time:
                 if t.until is None or t.until > now:
                     t.callback()
                 if t.repeating > 0:
                     if t.until is None or t.until > now:
                         t.end_time += t.repeating
                         continue
                 clear.append(t)
     for t in clear:
         cls.timers.remove(t)
示例#15
0
    def start(self):
        """
        Starts the engine.

        Called by :meth:`GameEngine.run` before :meth:`GameEngine.main_loop`.

        You shouldn't call this yourself unless you're embedding :mod:`ppb` in
        another event loop.
        """
        self.running = True
        self._last_idle_time = get_time()
        if isinstance(self.first_scene, type):
            scene = self.first_scene(**self.scene_kwargs)
        else:
            scene = self.first_scene

        self._start_scene(scene, None)
示例#16
0
 def tween(self, entity, attr, *args, **kwargs):
     if len(args) == 2:
         end_value, duration = args
         start_value = getattr(entity, attr)
     elif len(args) == 3:
         start_value, end_value, duration = args
     delay = kwargs.pop('delay', 0)
     self.used = True
     start_time = get_time() + delay
     self.tweens.append(
         Tween(
             start_time=start_time,
             end_time=start_time + duration,
             obj=entity,
             attr=attr,
             start_value=start_value,
             end_value=end_value,
             **kwargs,
         ))
示例#17
0
 def delay(cls, seconds, func):
     t = Timer(get_time() + seconds, func)
     cls.timers.add(t)
     return t
示例#18
0
    def on_update(self, ev: Update, signal):
        self.state.on_update(self, ev, signal)

        if self.hp and 'shield' in self.parts:
            s = math.sin(get_time() * 4)
            self.parts['shield'].position = ppb.Vector(0.5, 0.05 - s * 0.1)
示例#19
0
 def __init__(self, name=None):
     self.name = name or f"tweener-{id(self)}"
     self.tweens = []
     self.callbacks = []
     self.last_frame = get_time()
示例#20
0
 def repeat(cls, seconds, func, until=None):
     n = get_time()
     t = Timer(n + seconds, func, repeating=seconds, until=n + until)
     cls.timers.add(t)
     return t