diff --git a/NS.py b/NS.py index 8d78d2c..de4f32b 100644 --- a/NS.py +++ b/NS.py @@ -7,49 +7,27 @@ from glob import iglob from os.path import basename from threading import Thread from serial import Serial +from PIL import Image, ImageDraw from pygame import Surface, Color from pygame.event import clear from pygame.mixer import Sound -from pygame.image import load +from pygame.image import load, fromstring from pygame.transform import rotate, flip from pygame.time import get_ticks from pygame.font import Font -from pygame.gfxdraw import aapolygon +from pygame.gfxdraw import aapolygon, arc from pygame.locals import * 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.Audio import SoundEffect from lib.pgfw.pgfw.extension import (get_step, get_step_relative, get_delta, reflect_angle, render_box) from lib.pgfw.pgfw.gfx_extension import aa_filled_polygon -class SoundEffect(GameChild, Sound): - - def __init__(self, parent, path, volume=1.0): - GameChild.__init__(self, parent) - Sound.__init__(self, path) - self.display_surface = self.get_display_surface() - self.initial_volume = volume - self.set_volume(volume) - - def play(self, loops=0, maxtime=0, fade_ms=0, position=None, x=None): - self.set_volume(self.initial_volume * - self.get_configuration("audio", "sfx-volume")) - channel = Sound.play(self, loops, maxtime, fade_ms) - if x is not None: - position = float(x) / self.display_surface.get_width() - if position is not None and channel is not None: - channel.set_volume(*self.get_panning(position)) - return channel - - def get_panning(self, position): - return 1 - max(0, ((position - .5) * 2)), \ - 1 + min(0, ((position - .5) * 2)) - - class NS(Game, Animation): LNW, LNE, LSE, LSW = range(4) @@ -963,6 +941,7 @@ class Chemtrails(Sprite): self.timer.reset() if not boss.is_playing(boss.show_end_dialogue): boss.combo() + boss.damaged.unhide() self.get_game().sfx["complete_pattern"].play() else: self.get_game().sfx["land"].play() @@ -1033,22 +1012,40 @@ class Timer(GameChild): self.time_remaining -= self.get_game().time_filter.get_last_frame_duration() def update(self): - self.background.update() - self.label.update() + # self.background.update() + # self.label.update() if self.time_remaining > 5500: - color = 0, 255, 0 + color = Color(0, 255, 0) elif self.time_remaining > 3000: color = Color("orange") else: color = Color("red") - mask = Surface(self.bar.get_size()) - mask.fill((128, 128, 128)) - width = min(mask.get_width(), mask.get_width() * float(self.time_remaining) / - self.get_configuration("time", "timer-max-time")) - mask.fill(color, (mask.get_width() - width, 0, width, mask.get_height())) - surface = self.bar.copy() - surface.blit(mask, (0, 0), None, BLEND_RGBA_MIN) - self.get_display_surface().blit(surface, self.BAR_POSITION) + ds = self.get_display_surface() + max_time = self.get_configuration("time", "timer-max-time") + size = 160 + top = 120 + image = Image.new("RGBA", (size, size)) + shadow = Image.new("RGBA", (size, size)) + draw = ImageDraw.Draw(image) + draw_shadow = ImageDraw.Draw(shadow) + draw.pieslice((0, 0, size - 1, size - 1), 90, float(self.time_remaining) / max_time * 180 + 90, + fill=(color.r, color.g, color.b, 128)) + draw_shadow.pieslice((0, 0, size - 1, size - 1), 90, float(self.time_remaining) / max_time * 180 + 90, + fill=(0, 0, 0, 128)) + draw.ellipse((40, 40, 120, 120), (0, 0, 0, 0)) + draw_shadow.ellipse((40, 40, 120, 120), (0, 0, 0, 0)) + surface = fromstring(image.tobytes(), image.size, image.mode) + surface_shadow = fromstring(shadow.tobytes(), shadow.size, shadow.mode) + ds.blit(surface_shadow, (ds.get_width() - size / 2, top + 8)) + ds.blit(surface, (ds.get_width() - size / 2, top)) + # mask = Surface(self.bar.get_size()) + # mask.fill((128, 128, 128)) + # width = min(mask.get_width(), mask.get_width() * float(self.time_remaining) / + # self.get_configuration("time", "timer-max-time")) + # mask.fill(color, (mask.get_width() - width, 0, width, mask.get_height())) + # surface = self.bar.copy() + # surface.blit(mask, (0, 0), None, BLEND_RGBA_MIN) + # self.get_display_surface().blit(surface, self.BAR_POSITION) class Life(GameChild): @@ -1085,13 +1082,16 @@ class Boss(Animation): def __init__(self, parent): Animation.__init__(self, parent) - self.kool_man = RainbowSprite(self, load(self.get_resource("Kool_man.png")).convert_alpha(), 30) + self.kool_man = RainbowSprite(self, load(self.get_resource("Kool_man_waah.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.damaged = Sprite(self) + self.damaged.load_from_path(self.get_resource("kool/damage.png"), True) + self.damaged.location.topleft = 174, 22 self.health = Health(self) self.sword = Sword(self) self.register(self.brandish, self.cancel_flash, self.show_introduction_dialogue, - self.show_end_dialogue) + self.show_end_dialogue, self.cancel_damaged) 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) @@ -1112,6 +1112,15 @@ class Boss(Animation): elif self.level_index == 2: self.spoopy.set_frameset("normal") + def cancel_damaged(self): + self.damaged.hide() + if self.level_index == 0: + self.kool_man.unhide() + elif self.level_index == 1: + self.visitor.unhide() + elif self.level_index == 2: + self.spoopy.unhide() + def start_level(self, index): self.level_index = index self.battle_finished = False @@ -1168,6 +1177,8 @@ class Boss(Animation): self.advance_prompt.reset() self.queue = None self.brandish_complete = True + self.halt(self.cancel_damaged) + self.damaged.hide() def deactivate(self): self.active = False @@ -1182,7 +1193,9 @@ class Boss(Animation): def brandish(self): self.queue = [] platform = self.get_game().platform + self.damaged.hide() if self.level_index == 0: + self.kool_man.hide() if self.health.amount > 90: first = choice(platform.get_steps_from_edge(self.last_attack)) self.queue = [first] @@ -1355,9 +1368,17 @@ class Boss(Animation): self.battle_finished = True self.halt(self.brandish) self.halt(self.cancel_flash) + self.halt(self.cancel_damaged) self.sword.reset() self.queue = [] self.brandish_complete = True + if self.level_index == 0: + self.kool_man.unhide() + elif self.level_index == 1: + self.visitor.unhide() + elif self.level_index == 2: + self.spoopy.unhide() + self.damaged.hide() if win: if self.level_index == 0: self.kool_man.set_frameset(0) @@ -1415,11 +1436,12 @@ class Boss(Animation): 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) def update(self): if self.active: self.backgrounds[self.level_index].update() - # self.get_display_surface().fill((0, 0, 0)) dialogue = self.get_game().dialogue if dialogue.active: if self.advance_prompt.check_first_press(): @@ -1437,6 +1459,7 @@ class Boss(Animation): else: self.time_elapsed += self.get_game().time_filter.get_last_frame_duration() Animation.update(self) + self.damaged.update() if self.level_index == 0: self.kool_man.update() elif self.level_index == 1: @@ -1457,22 +1480,30 @@ class Boss(Animation): class Sword(Animation): OFFSET = 10 + SPRITE_COUNT = 6 def __init__(self, parent): Animation.__init__(self, parent) image = load(self.get_resource("Sword.png")).convert_alpha() sprites = self.sprites = [] - for _ in xrange(6): + # for _ in xrange(6): + # sprite = Sprite(self) + # sprite.add_frame(image) + # for angle in 270, 315, 45: + # sprite.add_frame(rotate(image, angle)) + # sprite.add_frameset([0], name="vertical") + # sprite.add_frameset([1], name="horizontal") + # sprite.add_frameset([2], name="rdiagonal") + # sprite.add_frameset([3], name="ldiagonal") + # sprite.set_frameset("vertical") + # sprite.location.center = self.get_display_surface().get_rect().center + # sprites.append(sprite) + for _ in xrange(self.SPRITE_COUNT): sprite = Sprite(self) - sprite.add_frame(image) - for angle in 270, 315, 45: - sprite.add_frame(rotate(image, angle)) - sprite.add_frameset([0], name="vertical") - sprite.add_frameset([1], name="horizontal") - sprite.add_frameset([2], name="rdiagonal") - sprite.add_frameset([3], name="ldiagonal") - sprite.set_frameset("vertical") - sprite.location.center = self.get_display_surface().get_rect().center + sprite.load_from_path(self.get_resource("kool/"), True, query="[0-9]-*.png") + for ii in xrange(6): + sprite.add_frameset(ii) + sprite.location.topleft = 114, 0 sprites.append(sprite) self.register(self.brandish, self.lower) @@ -1489,26 +1520,27 @@ class Sword(Animation): self.next_index += 1 sprite.unhide() dsr = self.get_display_surface().get_rect() - if position in (NS.W, NS.E): - sprite.set_frameset("vertical") - sprite.location.centery = dsr.centery - 100 - if position == NS.W: - sprite.location.centerx = dsr.centerx - 100 - else: - sprite.location.centerx = dsr.centerx + 100 - elif position in (NS.N, NS.S): - sprite.set_frameset("horizontal") - sprite.location.centerx = dsr.centerx - if position == NS.N: - sprite.location.centery = dsr.centery - 200 - else: - sprite.location.centery = dsr.centery - else: - if position == NS.NW: - sprite.set_frameset("ldiagonal") - else: - sprite.set_frameset("rdiagonal") - sprite.location.center = dsr.centerx, dsr.centery - 100 + # if position in (NS.W, NS.E): + # sprite.set_frameset("vertical") + # sprite.location.centery = dsr.centery - 100 + # if position == NS.W: + # sprite.location.centerx = dsr.centerx - 100 + # else: + # sprite.location.centerx = dsr.centerx + 100 + # elif position in (NS.N, NS.S): + # sprite.set_frameset("horizontal") + # sprite.location.centerx = dsr.centerx + # if position == NS.N: + # sprite.location.centery = dsr.centery - 200 + # else: + # sprite.location.centery = dsr.centery + # else: + # if position == NS.NW: + # sprite.set_frameset("ldiagonal") + # else: + # sprite.set_frameset("rdiagonal") + # sprite.location.center = dsr.centerx, dsr.centery - 100 + sprite.set_frameset(position + 1) self.get_game().sfx["brandish"].play() self.play(self.lower, delay=400, play_once=True) if len(self.parent.unbrandished) > 0: @@ -1540,32 +1572,33 @@ class Sword(Animation): if not sprite.is_hidden(): display_index += 1 alpha = int(float(display_index) / display_count * 255) - frame = sprite.get_current_frame() - surface = frame.copy() + surface = sprite.get_current_frame().copy() rect = surface.get_rect() colors = self.get_game().platform.get_color_pair_from_edge(sprite.sword_position) color_a = colors[0].r, colors[0].g, colors[0].b, alpha color_b = colors[1].r, colors[1].g, colors[1].b, alpha + # color_a = 255, 255, 255, alpha + # color_b = 255, 255, 255, alpha if sprite.sword_position == NS.NE: location = sprite.location.move(*([offset[sprite.sword_position]] * 2)).topleft else: location = sprite.location.move(offset[sprite.sword_position], -offset[sprite.sword_position]) - if sprite.sword_position == NS.N or sprite.sword_position == NS.S: - surface.fill(color_a, (0, 0, rect.w / 2, rect.h), BLEND_RGBA_MULT) - surface.fill(color_b, (rect.centerx, 0, rect.w / 2, rect.h), BLEND_RGBA_MULT) - self.get_display_surface().blit(surface, location) - else: - surface.fill(color_a, (0, 0, rect.w, rect.h / 2), BLEND_RGBA_MULT) - surface.fill(color_b, (0, rect.centery, rect.w, rect.h / 2), BLEND_RGBA_MULT) - self.get_display_surface().blit(surface, location) + # if sprite.sword_position == NS.N or sprite.sword_position == NS.S: + # surface.fill(color_a, (0, 0, rect.w / 2, rect.h), BLEND_RGBA_MIN) + # surface.fill(color_b, (rect.centerx, 0, rect.w / 2, rect.h), BLEND_RGBA_MIN) + # else: + # surface.fill(color_a, (0, 0, rect.w, rect.h / 2), BLEND_RGBA_MIN) + # surface.fill(color_b, (0, rect.centery, rect.w, rect.h / 2), BLEND_RGBA_MIN) + surface.fill((255, 255, 255, alpha), None, BLEND_RGBA_MIN) + self.get_display_surface().blit(surface, location) offset[sprite.sword_position] += self.OFFSET # sprite.update() class Health(GameChild): - TEXT = "HP" + TEXT = "BOSS" BAR_POSITION = 23, 11 BACKGROUND_ALPHA = 125 diff --git a/resource/Kool_man.png b/resource/Kool_man.png deleted file mode 100644 index ece5227..0000000 Binary files a/resource/Kool_man.png and /dev/null differ diff --git a/resource/Kool_man_waah.png b/resource/Kool_man_waah.png new file mode 100644 index 0000000..3608a1a Binary files /dev/null and b/resource/Kool_man_waah.png differ diff --git a/resource/kool/0-N.png b/resource/kool/0-N.png new file mode 100644 index 0000000..fce0a9f Binary files /dev/null and b/resource/kool/0-N.png differ diff --git a/resource/kool/1-NE.png b/resource/kool/1-NE.png new file mode 100644 index 0000000..f6460f6 Binary files /dev/null and b/resource/kool/1-NE.png differ diff --git a/resource/kool/2-E.png b/resource/kool/2-E.png new file mode 100644 index 0000000..aa15732 Binary files /dev/null and b/resource/kool/2-E.png differ diff --git a/resource/kool/3-NW.png b/resource/kool/3-NW.png new file mode 100644 index 0000000..cde008f Binary files /dev/null and b/resource/kool/3-NW.png differ diff --git a/resource/kool/4-S.png b/resource/kool/4-S.png new file mode 100644 index 0000000..56accff Binary files /dev/null and b/resource/kool/4-S.png differ diff --git a/resource/kool/5-W.png b/resource/kool/5-W.png new file mode 100644 index 0000000..915f08f Binary files /dev/null and b/resource/kool/5-W.png differ diff --git a/resource/kool/damage.png b/resource/kool/damage.png new file mode 100644 index 0000000..e4687f8 Binary files /dev/null and b/resource/kool/damage.png differ diff --git a/resource/scores b/resource/scores index 421f809..3dc310d 100644 --- a/resource/scores +++ b/resource/scores @@ -29,3 +29,6 @@ 155712 247891 178357 +202333 +278582 +286504