diff --git a/NS.py b/NS.py index 723f728..7735145 100644 --- a/NS.py +++ b/NS.py @@ -71,15 +71,13 @@ class NS(Game, Animation): self.chemtrails = Chemtrails(self) self.boss = Boss(self) self.last_press = get_ticks() - self.register(self.unsuppress_restart) self.reset() - def reset(self): + def reset(self, leave_wipe_running=False): self.suppressing_input = False - self.suppress_restart = False - self.game_over = False self.title.reset() - self.wipe.reset() + if not leave_wipe_running: + self.wipe.reset() self.introduction.reset() self.boss.reset() self.chemtrails.reset() @@ -88,7 +86,7 @@ class NS(Game, Animation): def suppress_input(self): self.suppressing_input = True - self.platform.unpress() + # self.platform.unpress() def unsuppress_input(self): self.suppressing_input = False @@ -100,8 +98,6 @@ class NS(Game, Animation): lights = self.platform.lights if event.key in (K_UP, K_o): lights[NS.LNW].pressed = pressed - if self.game_over and not self.suppress_restart: - self.reset() elif event.key in (K_RIGHT, K_p): lights[NS.LNE].pressed = pressed elif event.key in (K_DOWN, K_SEMICOLON): @@ -113,31 +109,6 @@ class NS(Game, Animation): if self.get_delegate().compare(event, "reset-game"): self.reset() - def finish_battle(self, win): - self.game_over = True - font = Font(self.get_resource("rounded-mplus-1m-bold.ttf"), 128) - text = font.render("YOU WIN" if win else "GAME OVER", True, Color("white")) - self.message = Sprite(self) - self.message.add_frame(text) - self.message.location.center = self.get_display_surface().get_rect().center - self.boss.halt(self.boss.brandish) - self.boss.sword.reset() - self.boss.queue = [] - self.boss.brandish_complete = True - if win: - self.boss.set_frameset(0) - self.suppress_restart = True - self.play(self.unsuppress_restart, delay=4000, play_once=True) - - def unsuppress_restart(self): - self.suppress_restart = False - font = Font(self.get_resource("rounded-mplus-1m-bold.ttf"), 48) - text = font.render("(PRESS BLUE TO RESTART)", True, Color("white")) - self.restart_message = Sprite(self) - self.restart_message.add_frame(text) - dsr = self.get_display_surface().get_rect() - self.restart_message.location.center = dsr.centerx, dsr.centery + 80 - def update(self): Animation.update(self) self.title.update() @@ -147,10 +118,6 @@ class NS(Game, Animation): self.platform.update() self.chemtrails.update() self.boss.update_dialogue() - if self.game_over: - self.message.update() - if not self.suppress_restart: - self.restart_message.update() self.wipe.update() @@ -329,10 +296,10 @@ class Introduction(Animation): "on it. Now the power of Giant Tony pulses through you.", \ "Before you go, show me you can scrape! Use your board to touch\n" + \ "the glowing pads on the platform!", \ - "Great job, lizard scum! Maybe now you're ready to take on Kool\n" + \ + "Good job, lizard scum! Maybe now you're ready to take on Kool\n" + \ "Man and his friends. Don't let me down!" SKATEBOARD_START = -30, -20 - TUTORIAL_MOVES = NS.S, NS.NE, NS.N, NS.E, NS.NW, NS.W, NS.E, NS.W + TUTORIAL_MOVES = NS.S, NS.NE, NS.N, NS.E def __init__(self, parent): Animation.__init__(self, parent) @@ -367,6 +334,7 @@ class Introduction(Animation): def activate(self): self.active = True self.play(self.start, delay=3000, play_once=True) + # self.get_game().platform.unpress() def start(self): self.advance_prompt.cancel_first_press() @@ -395,7 +363,7 @@ class Introduction(Animation): def activate_boss(self): self.deactivate() - self.get_game().boss.start_level() + self.get_game().boss.start_level(0) def start_wipe(self): self.get_game().wipe.start(self.activate_boss) @@ -429,7 +397,7 @@ class Introduction(Animation): dialogue.show_text(self.TEXT[self.text_index]) else: self.start_wipe() - self.get_game().platform.unpress() + # self.get_game().platform.unpress() self.advance_prompt.cancel_first_press() elif self.text_index == 2: platform = self.get_game().platform @@ -451,7 +419,7 @@ class Introduction(Animation): if not wipe.is_playing() and not self.is_playing(self.start) and \ not self.text_index == 2: self.advance_prompt.update() - if not self.text_index == 2: + if not wipe.is_playing() and not self.text_index == 2: self.skip_prompt.update() @@ -646,6 +614,48 @@ class Platform(GameChild): buttons = buttons.union((NS.LSW, NS.LNW)) return list(buttons) + def get_steps_from_edge(self, edge): + if edge == NS.N: + return NS.NE, NS.NW + elif edge == NS.NE: + return NS.N, NS.E, NS.S, NS.W + elif edge == NS.E: + return NS.NE, NS.NW + elif edge == NS.NW: + return NS.N, NS.E, NS.S, NS.W + elif edge == NS.S: + return NS.NE, NS.NW + elif edge == NS.W: + return NS.NE, NS.NW + + def get_right_angles_from_edge(self, edge): + if edge == NS.N: + return NS.E, NS.W + elif edge == NS.NE: + return None + elif edge == NS.E: + return NS.N, NS.S + elif edge == NS.NW: + return None + elif edge == NS.S: + return NS.E, NS.W + elif edge == NS.W: + return NS.N, NS.S + + def get_opposite_of_edge(self, edge): + if edge == NS.N: + return NS.S + elif edge == NS.NE: + return NS.NW + elif edge == NS.E: + return NS.W + elif edge == NS.NW: + return NS.NE + elif edge == NS.S: + return NS.N + elif edge == NS.W: + return NS.E + def set_glowing(self, selected): for ii, light in enumerate(self.lights): light.glow_index = 0 @@ -714,11 +724,11 @@ class Light(Animation): if not self.get_game().introduction.active: boss = self.get_game().boss chemtrails = self.get_game().chemtrails - if boss.queue and boss.brandish_complete and not self.is_playing(self.blink) \ + if boss.queue and boss.brandish_complete and not self.is_playing(self.glow) \ and self.in_orientation(boss.queue[chemtrails.queue_index]): - self.play(self.blink) - elif self.is_playing(self.blink) and (not boss.queue or - not self.in_orientation(boss.queue[chemtrails.queue_index])): + self.play(self.glow) + elif self.is_playing(self.glow) and (not boss.queue or + not self.in_orientation(boss.queue[chemtrails.queue_index])): self.reset() points = self.points else: @@ -777,20 +787,15 @@ class Chemtrails(GameChild): if self.active: self.orient() if not self.get_game().introduction.active: - if self.get_game().boss.queue: + boss = self.get_game().boss + if boss.queue: self.timer.tick() self.attack() if self.timer.time_remaining < 0: self.life.decrease() - if not self.get_game().game_over: + if not boss.is_playing(boss.show_end_dialogue): self.timer.reset() - self.get_game().boss.combo() - # font = Font(self.get_resource("rounded-mplus-1m-bold.ttf"), 24) - # text = font.render("%.2f" % max(0, self.timer_remaining / 1000.0), True, Color("white")) - # rect = text.get_rect() - # ds = self.get_display_surface() - # rect.topright = ds.get_rect().topright - # ds.blit(text, rect) + boss.combo() self.timer.update() self.life.update() @@ -799,11 +804,18 @@ class Chemtrails(GameChild): queue = boss.queue if self.orientation == queue[self.queue_index]: self.timer.add_time(self.TIME_ADDITION) - boss.health.decrease(5) + if boss.level_index == 0: + boss.health.decrease(4) + elif boss.level_index == 1: + boss.health.decrease(4) + elif boss.level_index == 2: + boss.health.decrease(4) self.queue_index += 1 + boss.last_attack = self.orientation if self.queue_index == len(queue): self.timer.reset() - self.get_game().boss.combo() + if not boss.is_playing(boss.show_end_dialogue): + boss.combo() self.get_game().platform.reset_lights() def orient(self): @@ -918,7 +930,7 @@ class Life(GameChild): self.count -= 1 if self.count <= 0: self.count = 0 - self.get_game().finish_battle(False) + self.get_game().boss.finish_battle(False) def update(self): ds = self.get_display_surface() @@ -930,46 +942,85 @@ class Life(GameChild): ds.blit(self.heart, (x, rect.top)) -class Boss(RainbowSprite): +class Boss(Animation): def __init__(self, parent): - RainbowSprite.__init__(self, parent, load("resource/Kool_man.png").convert_alpha(), 30) + Animation.__init__(self, parent) + self.kool_man = RainbowSprite(self, load(self.get_resource("Kool_man.png")).convert_alpha(), 30) + self.visitor = RainbowSprite(self, load(self.get_resource("Visitor.png")).convert_alpha(), 30) + self.spoopy = RainbowSprite(self, load(self.get_resource("Spoopy.png")).convert_alpha(), 30) self.health = Health(self) self.sword = Sword(self) - self.register(self.brandish, self.cancel_flash, self.show_dialogue) - self.add_frameset([0], name="normal") - self.kool_man_avatar = load(self.get_resource("resource/Kool_man_avatar.png")).convert() + self.register(self.brandish, self.cancel_flash, self.show_introduction_dialogue, + self.show_end_dialogue) + self.kool_man.add_frameset([0], name="normal", switch=True) + self.visitor.add_frameset([0], name="normal", switch=True) + self.spoopy.add_frameset([0], name="normal", switch=True) + self.kool_man_avatar = load(self.get_resource("Kool_man_avatar.png")).convert() + self.visitor_avatar = load(self.get_resource("Visitor_avatar.png")).convert() + self.spoopy_avatar = load(self.get_resource("Spoopy_avatar.png")).convert() self.advance_prompt = AdvancePrompt(self) def cancel_flash(self): - self.set_frameset("normal") + if self.level_index == 0: + self.kool_man.set_frameset("normal") + elif self.level_index == 1: + self.visitor.set_frameset("normal") + elif self.level_index == 2: + self.spoopy.set_frameset("normal") - def start_level(self): + def start_level(self, index): + self.level_index = index + self.battle_finished = False + self.player_defeated = False + self.health.reset() + self.get_game().chemtrails.timer.reset() + self.get_game().chemtrails.life.reset() self.activate() dialogue = self.get_game().dialogue dialogue.deactivate() - dialogue.set_avatar(self.kool_man_avatar) - dialogue.set_name("Kool Man") - self.play(self.show_dialogue, delay=3000, play_once=True) + if index == 0: + dialogue.set_avatar(self.kool_man_avatar) + dialogue.set_name("Kool Man") + self.kool_man.unhide() + self.kool_man.set_frameset("normal") + elif index == 1: + dialogue.set_avatar(self.visitor_avatar) + dialogue.set_name("Visitor") + self.visitor.unhide() + self.visitor.set_frameset("normal") + elif index == 2: + dialogue.set_avatar(self.spoopy_avatar) + dialogue.set_name("Spoopy") + self.spoopy.unhide() + self.spoopy.set_frameset("normal") + self.play(self.show_introduction_dialogue, delay=3000, play_once=True) self.get_game().platform.activate() self.get_game().chemtrails.activate() + self.last_attack = NS.NW - def show_dialogue(self): + def show_introduction_dialogue(self): dialogue = self.get_game().dialogue dialogue.activate() - dialogue.show_text("You'll never be able to block my sword, you lizard slime!" + - " See if you\ncan keep up with these moves!") + if self.level_index == 0: + dialogue.show_text("You'll never be able to block my sword, you lizard slime!" + + " See if you\ncan keep up with these moves!") + elif self.level_index == 1: + dialogue.show_text("We're just warming up, slime breath! Prepare to get spun" + + " by\nthese combos!") + elif self.level_index == 2: + dialogue.show_text("Lizard! My moves are so unpredictable you might as well" + + " give\nup now!") def reset(self): + self.level_index = 0 self.deactivate() - self.unhide() self.cancel_flash() self.halt(self.cancel_flash) self.health.reset() self.halt(self.brandish) self.sword.reset() self.advance_prompt.reset() - # self.combo() self.queue = None self.brandish_complete = True @@ -985,26 +1036,225 @@ class Boss(RainbowSprite): def brandish(self): self.queue = [] - choices = range(6) - if self.health.amount > 90: - length = 1 - elif self.health.amount > 70: - length = 2 - elif self.health.amount > 40: - length = 3 - else: - length = 4 - while len(self.queue) < length: - while True: - orientation = randint(0, 5) - if not self.queue or orientation != self.queue[-1]: - self.queue.append(orientation) - break + platform = self.get_game().platform + if self.level_index == 0: + if self.health.amount > 90: + first = choice(platform.get_steps_from_edge(self.last_attack)) + self.queue = [first] + elif self.health.amount > 70: + first = choice(platform.get_steps_from_edge(self.last_attack)) + self.queue = [first, choice(platform.get_steps_from_edge(first))] + elif self.health.amount > 30: + choices = [0] + if self.last_attack in (NS.NE, NS.NW): + choices.append(1) + else: + choices.extend((2, 3)) + result = choice(choices) + if result == 0: + first = choice(platform.get_steps_from_edge(self.last_attack)) + second = choice(platform.get_steps_from_edge(first)) + self.queue = [first, second, first, second] + elif result == 1: + first = choice(platform.get_steps_from_edge(self.last_attack)) + self.queue = [first, choice(platform.get_steps_from_edge(first)), + choice(platform.get_right_angles_from_edge(first))] + elif result == 2: + first = choice(platform.get_steps_from_edge(self.last_attack)) + self.queue = [first, choice(platform.get_steps_from_edge(first)), + platform.get_opposite_of_edge(first)] + elif result == 3: + first = choice(platform.get_steps_from_edge(self.last_attack)) + second = choice(platform.get_steps_from_edge(first)) + self.queue = [first, second, + choice(platform.get_right_angles_from_edge(second))] + else: + choices = [0, 1] + if self.last_attack in (NS.NE, NS.NW): + choices.extend((2, 3, 4)) + else: + choices.append(5) + result = choice(choices) + if result == 0 or result == 1: + first = choice(platform.get_steps_from_edge(self.last_attack)) + second = choice(platform.get_steps_from_edge(first)) + last = second if result else platform.get_opposite_of_edge(second) + self.queue = [first, second, platform.get_opposite_of_edge(first), + last] + elif result == 2: + first = choice(platform.get_steps_from_edge(self.last_attack)) + self.queue = [first, choice(platform.get_right_angles_from_edge(first)), + platform.get_opposite_of_edge(first)] + elif result == 3: + first = choice(platform.get_steps_from_edge(self.last_attack)) + self.queue = [first, choice(platform.get_steps_from_edge(first)), + choice(platform.get_right_angles_from_edge(first)), + platform.get_opposite_of_edge(first)] + elif result == 4: + first = choice(platform.get_steps_from_edge(self.last_attack)) + second = choice(platform.get_steps_from_edge(first)) + self.queue = [first, second, + choice(platform.get_right_angles_from_edge(first)), + platform.get_opposite_of_edge(second)] + elif result == 5: + first = choice(platform.get_steps_from_edge(self.last_attack)) + second = choice(platform.get_steps_from_edge(first)) + self.queue = [first, second, platform.get_opposite_of_edge(first), + choice(platform.get_right_angles_from_edge(second))] + elif self.level_index == 1: + if self.health.amount > 85: + if self.last_attack in (NS.NE, NS.NW): + choices = 1, 2 + else: + choices = 0, + result = choice(choices) + if result == 0: + first = choice(platform.get_steps_from_edge(self.last_attack)) + self.queue = [first, platform.get_opposite_of_edge(first)] + elif result == 1: + first = choice(platform.get_steps_from_edge(self.last_attack)) + self.queue = [first, choice(platform.get_right_angles_from_edge(first)), + platform.get_opposite_of_edge(first)] + elif result == 2: + first = choice(platform.get_steps_from_edge(self.last_attack)) + self.queue = [first, platform.get_opposite_of_edge(first)] + elif self.health.amount > 60: + if self.last_attack in (NS.NE, NS.NW): + choices = 2, 3 + else: + choices = 0, 1 + result = choice(choices) + first = choice(platform.get_steps_from_edge(self.last_attack)) + if result == 0: + second = choice(platform.get_steps_from_edge(first)) + self.queue = [first, second, platform.get_opposite_of_edge(second)] + elif result == 1: + second = choice(platform.get_steps_from_edge(first)) + self.queue = [first, second, + choice(platform.get_right_angles_from_edge(second)), + platform.get_opposite_of_edge(first)] + elif result == 2: + second = platform.get_opposite_of_edge(first) + self.queue = [first, second, + choice(platform.get_right_angles_from_edge(second))] + elif result == 3: + second = choice(platform.get_right_angles_from_edge(first)) + self.queue = [first, second, platform.get_opposite_of_edge(first), + platform.get_opposite_of_edge(second)] + elif self.health.amount > 30: + result = choice(range(3)) + if result == 0: + first = self.choose_new_edge((NS.N, NS.E, NS.S, NS.W)) + self.queue = [first, choice(platform.get_steps_from_edge(first)), + platform.get_opposite_of_edge(first), first] + elif result == 1: + first = self.choose_new_edge((NS.NE, NS.NW)) + second = choice(platform.get_steps_from_edge(first)) + self.queue = [first, second, platform.get_opposite_of_edge(second), + choice(platform.get_right_angles_from_edge(second))] + elif result == 2: + first = self.choose_new_edge((NS.NE, NS.NW)) + second = choice(platform.get_steps_from_edge(first)) + self.queue = [first, second, + choice(platform.get_right_angles_from_edge(second)), + platform.get_opposite_of_edge(second)] + else: + result = choice(range(4)) + if result == 0: + first = self.choose_new_edge((NS.NE, NS.NW)) + second = platform.get_opposite_of_edge(first) + self.queue = [first, second, first, second] + elif result == 1: + first = self.choose_new_edge((NS.N, NS.E, NS.S, NS.W)) + self.queue = [first, platform.get_opposite_of_edge(first), first] + elif result == 2: + first = self.choose_new_edge((NS.N, NS.E, NS.S, NS.W)) + self.queue = [first, choice(platform.get_steps_from_edge(first)), + choice(platform.get_right_angles_from_edge(first)), + platform.get_opposite_of_edge(first), first] + elif result == 3: + first = self.choose_new_edge((NS.N, NS.E, NS.S, NS.W)) + second = platform.get_opposite_of_edge(first) + third = choice(platform.get_right_angles_from_edge(first)) + self.queue = [first, second, third, platform.get_opposite_of_edge(second), + platform.get_opposite_of_edge(third)] + elif self.level_index == 2: + if self.health.amount > 90: + length = 3 + elif self.health.amount > 70: + length = 4 + elif self.health.amount > 40: + length = 5 + else: + length = 6 + while len(self.queue) < length: + while True: + orientation = randint(0, 5) + if (not self.queue and orientation != self.last_attack) or \ + (len(self.queue) > 0 and orientation != self.queue[-1]): + self.queue.append(orientation) + break self.unbrandished = copy(self.queue) self.brandish_complete = False self.sword.play(self.sword.brandish, play_once=True) self.get_game().chemtrails.challenge() + def choose_new_edge(self, edges): + while True: + edge = choice(edges) + if edge != self.last_attack: + return edge + + def finish_battle(self, win): + self.battle_finished = True + self.halt(self.brandish) + self.halt(self.cancel_flash) + self.sword.reset() + self.queue = [] + self.brandish_complete = True + if win: + if self.level_index == 0: + self.kool_man.set_frameset(0) + elif self.level_index == 1: + self.visitor.set_frameset(0) + elif self.level_index == 2: + self.spoopy.set_frameset(0) + self.player_defeated = not win + self.play(self.show_end_dialogue, delay=3000, play_once=True) + + def show_end_dialogue(self): + dialogue = self.get_game().dialogue + dialogue.activate() + if self.level_index == 0: + if self.player_defeated: + dialogue.show_text("Maybe next time!") + else: + dialogue.show_text("Hey! Wow! Lizard!") + elif self.level_index == 1: + if self.player_defeated: + dialogue.show_text("Wiped out!") + else: + dialogue.show_text("Well done! But it's not over yet!") + elif self.level_index == 2: + if self.player_defeated: + dialogue.show_text("Just like I thought!") + else: + dialogue.show_text("H-how? But you're only a lizard! How could you" + + " manage to defeat\nall of us?") + + def transition_to_battle(self): + index = self.level_index + (not self.player_defeated) + if index < 3: + self.start_level(index) + else: + self.get_game().reset(True) + + def damage(self): + if self.level_index == 0: + self.kool_man.set_frameset(0) + elif self.level_index == 1: + self.visitor.set_frameset(0) + def update(self): if self.active: self.get_display_surface().fill((0, 0, 0)) @@ -1017,10 +1267,18 @@ class Boss(RainbowSprite): dialogue.show_all() else: self.get_game().dialogue.deactivate() - self.combo() + if not self.battle_finished: + self.combo() + else: + self.get_game().wipe.start(self.transition_to_battle) self.advance_prompt.cancel_first_press() - RainbowSprite.update(self) - # self.get_display_surface().blit(self.image, (0, 0)) + Animation.update(self) + if self.level_index == 0: + self.kool_man.update() + elif self.level_index == 1: + self.visitor.update() + elif self.level_index == 2: + self.spoopy.update() self.sword.update() self.health.update() @@ -1112,12 +1370,12 @@ class Health(GameChild): def decrease(self, damage): self.amount -= damage + self.parent.damage() if self.amount <= 0: self.amount = 0 - self.get_game().finish_battle(True) + self.get_game().boss.finish_battle(True) else: self.parent.play(self.parent.cancel_flash, delay=1000, play_once=True) - self.parent.set_frameset(0) def update(self): self.background.update() diff --git a/resource/Spoopy.png b/resource/Spoopy.png new file mode 100644 index 0000000..1cbd9dc Binary files /dev/null and b/resource/Spoopy.png differ diff --git a/resource/Spoopy_avatar.png b/resource/Spoopy_avatar.png new file mode 100644 index 0000000..4df14fd Binary files /dev/null and b/resource/Spoopy_avatar.png differ diff --git a/resource/Visitor.png b/resource/Visitor.png new file mode 100644 index 0000000..507d13d Binary files /dev/null and b/resource/Visitor.png differ diff --git a/resource/Visitor_avatar.png b/resource/Visitor_avatar.png new file mode 100644 index 0000000..80d5496 Binary files /dev/null and b/resource/Visitor_avatar.png differ