Пример #1
0
    def __init__(self, window, map, startp, endp):
        self.window = window
        self.bg = retro.Stage(asset(map))

        self.ui = UI(self.window)

        self.spawner = Spawner(self.window, self.bg, startp)
        self.exit = retro.Sprite.from_path(asset("sortie.png"))
        self.exit.rect.topleft = endp
Пример #2
0
class Mine:
    ICON = retro.Image(asset("ui_mine.png"))

    def __init__(self, lemming):
        self.lemming = lemming

    def start(self):
        self.enabled = False
        return self

    def run(self):
        if not self.enabled:
            self.lemming.start_animation("MINE")
            self.enabled = True

        if not self.lemming.animations.finished:
            return

        self.lemming.bg.original.draw_circle(
            color=retro.BLACK,
            center=self.lemming.rect.center,
            radius=18,
        )

        dx = self.lemming.actions.walk.dx
        self.lemming.rect.move_ip(3 * dx, 3)
        self.lemming.start_animation("MINE")
Пример #3
0
class Bomb:
    ICON = retro.Image(asset("ui_bomb.png"))

    def __init__(self, lemming):
        self.lemming = lemming

    def start(self):
        self.ticker = retro.Ticker(end=135)
        self.explode = False
        return self

    def run(self):
        if not self.explode:
            self.lemming.start_animation("BOMB")
            self.explode = True

            self.lemming.bg.original.draw_circle(
                color=retro.BLACK,
                center=self.lemming.bounding_rect.midbottom,
                radius=20,
            )
        elif self.lemming.animations.finished:
            self.lemming.kill()

    def draw_ticker(self):
        if self.explode: return

        window = self.lemming.window
        ticker_surface = retro.Sprite(window.fonts[0].render(
            text=f"{self.ticker.remaining}",
            color=retro.WHITE,
        ))
        ticker_surface.rect.midbottom = self.lemming.bounding_rect.midtop
        ticker_surface.draw(window)
Пример #4
0
class Build:
    ICON = retro.Image(asset("ui_build.png"))

    def __init__(self, lemming):
        self.lemming = lemming
        self.count = 0

    @property
    def finished(self):
        return (self.count >= 12)

    def start(self):
        self.lemming.start_animation("BUILD")
        return self

    def run(self):
        if not self.lemming.animations.finished: return

        dx = self.lemming.actions.walk.dx
        rect = self.lemming.rect.copy()
        rect.size = (15, 3)
        rect.top = self.lemming.rect.bottom - rect.height
        if (dx > 0): rect.left = self.lemming.rect.right - (rect.width // 2)
        elif (dx < 0): rect.left -= rect.width // 2

        self.lemming.bg.original.draw_rect(retro.GREY, rect)

        self.lemming.rect.move_ip(dx * rect.width // 2, -rect.height)

        self.count += 1
        self.lemming.start_animation("BUILD")
Пример #5
0
class Stop:
    ICON = retro.Image(asset("ui_stop.png"))

    def __init__(self, lemming):
        self.lemming = lemming

    def start(self):
        self.lemming.start_animation("STOP")
        return self

    def run(self):
        pass
Пример #6
0
class Float:
    ICON = retro.Image(asset("ui_float.png"))

    def __init__(self, lemming):
        self.lemming = lemming

    def start(self):
        self.enabled = False
        return self

    def run(self):
        if not self.enabled:
            self.lemming.start_animation("FLOAT")
            self.enabled = True
        self.lemming.rect.move_ip(0, 1)
Пример #7
0
class DigV:
    ICON = retro.Image(asset("ui_digv.png"))

    def __init__(self, lemming):
        self.lemming = lemming

    def start(self):
        self.lemming.start_animation("DIGV")
        return self

    def run(self):
        dx = self.lemming.actions.walk.dx

        rect = self.lemming.rect.copy()
        rect.top = rect.bottom - 1
        rect.left += 10 if dx > 0 else 0
        rect.size = (20, 2)

        self.lemming.bg.original.draw_rect(retro.BLACK, rect)
        self.lemming.rect.move_ip(0, 1)
Пример #8
0
class DigH:
    ICON = retro.Image(asset("ui_digh.png"))

    def __init__(self, lemming):
        self.lemming = lemming

    def start(self):
        self.enabled = False
        return self

    def run(self):
        if not self.enabled:
            self.lemming.start_animation("DIGH")
            self.enabled = True

        dx = self.lemming.actions.walk.dx

        rect = self.lemming.rect.copy()
        rect.left = rect.right - 15 if dx > 0 else rect.left - 1
        rect.width = 16

        self.lemming.bg.original.draw_rect(retro.BLACK, rect)
        self.lemming.rect.move_ip(dx, 0)
Пример #9
0
class Lemming(retro.Sprite):
    IMG = retro.Image(asset("lemming.png"))

    def __init__(self, window, bg, position):
        self.window = window
        self.bg = bg

        revrange = lambda start, end: range(end - 1, start - 1, -1)
        retro.Sprite.__init__(
            self=self,
            image=self.IMG,
            animations=retro.Animations(
                frame_size=(30, 30),
                period=4,
                WALK_L=(range(0, 8), 0),
                WALK_R=(revrange(0, 8), 12),
                WALKA_L=(range(0, 8), 11),
                WALKA_R=(revrange(0, 8), 23),
                FALL_L=(range(0, 4), 1),
                FALL_R=(revrange(0, 4), 13),
                FLOAT_L=(range(0, 6), 3),
                FLOAT_R=(revrange(0, 6), 15),
                STOP_L=(range(0, 16), 4),
                STOP_R=(revrange(0, 16), 16),
                BOMB_L=(range(0, 14), 5),
                BOMB_R=(revrange(0, 14), 17),
                BUILD_L=(range(0, 16), 6),
                BUILD_R=(revrange(0, 16), 18),
                DIGV_L=(range(0, 16), 7),
                DIGV_R=(revrange(0, 16), 19),
                DIGH_L=(range(0, 12), 8),
                DIGH_R=(revrange(0, 12), 20),
                MINE_L=(range(0, 17), 9),
                MINE_R=(revrange(0, 17), 21),
                DEAD_L=(range(0, 16), 10),
                DEAD_R=(revrange(0, 16), 22),
            ),
        )
        self.rect.topleft = position

        self.actions = Actions(self)
        self.state = None

    @property
    def bounding_rect(self):
        dx = self.actions.walk.dx
        rect = self.rect.copy()
        rect.width //= 2
        if dx > 0: rect.left += rect.width
        return rect

    def set_animation(self, name):
        dx = self.actions.walk.dx
        if dx < 0: self.animations.set(f"{name}_L")
        elif dx > 0: self.animations.set(f"{name}_R")
        else: self.animations.set("NONE")

    def start_animation(self, name):
        dx = self.actions.walk.dx
        if dx < 0: self.animations.start(f"{name}_L")
        elif dx > 0: self.animations.start(f"{name}_R")
        else: self.animations.start("NONE")

    def collisions(self, surface):
        directions = retro.Collisions.pixel_mid(surface, self.bounding_rect,
                                                retro.BLACK).invert()

        outside = (None in directions)
        directions.replace(None, True)

        fall = not directions.down

        dx = self.actions.walk.dx
        side = (directions.vec[0] == dx)

        return types.SimpleNamespace(
            outside=outside,
            fall=fall,
            side=side,
        )

    def update(self, new_action):
        collisions_all = self.collisions(self.bg.image)
        collisions_bg = self.collisions(self.bg.original)

        if self.state is None:
            self.state = self.actions.fall.start()

        elif self.state == self.actions.walk:
            if collisions_all.fall:
                self.state = self.actions.fall.start()
            elif new_action:
                self.state = self.actions.from_class(new_action).start()
            else:
                self.actions.walk.run(collisions_all)

        elif self.state == self.actions.fall:
            if collisions_all.fall:
                self.actions.fall.run()
            elif self.actions.fall.dead:
                self.state = self.actions.dead.start()
            else:
                self.actions.fall.clamp()
                self.state = self.actions.walk.start()

        elif self.state == self.actions.float:
            if collisions_all.fall:
                self.actions.float.run()
            elif self.actions.float.enabled:
                self.state = self.actions.walk.start()
            else:
                self.actions.walk.run(collisions_all, pending_action=True)

        elif self.state == self.actions.stop:
            self.actions.stop.run()

        elif self.state == self.actions.bomb:
            if self.actions.bomb.ticker.finished or collisions_all.fall:
                self.actions.bomb.run()
            else:
                self.actions.walk.run(collisions_all, pending_action=True)

        elif self.state == self.actions.build:
            if self.actions.build.finished or collisions_bg.side:
                self.state = self.actions.walk.start()
            else:
                self.actions.build.run()

        elif self.state == self.actions.digv:
            if (not collisions_bg.fall) and (not collisions_bg.outside):
                self.actions.digv.run()
            else:
                self.state = self.actions.walk.start()

        elif self.state == self.actions.digh:
            if (collisions_bg.side and (not collisions_bg.fall)
                    and (not collisions_bg.outside)):
                self.actions.digh.run()
            elif collisions_all.fall or self.actions.digh.enabled:
                self.state = self.actions.walk.start()
            else:
                self.actions.walk.run(collisions_all, pending_action=True)

        elif self.state == self.actions.mine:
            if (collisions_bg.side and (not collisions_bg.fall)
                    and (not collisions_bg.outside)):
                self.actions.mine.run()
            elif collisions_all.fall or self.actions.mine.enabled:
                self.state = self.actions.walk.start()
            else:
                self.actions.walk.run(collisions_all, pending_action=True)

        elif self.state == self.actions.dead:
            self.actions.dead.run()

    def draw_bg(self):
        if self.state == self.actions.stop:
            retro.Sprite.draw(self, self.bg.image)

    def draw_screen(self):
        if self.state == self.actions.stop: return
        elif self.state == self.actions.bomb:
            self.actions.bomb.draw_ticker()

        retro.Sprite.draw(self, self.window)