From 708027ee5ac492e46c8eb316ef5f19d9d984aae1 Mon Sep 17 00:00:00 2001 From: frank <420@shampoo.ooo> Date: Thu, 17 Mar 2022 16:09:07 -0400 Subject: [PATCH] tongue, boss death animation looping --- NS.py | 84 ++++++++++++++++++++++++++++++++++++------------- resource/scores | 7 +++++ 2 files changed, 69 insertions(+), 22 deletions(-) diff --git a/NS.py b/NS.py index 328ba5b..217afa5 100644 --- a/NS.py +++ b/NS.py @@ -1734,16 +1734,19 @@ class Chemtrails(Sprite): def __init__(self, parent): """ - Load the sprite frames, one for each pad orientation. Initialize a health object, lives object, and timer. + Load the sprite frames, one for each pad orientation. Initialize a health object, lives object, and timer. Create a sprite + for the tongue. @param parent PGFW game object that initialized this object """ - Sprite.__init__(self, parent, 125) + Sprite.__init__(self, parent, framerate=125) for directory in sorted(iglob(join(self.get_resource("littleSlimeGoop"), "[0-9]_*/"))): self.add_frameset(switch=True) self.load_from_path(directory, True) self.add_frameset(name="hurt", switch=True) self.load_from_path("littleSlimeGoop/Hurt", True) + self.tongue = Sprite(self, 160) + self.tongue.load_from_path("littleSlimeGoop/justTongue", True) self.set_frameset(NS.N) self.register(self.cancel_hurt) self.life = Life(self) @@ -1787,26 +1790,6 @@ class Chemtrails(Sprite): self.set_frameset(NS.N) self.orient() - def update(self, offset: Vector=(0, 0)): - if self.active: - self.orient() - self.location.move(offset) - Sprite.update(self) - if not self.get_game().title.active and not self.get_game().level_select.active: - boss = self.get_game().boss - if boss.queue: - self.timer.tick() - self.attack() - if self.timer.amount < 0: - self.life.decrease() - if not boss.is_playing(boss.show_end_dialogue, include_delay=True): - self.timer.reset() - boss.combo() - if not boss.is_playing(boss.show_introduction_dialogue, include_delay=True): - self.timer.update() - self.life.update() - # self.boys.update() - def attack(self): """ Hit the boss if this is called while the boss attack queue is active and the player is in the correct orientation. @@ -1816,6 +1799,7 @@ class Chemtrails(Sprite): boss = self.get_game().boss queue = boss.queue if self.orientation == queue[self.queue_index]: + self.blem() self.timer.add_time(self.get_configuration("time", f"timer-addition-level-{boss.level_index + 1}")) boss.health.decrease(self.get_configuration("boss", f"damage-per-hit-level-{boss.level_index + 1}")) self.queue_index += 1 @@ -1864,6 +1848,51 @@ class Chemtrails(Sprite): else: self.orientation = None + def blem(self): + """ + Start the tongue animation to block the sword + """ + if self.orientation in (NS.N, NS.NE): + self.tongue.location.center = self.location.centerx + 10, self.location.top + elif self.orientation == NS.E: + self.tongue.location.center = self.location.right - 10, self.location.top + 25 + elif self.orientation == NS.NW: + self.tongue.location.center = self.location.centerx, self.location.top + 27 + elif self.orientation == NS.S: + self.tongue.location.center = self.location.centerx, self.location.top + 100 + elif self.orientation == NS.W: + self.tongue.location.center = self.location.left + 13, self.location.top + 23 + self.tongue.unhide() + self.tongue.get_current_frameset().reset() + + def update(self, offset: Vector=(0, 0)): + if self.active: + self.orient() + self.location.move(offset) + # Draw tongue behind lizard if it the bottom, otherwise draw tongue in front of lizard + if self.orientation == NS.S: + self.tongue.update() + Sprite.update(self) + if self.orientation != NS.S: + self.tongue.update() + # End the tongue animation after one play + if self.tongue.get_current_frameset().current_index == len(self.tongue.get_current_frameset().order) - 1: + self.tongue.hide() + if not self.get_game().title.active and not self.get_game().level_select.active: + boss = self.get_game().boss + if boss.queue: + self.timer.tick() + self.attack() + if self.timer.amount < 0: + self.life.decrease() + if not boss.is_playing(boss.show_end_dialogue, include_delay=True): + self.timer.reset() + boss.combo() + if not boss.is_playing(boss.show_introduction_dialogue, include_delay=True): + self.timer.update() + self.life.update() + # self.boys.update() + class Timer(Meter): @@ -1941,14 +1970,19 @@ class Boys(Meter): class BossSprite(Sprite): """ + Overload the Sprite class to do custom animation for bosses """ def shift_frame(self): """ + Customize the sprite animation to play the entrance animation only once and to loop over the last three frames + of the death animation. """ frameset = self.get_current_frameset() if frameset.name == "entrance" and frameset.get_current_id() == frameset.order[-1]: self.set_frameset("normal") + elif frameset.name == "death" and frameset.current_index in (-1, len(frameset.order) - 1): + frameset.current_index = -4 super().shift_frame() @@ -2812,6 +2846,12 @@ class Sword(Animation): self.sprites[self.active_sprite_index].location.center = center_save self.attacking_player = player + def active_sprite(self): + """ + Get the sprite that is currently front of the queue (next to get hit) + """ + return self.sprites[self.active_sprite_index] + def update(self): """ Draw previously blocked swords and the boss's current move sword. diff --git a/resource/scores b/resource/scores index 86836ec..a0b1b4d 100644 --- a/resource/scores +++ b/resource/scores @@ -178,6 +178,7 @@ 33896 0 33896 0 33896 0 +52833 0 59424 0 59424 0 59424 0 @@ -214,6 +215,7 @@ 64471 0 64471 0 64471 0 +67571 0 10329 1 10329 1 10329 1 @@ -304,6 +306,7 @@ 33442 1 33442 1 33442 1 +64453 1 68561 1 68561 1 68561 1 @@ -340,6 +343,8 @@ 71763 1 71763 1 71763 1 +82974 1 +92810 1 95630 1 95630 1 95630 1 @@ -430,6 +435,7 @@ 10589 2 10589 2 10589 2 +66418 2 73798 2 73798 2 73798 2 @@ -467,6 +473,7 @@ 75161 2 75161 2 75161 2 +80087 2 86762 2 86762 2 86762 2