diff --git a/NS.py b/NS.py index a188df2..b7702eb 100644 --- a/NS.py +++ b/NS.py @@ -1,4 +1,5 @@ from random import randint, choice +from math import pi from copy import copy from pygame import Surface, Color @@ -13,7 +14,7 @@ from lib.pgfw.pgfw.Game import Game from lib.pgfw.pgfw.GameChild import GameChild from lib.pgfw.pgfw.Sprite import Sprite, RainbowSprite from lib.pgfw.pgfw.Animation import Animation -from lib.pgfw.pgfw.extension import get_step_relative +from lib.pgfw.pgfw.extension import get_step_relative, get_delta, reflect_angle from lib.pgfw.pgfw.gfx_extension import aa_filled_polygon class SoundEffect(GameChild, Sound): @@ -59,6 +60,9 @@ class NS(Game, Animation): ds = self.get_display_surface() self.background = Surface(ds.get_size()) self.background.fill((0, 0, 0)) + self.title = Title(self) + self.introduction = Introduction(self) + self.wipe = Wipe(self) self.platform = Platform(self) self.chemtrails = Chemtrails(self) self.boss = Boss(self) @@ -70,6 +74,9 @@ class NS(Game, Animation): self.suppressing_input = False self.suppress_restart = False self.game_over = False + self.title.reset() + self.wipe.reset() + self.introduction.reset() self.boss.reset() self.chemtrails.reset() self.platform.reset() @@ -121,7 +128,8 @@ class NS(Game, Animation): def update(self): Animation.update(self) - self.get_display_surface().blit(self.background, (0, 0)) + self.title.update() + self.introduction.update() self.boss.update() self.platform.update() self.chemtrails.update() @@ -129,15 +137,38 @@ class NS(Game, Animation): self.message.update() if not self.suppress_restart: self.restart_message.update() + self.wipe.update() class Title(GameChild): def __init__(self, parent): GameChild.__init__(self, parent) + self.plank = Sprite(self) + self.plank.load_from_path(self.get_resource("Title_plank.png"), True) + ds = self.get_display_surface() + dsr = ds.get_rect() + self.plank.location.center = dsr.center + self.slime_bag = Sprite(self) + self.slime_bag.load_from_path(self.get_resource("Title_slime_bag.png"), True) + self.slime_bag.location.bottomleft = dsr.bottomleft + image = load(self.get_resource("Title_border.png")).convert() + image.set_colorkey((0, 0, 0)) + self.border = RainbowSprite(self, image, 30) + self.border.location.center = dsr.centerx, dsr.bottom - 100 + self.text = Sprite(self) + self.text.load_from_path(self.get_resource("Title_text.png"), True, False, (255, 0, 0)) + self.text.load_from_path(self.get_resource("Title_text_half.png"), True, False, (255, 0, 0)) + self.text.add_frameset([0], name="full", switch=True) + self.text.add_frameset([1], name="half") + self.text.location.center = dsr.centerx, dsr.bottom - 100 + self.angle = choice((pi / 4, 3 * pi / 4, 5 * pi / 4, 7 * pi / 4)) def reset(self): self.activate() + self.first_pressed = False + self.first_pressed_elapsed = 0 + self.text.set_frameset("full") def activate(self): self.active = True @@ -145,15 +176,54 @@ class Title(GameChild): def deactivate(self): self.active = False + def activate_introduction(self): + self.deactivate() + self.get_game().introduction.activate() + def update(self): if self.active: - pass + ds = self.get_display_surface() + ds.fill((255, 255, 255)) + dsr = ds.get_rect() + if self.plank.location.right > dsr.right or self.plank.location.left < dsr.left: + self.angle = reflect_angle(self.angle, 0) + if self.plank.location.right > dsr.right: + self.plank.move(dsr.right - self.plank.location.right) + else: + self.plank.move(dsr.left - self.plank.location.left) + if self.plank.location.bottom > dsr.bottom or self.plank.location.top < dsr.top: + self.angle = reflect_angle(self.angle, pi) + if self.plank.location.bottom > dsr.bottom: + self.plank.move(dy=dsr.bottom - self.plank.location.bottom) + else: + self.plank.move(dy=dsr.top - self.plank.location.top) + dx, dy = get_delta(self.angle, 2, False) + self.plank.move(dx, dy) + self.plank.update() + self.slime_bag.update() + wipe = self.get_game().wipe + if not self.first_pressed and self.get_game().platform.get_edge_pressed() == NS.N: + self.first_pressed = True + self.first_pressed_elapsed = 0 + self.text.set_frameset("half") + elif not wipe.is_playing() and self.first_pressed and \ + self.get_game().platform.get_edge_pressed() == NS.NW: + wipe.start(self.activate_introduction) + elif self.first_pressed: + self.first_pressed_elapsed += self.get_game().time_filter.get_last_frame_duration() + if self.first_pressed_elapsed > 4000: + self.first_pressed = False + self.first_pressed_elapsed = 0 + self.text.set_frameset("full") + self.border.update() + self.text.update() class Introduction(Animation): def __init__(self, parent): Animation.__init__(self, parent) + self.tony = load(self.get_resource("Big_Tony.png")) def reset(self): self.deactivate() @@ -167,15 +237,23 @@ class Introduction(Animation): def update(self): if self.active: Animation.update(self) + self.get_display_surface().blit(self.tony, (0, 0)) class Wipe(Animation): + BLIND_COUNT = 4 + SPEED = 6 + TRANSPARENT_COLOR = 255, 0, 0 + def __init__(self, parent): Animation.__init__(self, parent) + self.image = load(self.get_resource("Ink.png")).convert() + self.image.set_colorkey(self.TRANSPARENT_COLOR) def reset(self): self.deactivate() + self.halt() def deactivate(self): self.active = False @@ -183,9 +261,40 @@ class Wipe(Animation): def activate(self): self.active = True + def start(self, callback): + self.activate() + self.up = True + self.get_game().suppressing_input = True + self.blind_height = self.get_display_surface().get_height() / self.BLIND_COUNT + self.callback = callback + self.play() + + def build_frame(self): + if self.up: + self.blind_height -= self.SPEED + if self.blind_height <= 0: + self.up = False + self.callback() + else: + self.blind_height += self.SPEED + if self.blind_height >= self.get_display_surface().get_height() / self.BLIND_COUNT: + self.halt() + self.deactivate() + self.get_game().suppressing_input = False + def update(self): if self.active: Animation.update(self) + ds = self.get_display_surface() + dsr = ds.get_rect() + frame = self.image.copy() + for y in xrange(0, dsr.h, dsr.h / self.BLIND_COUNT): + if self.up: + frame.fill(self.TRANSPARENT_COLOR, (0, y, dsr.w, self.blind_height)) + else: + frame.fill(self.TRANSPARENT_COLOR, + (0, y + dsr.h / self.BLIND_COUNT - self.blind_height, dsr.w, self.blind_height)) + ds.blit(frame, (0, 0)) class Platform(GameChild): @@ -200,9 +309,16 @@ class Platform(GameChild): ] def reset(self): + self.deactivate() for light in self.lights: light.reset() + def deactivate(self): + self.active = False + + def activate(self): + self.active = True + def get_pressed(self): return [light.position for light in self.lights if light.pressed] @@ -222,8 +338,9 @@ class Platform(GameChild): return NS.W def update(self): - for light in self.lights: - light.update() + if self.active: + for light in self.lights: + light.update() @@ -299,30 +416,38 @@ class Chemtrails(GameChild): self.life = Life(self) def reset(self): + self.deactivate() self.life.reset() self.timer_remaining = self.TIME_LIMIT + def deactivate(self): + self.active = False + + def activate(self): + self.active = True + def challenge(self): self.timer_remaining = self.TIME_LIMIT self.queue_index = 0 def update(self): - self.orient() - if self.get_game().boss.queue: - self.timer_remaining -= self.get_game().time_filter.get_last_frame_duration() - self.attack() - if self.timer_remaining < 0: - self.life.decrease() - if not self.get_game().game_over: - self.timer_remaining = self.TIME_LIMIT - 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) - self.life.update() + if self.active: + self.orient() + if self.get_game().boss.queue: + self.timer_remaining -= self.get_game().time_filter.get_last_frame_duration() + self.attack() + if self.timer_remaining < 0: + self.life.decrease() + if not self.get_game().game_over: + self.timer_remaining = self.TIME_LIMIT + 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) + self.life.update() def attack(self): boss = self.get_game().boss @@ -419,6 +544,7 @@ class Boss(RainbowSprite): self.set_frameset("normal") def reset(self): + self.deactivate() self.unhide() self.cancel_flash() self.halt(self.cancel_flash) @@ -429,6 +555,12 @@ class Boss(RainbowSprite): self.queue = None self.brandish_complete = True + def deactivate(self): + self.active = False + + def activate(self): + self.active = True + def combo(self): self.queue = None self.play(self.brandish, delay=2500, play_once=True) @@ -456,10 +588,11 @@ class Boss(RainbowSprite): self.get_game().chemtrails.challenge() def update(self): - RainbowSprite.update(self) - # self.get_display_surface().blit(self.image, (0, 0)) - self.sword.update() - self.health.update() + if self.active: + RainbowSprite.update(self) + # self.get_display_surface().blit(self.image, (0, 0)) + self.sword.update() + self.health.update() class Sword(Sprite): diff --git a/lib/pgfw b/lib/pgfw index 446388e..ff096ec 160000 --- a/lib/pgfw +++ b/lib/pgfw @@ -1 +1 @@ -Subproject commit 446388ef9a6d52b8ebf111d277fc65ca5a6d9c31 +Subproject commit ff096eca52dc95a9eabfd9f25ba7c4e9415e4389 diff --git a/resource/Big_Tony.png b/resource/Big_Tony.png new file mode 100644 index 0000000..353c048 Binary files /dev/null and b/resource/Big_Tony.png differ diff --git a/resource/Ink.png b/resource/Ink.png new file mode 100644 index 0000000..6524bd8 Binary files /dev/null and b/resource/Ink.png differ diff --git a/resource/Title_border.png b/resource/Title_border.png new file mode 100644 index 0000000..ad33be5 Binary files /dev/null and b/resource/Title_border.png differ diff --git a/resource/Title_plank.png b/resource/Title_plank.png new file mode 100644 index 0000000..646c97b Binary files /dev/null and b/resource/Title_plank.png differ diff --git a/resource/Title_slime_bag.png b/resource/Title_slime_bag.png new file mode 100644 index 0000000..8a15793 Binary files /dev/null and b/resource/Title_slime_bag.png differ diff --git a/resource/Title_text.png b/resource/Title_text.png new file mode 100644 index 0000000..21fe2d6 Binary files /dev/null and b/resource/Title_text.png differ diff --git a/resource/Title_text_half.png b/resource/Title_text_half.png new file mode 100644 index 0000000..1397258 Binary files /dev/null and b/resource/Title_text_half.png differ