This commit is contained in:
Frank DeMarco 2018-07-03 18:10:26 -04:00
parent 6b17bb1e24
commit 93af99ecf7
11 changed files with 117 additions and 81 deletions

195
NS.py
View File

@ -7,49 +7,27 @@ from glob import iglob
from os.path import basename from os.path import basename
from threading import Thread from threading import Thread
from serial import Serial from serial import Serial
from PIL import Image, ImageDraw
from pygame import Surface, Color from pygame import Surface, Color
from pygame.event import clear from pygame.event import clear
from pygame.mixer import Sound from pygame.mixer import Sound
from pygame.image import load from pygame.image import load, fromstring
from pygame.transform import rotate, flip from pygame.transform import rotate, flip
from pygame.time import get_ticks from pygame.time import get_ticks
from pygame.font import Font from pygame.font import Font
from pygame.gfxdraw import aapolygon from pygame.gfxdraw import aapolygon, arc
from pygame.locals import * from pygame.locals import *
from lib.pgfw.pgfw.Game import Game from lib.pgfw.pgfw.Game import Game
from lib.pgfw.pgfw.GameChild import GameChild from lib.pgfw.pgfw.GameChild import GameChild
from lib.pgfw.pgfw.Sprite import Sprite, RainbowSprite from lib.pgfw.pgfw.Sprite import Sprite, RainbowSprite
from lib.pgfw.pgfw.Animation import Animation 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, from lib.pgfw.pgfw.extension import (get_step, get_step_relative, get_delta, reflect_angle,
render_box) render_box)
from lib.pgfw.pgfw.gfx_extension import aa_filled_polygon 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): class NS(Game, Animation):
LNW, LNE, LSE, LSW = range(4) LNW, LNE, LSE, LSW = range(4)
@ -963,6 +941,7 @@ class Chemtrails(Sprite):
self.timer.reset() self.timer.reset()
if not boss.is_playing(boss.show_end_dialogue): if not boss.is_playing(boss.show_end_dialogue):
boss.combo() boss.combo()
boss.damaged.unhide()
self.get_game().sfx["complete_pattern"].play() self.get_game().sfx["complete_pattern"].play()
else: else:
self.get_game().sfx["land"].play() 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() self.time_remaining -= self.get_game().time_filter.get_last_frame_duration()
def update(self): def update(self):
self.background.update() # self.background.update()
self.label.update() # self.label.update()
if self.time_remaining > 5500: if self.time_remaining > 5500:
color = 0, 255, 0 color = Color(0, 255, 0)
elif self.time_remaining > 3000: elif self.time_remaining > 3000:
color = Color("orange") color = Color("orange")
else: else:
color = Color("red") color = Color("red")
mask = Surface(self.bar.get_size()) ds = self.get_display_surface()
mask.fill((128, 128, 128)) max_time = self.get_configuration("time", "timer-max-time")
width = min(mask.get_width(), mask.get_width() * float(self.time_remaining) / size = 160
self.get_configuration("time", "timer-max-time")) top = 120
mask.fill(color, (mask.get_width() - width, 0, width, mask.get_height())) image = Image.new("RGBA", (size, size))
surface = self.bar.copy() shadow = Image.new("RGBA", (size, size))
surface.blit(mask, (0, 0), None, BLEND_RGBA_MIN) draw = ImageDraw.Draw(image)
self.get_display_surface().blit(surface, self.BAR_POSITION) 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): class Life(GameChild):
@ -1085,13 +1082,16 @@ class Boss(Animation):
def __init__(self, parent): def __init__(self, parent):
Animation.__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.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.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.health = Health(self)
self.sword = Sword(self) self.sword = Sword(self)
self.register(self.brandish, self.cancel_flash, self.show_introduction_dialogue, 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.kool_man.add_frameset([0], name="normal", switch=True)
self.visitor.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.spoopy.add_frameset([0], name="normal", switch=True)
@ -1112,6 +1112,15 @@ class Boss(Animation):
elif self.level_index == 2: elif self.level_index == 2:
self.spoopy.set_frameset("normal") 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): def start_level(self, index):
self.level_index = index self.level_index = index
self.battle_finished = False self.battle_finished = False
@ -1168,6 +1177,8 @@ class Boss(Animation):
self.advance_prompt.reset() self.advance_prompt.reset()
self.queue = None self.queue = None
self.brandish_complete = True self.brandish_complete = True
self.halt(self.cancel_damaged)
self.damaged.hide()
def deactivate(self): def deactivate(self):
self.active = False self.active = False
@ -1182,7 +1193,9 @@ class Boss(Animation):
def brandish(self): def brandish(self):
self.queue = [] self.queue = []
platform = self.get_game().platform platform = self.get_game().platform
self.damaged.hide()
if self.level_index == 0: if self.level_index == 0:
self.kool_man.hide()
if self.health.amount > 90: if self.health.amount > 90:
first = choice(platform.get_steps_from_edge(self.last_attack)) first = choice(platform.get_steps_from_edge(self.last_attack))
self.queue = [first] self.queue = [first]
@ -1355,9 +1368,17 @@ class Boss(Animation):
self.battle_finished = True self.battle_finished = True
self.halt(self.brandish) self.halt(self.brandish)
self.halt(self.cancel_flash) self.halt(self.cancel_flash)
self.halt(self.cancel_damaged)
self.sword.reset() self.sword.reset()
self.queue = [] self.queue = []
self.brandish_complete = True 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 win:
if self.level_index == 0: if self.level_index == 0:
self.kool_man.set_frameset(0) self.kool_man.set_frameset(0)
@ -1415,11 +1436,12 @@ class Boss(Animation):
self.kool_man.set_frameset(0) self.kool_man.set_frameset(0)
elif self.level_index == 1: elif self.level_index == 1:
self.visitor.set_frameset(0) self.visitor.set_frameset(0)
elif self.level_index == 2:
self.spoopy.set_frameset(0)
def update(self): def update(self):
if self.active: if self.active:
self.backgrounds[self.level_index].update() self.backgrounds[self.level_index].update()
# self.get_display_surface().fill((0, 0, 0))
dialogue = self.get_game().dialogue dialogue = self.get_game().dialogue
if dialogue.active: if dialogue.active:
if self.advance_prompt.check_first_press(): if self.advance_prompt.check_first_press():
@ -1437,6 +1459,7 @@ class Boss(Animation):
else: else:
self.time_elapsed += self.get_game().time_filter.get_last_frame_duration() self.time_elapsed += self.get_game().time_filter.get_last_frame_duration()
Animation.update(self) Animation.update(self)
self.damaged.update()
if self.level_index == 0: if self.level_index == 0:
self.kool_man.update() self.kool_man.update()
elif self.level_index == 1: elif self.level_index == 1:
@ -1457,22 +1480,30 @@ class Boss(Animation):
class Sword(Animation): class Sword(Animation):
OFFSET = 10 OFFSET = 10
SPRITE_COUNT = 6
def __init__(self, parent): def __init__(self, parent):
Animation.__init__(self, parent) Animation.__init__(self, parent)
image = load(self.get_resource("Sword.png")).convert_alpha() image = load(self.get_resource("Sword.png")).convert_alpha()
sprites = self.sprites = [] 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 = Sprite(self)
sprite.add_frame(image) sprite.load_from_path(self.get_resource("kool/"), True, query="[0-9]-*.png")
for angle in 270, 315, 45: for ii in xrange(6):
sprite.add_frame(rotate(image, angle)) sprite.add_frameset(ii)
sprite.add_frameset([0], name="vertical") sprite.location.topleft = 114, 0
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) sprites.append(sprite)
self.register(self.brandish, self.lower) self.register(self.brandish, self.lower)
@ -1489,26 +1520,27 @@ class Sword(Animation):
self.next_index += 1 self.next_index += 1
sprite.unhide() sprite.unhide()
dsr = self.get_display_surface().get_rect() dsr = self.get_display_surface().get_rect()
if position in (NS.W, NS.E): # if position in (NS.W, NS.E):
sprite.set_frameset("vertical") # sprite.set_frameset("vertical")
sprite.location.centery = dsr.centery - 100 # sprite.location.centery = dsr.centery - 100
if position == NS.W: # if position == NS.W:
sprite.location.centerx = dsr.centerx - 100 # sprite.location.centerx = dsr.centerx - 100
else: # else:
sprite.location.centerx = dsr.centerx + 100 # sprite.location.centerx = dsr.centerx + 100
elif position in (NS.N, NS.S): # elif position in (NS.N, NS.S):
sprite.set_frameset("horizontal") # sprite.set_frameset("horizontal")
sprite.location.centerx = dsr.centerx # sprite.location.centerx = dsr.centerx
if position == NS.N: # if position == NS.N:
sprite.location.centery = dsr.centery - 200 # sprite.location.centery = dsr.centery - 200
else: # else:
sprite.location.centery = dsr.centery # sprite.location.centery = dsr.centery
else: # else:
if position == NS.NW: # if position == NS.NW:
sprite.set_frameset("ldiagonal") # sprite.set_frameset("ldiagonal")
else: # else:
sprite.set_frameset("rdiagonal") # sprite.set_frameset("rdiagonal")
sprite.location.center = dsr.centerx, dsr.centery - 100 # sprite.location.center = dsr.centerx, dsr.centery - 100
sprite.set_frameset(position + 1)
self.get_game().sfx["brandish"].play() self.get_game().sfx["brandish"].play()
self.play(self.lower, delay=400, play_once=True) self.play(self.lower, delay=400, play_once=True)
if len(self.parent.unbrandished) > 0: if len(self.parent.unbrandished) > 0:
@ -1540,32 +1572,33 @@ class Sword(Animation):
if not sprite.is_hidden(): if not sprite.is_hidden():
display_index += 1 display_index += 1
alpha = int(float(display_index) / display_count * 255) alpha = int(float(display_index) / display_count * 255)
frame = sprite.get_current_frame() surface = sprite.get_current_frame().copy()
surface = frame.copy()
rect = surface.get_rect() rect = surface.get_rect()
colors = self.get_game().platform.get_color_pair_from_edge(sprite.sword_position) 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_a = colors[0].r, colors[0].g, colors[0].b, alpha
color_b = colors[1].r, colors[1].g, colors[1].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: if sprite.sword_position == NS.NE:
location = sprite.location.move(*([offset[sprite.sword_position]] * 2)).topleft location = sprite.location.move(*([offset[sprite.sword_position]] * 2)).topleft
else: else:
location = sprite.location.move(offset[sprite.sword_position], location = sprite.location.move(offset[sprite.sword_position],
-offset[sprite.sword_position]) -offset[sprite.sword_position])
if sprite.sword_position == NS.N or sprite.sword_position == NS.S: # 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_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_MULT) # surface.fill(color_b, (rect.centerx, 0, rect.w / 2, rect.h), BLEND_RGBA_MIN)
self.get_display_surface().blit(surface, location) # else:
else: # surface.fill(color_a, (0, 0, rect.w, rect.h / 2), BLEND_RGBA_MIN)
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_MIN)
surface.fill(color_b, (0, rect.centery, rect.w, rect.h / 2), BLEND_RGBA_MULT) surface.fill((255, 255, 255, alpha), None, BLEND_RGBA_MIN)
self.get_display_surface().blit(surface, location) self.get_display_surface().blit(surface, location)
offset[sprite.sword_position] += self.OFFSET offset[sprite.sword_position] += self.OFFSET
# sprite.update() # sprite.update()
class Health(GameChild): class Health(GameChild):
TEXT = "HP" TEXT = "BOSS"
BAR_POSITION = 23, 11 BAR_POSITION = 23, 11
BACKGROUND_ALPHA = 125 BACKGROUND_ALPHA = 125

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

BIN
resource/Kool_man_waah.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
resource/kool/0-N.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
resource/kool/1-NE.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
resource/kool/2-E.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
resource/kool/3-NW.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
resource/kool/4-S.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
resource/kool/5-W.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
resource/kool/damage.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -29,3 +29,6 @@
155712 155712
247891 247891
178357 178357
202333
278582
286504