From eec39049fa4f5fb72c7acbf172b4b631b35166da Mon Sep 17 00:00:00 2001 From: Frank DeMarco Date: Thu, 20 Sep 2018 04:57:06 -0400 Subject: [PATCH] dots --- NS.py | 230 ++++++++++++++++++---------------------- resource/HUD_boss.png | Bin 0 -> 952 bytes resource/HUD_circle.png | Bin 0 -> 121 bytes resource/HUD_health.png | Bin 0 -> 1067 bytes resource/HUD_lives.png | Bin 0 -> 1013 bytes resource/HUD_timer.png | Bin 0 -> 1666 bytes resource/scores | 4 - 7 files changed, 103 insertions(+), 131 deletions(-) create mode 100644 resource/HUD_boss.png create mode 100644 resource/HUD_circle.png create mode 100644 resource/HUD_health.png create mode 100644 resource/HUD_lives.png create mode 100644 resource/HUD_timer.png diff --git a/NS.py b/NS.py index 2775e3a..ca50f3c 100644 --- a/NS.py +++ b/NS.py @@ -7,7 +7,6 @@ from glob import iglob from os.path import basename, join from threading import Thread from serial import Serial -from PIL import Image, ImageDraw from pygame import Surface, Color from pygame.event import clear @@ -27,7 +26,8 @@ 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, get_hsla_color, get_hue_shifted_surface + render_box, get_hsla_color, get_hue_shifted_surface, + get_color_swapped_surface ) from lib.pgfw.pgfw.gfx_extension import aa_filled_polygon @@ -44,6 +44,17 @@ class NS(Game, Animation): def __init__(self): Game.__init__(self) + self.get_configuration().type_declarations.add_chart( + { + "time": + { + "int": ["timer-max-time", "timer-start-time", "timer-addition", "sword-delay"] + }, + "input": + { + "bool": "serial" + } + }) Animation.__init__(self, self) self.load_sfx() self.subscribe(self.respond, KEYDOWN) @@ -60,17 +71,6 @@ class NS(Game, Animation): self.dialogue = Dialogue(self) self.chemtrails = Chemtrails(self) self.boss = Boss(self) - self.get_configuration().type_declarations.add_chart( - { - "time": - { - "int": ["timer-max-time", "timer-start-time", "timer-addition", "sword-delay"] - }, - "input": - { - "bool": "serial" - } - }) if self.serial_enabled(): self.serial_kill = False self.serial_data = 0 @@ -222,6 +222,50 @@ class Button(Sprite): self.add_frame(frame) +class Meter(GameChild): + + SPACING = 12 + + def __init__(self, parent): + GameChild.__init__(self, parent) + + def setup(self, background, rect, indent, color, units): + self.background = background + self.rect = rect + self.icons = [] + x = rect.left + indent + base = get_color_swapped_surface( + load(self.get_resource("HUD_circle.png")).convert_alpha(), + (0, 0, 0), color) + while x <= self.rect.right - base.get_width() - self.SPACING: + icon = Sprite(self) + icon.add_frame(base) + icon.location.midleft = x, self.rect.centery + self.icons.append(icon) + x += icon.location.w + self.SPACING + self.units = units + + def reset(self): + self.amount = self.units + for icon in self.icons: + icon.unhide() + + def change(self, delta): + self.amount += delta + cutoff = float(self.amount) / self.units * len(self.icons) + for ii, icon in enumerate(self.icons): + if ii < cutoff: + icon.unhide() + else: + icon.hide() + + def update(self): + ds = self.get_display_surface() + ds.blit(self.background, self.rect) + for icon in self.icons: + icon.update() + + class Title(GameChild): def __init__(self, parent): @@ -1010,11 +1054,13 @@ class Chemtrails(Sprite): for direction in (NS.N, NS.NE, NS.E, NS.NW, NS.S, NS.W): self.add_frameset([direction], switch=(direction == NS.N)) self.life = Life(self) + self.boys = Boys(self) self.timer = Timer(self) def reset(self): self.deactivate() self.life.reset() + self.boys.reset() self.timer.reset() def deactivate(self): @@ -1036,13 +1082,15 @@ class Chemtrails(Sprite): if boss.queue: self.timer.tick() self.attack() - if self.timer.time_remaining < 0: + if self.timer.amount < 0: self.life.decrease() if not boss.is_playing(boss.show_end_dialogue): self.timer.reset() boss.combo() - # self.timer.update() - self.life.update() + if not boss.is_playing(boss.show_introduction_dialogue): + self.timer.update() + self.life.update() + self.boys.update() def attack(self): boss = self.get_game().boss @@ -1103,94 +1151,52 @@ class Chemtrails(Sprite): self.orientation = None -class Timer(GameChild): - - TEXT = u"\u25F7" - BAR_POSITION = 448, 11 - SIZE = 160 - TOP = 120 - RING_OFFSET = 8 +class Timer(Meter): def __init__(self, parent): - GameChild.__init__(self, parent) - self.background = Sprite(self) - image = load(self.get_resource("HUD_background.png")).convert_alpha() - image = flip(image, True, False) - self.background.add_frame(image) - self.background.location.topright = self.get_display_surface().get_rect().topright - self.bar = load(self.get_resource("HUD_bar.png")).convert_alpha() - self.bar = flip(self.bar, True, False) - self.hourglass = Sprite(self) - self.hourglass.load_from_path(self.get_resource("Hourglass.png"), True) + Meter.__init__(self, parent) dsr = self.get_display_surface().get_rect() - self.hourglass.location.midright = dsr.right, self.TOP + self.SIZE / 2 - - def reset(self): - self.time_remaining = self.get_configuration("time", "timer-start-time") + background = load(self.get_resource("HUD_timer.png")).convert() + rect = background.get_rect() + rect.bottomright = dsr.right - 6, dsr.bottom - 4 + self.setup(background, rect, 53, (0, 0, 255), + self.get_configuration("time", "timer-start-time")) def add_time(self, amount): - self.time_remaining += amount + self.change(amount) def tick(self): - self.time_remaining -= self.get_game().time_filter.get_last_frame_duration() - - def update(self): - self.hourglass.update() - if self.time_remaining > 5500: - hue = 120 - elif self.time_remaining > 3000: - hue = 30 - else: - hue = 0 - ds = self.get_display_surface() - max_time = self.get_configuration("time", "timer-max-time") - remaining_ratio = float(self.time_remaining) / max_time - left = ds.get_width() - self.SIZE / 2 - ds.blit(self.get_ring(get_hsla_color(hue, lightness=20, alpha=67), remaining_ratio), - (left, self.TOP + self.RING_OFFSET)) - ds.blit(self.get_ring(get_hsla_color(hue, lightness=80, alpha=67), remaining_ratio), - (left, self.TOP - self.RING_OFFSET)) - ds.blit(self.get_ring(get_hsla_color(hue, alpha=67), remaining_ratio), (left, self.TOP)) - - def get_ring(self, color, remaining): - image = Image.new("RGBA", (self.SIZE, self.SIZE)) - draw = ImageDraw.Draw(image) - draw.pieslice((0, 0, self.SIZE - 1, self.SIZE - 1), 90, remaining * 180 + 90, - fill=(color.r, color.g, color.b, color.a)) - draw.ellipse((self.SIZE / 4, self.SIZE / 4, self.SIZE / 4 * 3, self.SIZE / 4 * 3), (0, 0, 0, 0)) - string = fromstring(image.tobytes(), image.size, image.mode) - image.close() - return string + self.change(-self.get_game().time_filter.get_last_frame_duration()) -class Life(GameChild): - - SPACING = 30 - MARGIN = 0 +class Life(Meter): def __init__(self, parent): - GameChild.__init__(self, parent) - self.heart = load(self.get_resource("Heart.png")).convert_alpha() - - def reset(self): - self.count = 3 + Meter.__init__(self, parent) + dsr = self.get_display_surface().get_rect() + background = load(self.get_resource("HUD_health.png")).convert() + rect = background.get_rect() + rect.bottomleft = 172, dsr.bottom - 4 + self.setup(background, rect, 70, (255, 0, 0), 3) def decrease(self): self.get_game().sfx["hurt"].play() - if self.count > 0: - self.count -= 1 - if self.count <= 0: - self.count = 0 + self.change(-1) + if self.amount <= 0: + self.amount = 0 + self.parent.boys.change(-1) self.get_game().boss.finish_battle(False) - def update(self): - ds = self.get_display_surface() - dsr = ds.get_rect() - hr = self.heart.get_rect() - rect = Rect(0, 0, hr.w * self.count + self.SPACING * (self.count - 1), hr.h) - rect.midbottom = dsr.centerx, dsr.h - self.MARGIN - for x in xrange(rect.left, rect.right, hr.w + self.SPACING): - ds.blit(self.heart, (x, rect.top)) + +class Boys(Meter): + + def __init__(self, parent): + Meter.__init__(self, parent) + dsr = self.get_display_surface().get_rect() + background = load(self.get_resource("HUD_lives.png")).convert() + rect = background.get_rect() + rect.bottomleft = 6, dsr.bottom - 4 + self.setup(background, rect, 60, (0, 255, 0), 3) class Boss(Animation): @@ -1227,7 +1233,7 @@ class Boss(Animation): self.spoopy.set_frameset("normal") def start_level(self, index): - self.level_index = 2 + self.level_index = index self.battle_finished = False self.player_defeated = False self.health.reset() @@ -1669,34 +1675,20 @@ class Sword(Animation): sprite.update(substitute=substitute) -class Health(GameChild): +class Health(Meter): - TEXT = "BOSS" - BAR_POSITION = 23, 11 - BACKGROUND_ALPHA = 125 - OFFSET = 11 + OFFSET = 4 def __init__(self, parent): - GameChild.__init__(self, parent) - self.background = Sprite(self) - self.background.load_from_path(self.get_resource("HUD_boss_health_background.png"), True) + Meter.__init__(self, parent) dsr = self.get_display_surface().get_rect() - self.background.location.center = dsr.centerx, self.OFFSET - self.foreground = Sprite(self) - self.foreground.load_from_path(self.get_resource("HUD_boss_health_foreground.png"), True) - self.foreground.location.center = dsr.centerx, self.OFFSET - self.label = Sprite(self) - font = Font(self.get_resource("rounded-mplus-1m-bold.ttf"), 24) - text = font.render(self.TEXT, True, Color("white")) - self.label.add_frame(text) - self.label.location.topleft = 2, -2 - self.bar = load(self.get_resource("HUD_bar.png")).convert_alpha() - - def reset(self): - self.amount = 100 + background = load(self.get_resource("HUD_boss.png")).convert() + rect = background.get_rect() + rect.midtop = dsr.centerx, self.OFFSET + self.setup(background, rect, 52, (255, 0, 255), 100) def decrease(self, damage): - self.amount -= damage + self.change(-damage) self.parent.damage() if self.amount <= 0: self.amount = 0 @@ -1706,22 +1698,6 @@ class Health(GameChild): else: self.parent.play(self.parent.cancel_flash, delay=1000, play_once=True) - def update(self): - self.background.update() - if self.amount > 50: - shift = 0 - elif self.amount > 25: - shift = -70 - else: - shift = -120 - ratio = self.amount / 100.0 - ds = self.get_display_surface() - ds.set_clip((self.foreground.location.left, self.foreground.location.top, - int(self.foreground.location.w * ratio), self.foreground.location.h)) - surface = get_hue_shifted_surface(self.foreground.get_current_frame(), shift) - ds.blit(surface, self.foreground.location.topleft) - ds.set_clip(None) - class Ending(Animation): diff --git a/resource/HUD_boss.png b/resource/HUD_boss.png new file mode 100644 index 0000000000000000000000000000000000000000..02a1063a92164f8b71ea72380b03029f32ee0f5e GIT binary patch literal 952 zcmeAS@N?(olHy`uVBq!ia0y~yU@8EzYW zV9xS%aSW-r_4clzhgGf2@sH=HF51Gf?TUPKR1{Z~%PPy}mbPhPo!teQ9ZcFvT-w>( zx3rFEb`-2s_2SBWBkvKAD5!NY$lEzEN#(BbA4fUOe>cAU_)yo_Tpr*5xcs#Ad1vQI zszAF#c%!$@S&@2iCXn5hxS}l;NUzXikpWVS>_CEv4@h9)9{8{RVA`~4Uw-~v+279} z#>&93K#D0ZJKK9>gpb+m-cUxMF>MXI_wK!V^eC$~69YqlF37wFExsKqS8Cq9e}8p= z#*3dnBgMtVxmcK%{w*#pK9yorRb74g_U+k5Gkcyrdv>aCgqX4clmmhFzUo9}=3?%krDF_S_r@&HZM;@L5IvhdHE zeVcN_!^3CInG+HmJQ-+yRaMogZ}PITCrx~T`gg|Y-OMoqS@7(c+w|$vyIho_;^MCT z{=Hiz)Px!6!S(z0w(i=w^JnVqfB*JHMMpm^+9}fOw*O84(WI=5jDY<7^+KI3Wo2b4 zvzC4P_HD}9w5jKxn_5_`m_A+Ha~0ToqHJ>xKm4)jY~J?&FAf|(e*D+h*VEb9*i6jK zmVNzNx_95ctg5PC?#4hTYkYsJd*$NAz})=&>GyWu&HMWOyY^ha({IbPC3v*t`lr{X zrKGs{`}=#T2ywAB-@0)lptyLmn3$NC@xy`$V`F2e&;JP(=<4bMgKzSe=L=hM%vP6J z=`O##vagTt>eZ{66%`S2>%$*Ee(be0$ja7sYHH-GH*Z4R-P^BSyQbplw>;R?)O6O| zxl@ln4%C_&l$^Zy*RNkwPCwO}2TTG7;+f8w__8)TigvrMUAIn4faApT&zkekYfnF| zDb$%!ULO9jBIf-0^HNe$lQL%+@i_DI^GC(R=+sXB_T$Hjq>UQ8@9OQpufPBP`s>%j z@7}qSQCGL`ktERPHK`t(Ry}mlJ^d&PXw9Ru20zq+DWf4PcvoxI%kTA@jh;T$0!sYh zzJCBn34pSk!UG@?a42{Mkh&_8-xg>KPLTHh82?SmeYt|S>@QG)!PC{xWt~$(69BE~ Bm`4Br literal 0 HcmV?d00001 diff --git a/resource/HUD_circle.png b/resource/HUD_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..a99fdf7788681009a16c9bcffeb0638c99b5a961 GIT binary patch literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa2TvEr5RLQ6DF^ueE&eDe$-(g_ z{Q$qj#!QtZoUZ)JowFXynkjLDr6=Xau>(Nhu&wvYbqj-qUV%&tG)_*Oa)QxHj#Kz{ Szq~WhECx?kKbLh*2~7a%C?_ZY literal 0 HcmV?d00001 diff --git a/resource/HUD_health.png b/resource/HUD_health.png new file mode 100644 index 0000000000000000000000000000000000000000..8cb09221142585266f97fc192744dd1482e9a776 GIT binary patch literal 1067 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 M07*qoM6N<$f+GAh1poj5 literal 0 HcmV?d00001 diff --git a/resource/scores b/resource/scores index 2546f5f..d4c0f1d 100644 --- a/resource/scores +++ b/resource/scores @@ -15,7 +15,3 @@ 171204 256769 312561 -167744 -91410 -41874 -32477