This commit is contained in:
Frank DeMarco 2018-09-20 04:57:06 -04:00
parent 41c647b1e9
commit eec39049fa
7 changed files with 103 additions and 131 deletions

230
NS.py
View File

@ -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):

BIN
resource/HUD_boss.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 B

BIN
resource/HUD_circle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 B

BIN
resource/HUD_health.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
resource/HUD_lives.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1013 B

BIN
resource/HUD_timer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -15,7 +15,3 @@
171204
256769
312561
167744
91410
41874
32477