|
|
|
@ -8,13 +8,14 @@ from pygame.image import load
|
|
|
|
|
from pygame.transform import rotate
|
|
|
|
|
from pygame.time import get_ticks
|
|
|
|
|
from pygame.font import Font
|
|
|
|
|
from pygame.gfxdraw import aapolygon
|
|
|
|
|
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.extension import get_step_relative, get_delta, reflect_angle
|
|
|
|
|
from lib.pgfw.pgfw.extension import get_step, get_step_relative, get_delta, reflect_angle
|
|
|
|
|
from lib.pgfw.pgfw.gfx_extension import aa_filled_polygon
|
|
|
|
|
|
|
|
|
|
class SoundEffect(GameChild, Sound):
|
|
|
|
@ -43,7 +44,7 @@ class SoundEffect(GameChild, Sound):
|
|
|
|
|
|
|
|
|
|
class NS(Game, Animation):
|
|
|
|
|
|
|
|
|
|
NW, NE, SE, SW = range(4)
|
|
|
|
|
LNW, LNE, LSE, LSW = range(4)
|
|
|
|
|
N, E, S, W, NE, NW = range(6)
|
|
|
|
|
FRONT_WIDTH = 230
|
|
|
|
|
BACK_WIDTH = 500
|
|
|
|
@ -96,15 +97,15 @@ class NS(Game, Animation):
|
|
|
|
|
pressed = True if event.type == KEYDOWN else False
|
|
|
|
|
lights = self.platform.lights
|
|
|
|
|
if event.key in (K_UP, K_o):
|
|
|
|
|
lights[0].pressed = pressed
|
|
|
|
|
lights[NS.LNW].pressed = pressed
|
|
|
|
|
if self.game_over and not self.suppress_restart:
|
|
|
|
|
self.reset()
|
|
|
|
|
elif event.key in (K_RIGHT, K_p):
|
|
|
|
|
lights[1].pressed = pressed
|
|
|
|
|
lights[NS.LNE].pressed = pressed
|
|
|
|
|
elif event.key in (K_DOWN, K_SEMICOLON):
|
|
|
|
|
lights[2].pressed = pressed
|
|
|
|
|
lights[NS.LSE].pressed = pressed
|
|
|
|
|
elif event.key in (K_LEFT, K_l):
|
|
|
|
|
lights[3].pressed = pressed
|
|
|
|
|
lights[NS.LSW].pressed = pressed
|
|
|
|
|
self.last_press = get_ticks()
|
|
|
|
|
else:
|
|
|
|
|
if self.get_delegate().compare(event, "reset-game"):
|
|
|
|
@ -140,8 +141,10 @@ class NS(Game, Animation):
|
|
|
|
|
self.title.update()
|
|
|
|
|
self.introduction.update()
|
|
|
|
|
self.boss.update()
|
|
|
|
|
self.platform.update()
|
|
|
|
|
if not self.introduction.active:
|
|
|
|
|
self.platform.update()
|
|
|
|
|
self.chemtrails.update()
|
|
|
|
|
self.boss.update_dialogue()
|
|
|
|
|
if self.game_over:
|
|
|
|
|
self.message.update()
|
|
|
|
|
if not self.suppress_restart:
|
|
|
|
@ -321,32 +324,40 @@ class Introduction(Animation):
|
|
|
|
|
TEXT = "Hey, you lizard slime bag. It's me Giant Tony. " + \
|
|
|
|
|
"Do you think you\ncan skate like me? Prove it!", \
|
|
|
|
|
"I'll even give you my board for this adventure. And ink my name\n" + \
|
|
|
|
|
"on it. Now the power of Giant Tony pulses through you."
|
|
|
|
|
"on it. Now the power of Giant Tony pulses through you.", \
|
|
|
|
|
"Before you go, show me you can scrape! Use your board to touch\n" + \
|
|
|
|
|
"the glowing pads on the platform!", \
|
|
|
|
|
"Great job, lizard scum! Maybe now you're ready to take on Kool\n" + \
|
|
|
|
|
"Man and his friends. Don't let me down!"
|
|
|
|
|
SKATEBOARD_START = -30, -20
|
|
|
|
|
TUTORIAL_MOVES = NS.S, NS.NE, NS.N, NS.E, NS.NW, NS.W, NS.E, NS.W
|
|
|
|
|
|
|
|
|
|
def __init__(self, parent):
|
|
|
|
|
Animation.__init__(self, parent)
|
|
|
|
|
self.tony = load(self.get_resource("Big_Tony.png")).convert()
|
|
|
|
|
self.skateboard = Sprite(self)
|
|
|
|
|
self.skateboard.load_from_path(self.get_resource("Introduction_skateboard.png"), True)
|
|
|
|
|
self.skateboard.hide()
|
|
|
|
|
self.slime_bag = Sprite(self)
|
|
|
|
|
self.slime_bag.load_from_path(self.get_resource("Introduction_slime_bag.png"), True)
|
|
|
|
|
self.slime_bag.load_from_path(self.get_resource("Introduction_slime_bag_board.png"), True)
|
|
|
|
|
self.slime_bag.add_frameset([0], name="standing", switch=True)
|
|
|
|
|
self.slime_bag.add_frameset([1], name="board")
|
|
|
|
|
self.slime_bag.location.center = self.get_display_surface().get_rect().center
|
|
|
|
|
self.tony_avatar = load(self.get_resource("Introduction_tony_avatar.png")).convert()
|
|
|
|
|
self.advance_prompt = Sprite(self)
|
|
|
|
|
self.advance_prompt.load_from_path(self.get_resource("Dialogue_buttons_full.png"), True,
|
|
|
|
|
False, (255, 255, 255))
|
|
|
|
|
self.advance_prompt.load_from_path(self.get_resource("Dialogue_buttons_half.png"), True,
|
|
|
|
|
False, (255, 255, 255))
|
|
|
|
|
self.advance_prompt.add_frameset([0], name="full", switch=True)
|
|
|
|
|
self.advance_prompt.add_frameset([1], name="half")
|
|
|
|
|
dsr = self.get_display_surface().get_rect()
|
|
|
|
|
self.advance_prompt.location.bottomright = dsr.right - 3, dsr.bottom - 3
|
|
|
|
|
self.register(self.start)
|
|
|
|
|
self.advance_prompt = AdvancePrompt(self)
|
|
|
|
|
self.skip_prompt = SkipPrompt(self, self.start_wipe)
|
|
|
|
|
self.register(self.start, self.move_board, self.take_board)
|
|
|
|
|
|
|
|
|
|
def reset(self):
|
|
|
|
|
self.deactivate()
|
|
|
|
|
self.cancel_first_press()
|
|
|
|
|
self.slime_bag.set_frameset("standing")
|
|
|
|
|
self.slime_bag.unhide()
|
|
|
|
|
self.halt()
|
|
|
|
|
self.skateboard.hide()
|
|
|
|
|
self.text_index = 0
|
|
|
|
|
self.tutorial_index = 0
|
|
|
|
|
self.advance_prompt.reset()
|
|
|
|
|
self.skip_prompt.reset()
|
|
|
|
|
|
|
|
|
|
def deactivate(self):
|
|
|
|
|
self.active = False
|
|
|
|
@ -356,7 +367,7 @@ class Introduction(Animation):
|
|
|
|
|
self.play(self.start, delay=3000, play_once=True)
|
|
|
|
|
|
|
|
|
|
def start(self):
|
|
|
|
|
self.cancel_first_press()
|
|
|
|
|
self.advance_prompt.cancel_first_press()
|
|
|
|
|
dialogue = self.get_game().dialogue
|
|
|
|
|
dialogue.activate()
|
|
|
|
|
dialogue.set_avatar(self.tony_avatar)
|
|
|
|
@ -364,37 +375,152 @@ class Introduction(Animation):
|
|
|
|
|
dialogue.show_text(self.TEXT[0])
|
|
|
|
|
self.text_index = 0
|
|
|
|
|
|
|
|
|
|
def cancel_first_press(self):
|
|
|
|
|
self.first_pressed = False
|
|
|
|
|
self.first_pressed_elapsed = 0
|
|
|
|
|
self.advance_prompt.set_frameset("full")
|
|
|
|
|
def give_board(self):
|
|
|
|
|
self.skateboard.location.center = self.SKATEBOARD_START
|
|
|
|
|
self.skateboard_step = get_step(self.skateboard.location.center, self.slime_bag.location.center, 2)
|
|
|
|
|
self.skateboard.unhide()
|
|
|
|
|
self.play(self.move_board)
|
|
|
|
|
|
|
|
|
|
def move_board(self):
|
|
|
|
|
self.skateboard.move(*self.skateboard_step)
|
|
|
|
|
if self.skateboard.location.colliderect(self.slime_bag.location.inflate(-30, -30)):
|
|
|
|
|
self.halt(self.move_board)
|
|
|
|
|
self.play(self.take_board, delay=2000, play_once=True)
|
|
|
|
|
|
|
|
|
|
def take_board(self):
|
|
|
|
|
self.skateboard.hide()
|
|
|
|
|
self.slime_bag.set_frameset("board")
|
|
|
|
|
|
|
|
|
|
def activate_boss(self):
|
|
|
|
|
self.deactivate()
|
|
|
|
|
self.get_game().boss.start_level()
|
|
|
|
|
|
|
|
|
|
def start_wipe(self):
|
|
|
|
|
self.get_game().wipe.start(self.activate_boss)
|
|
|
|
|
|
|
|
|
|
def update(self):
|
|
|
|
|
if self.active:
|
|
|
|
|
Animation.update(self)
|
|
|
|
|
dialogue = self.get_game().dialogue
|
|
|
|
|
if not self.first_pressed and self.get_game().platform.get_edge_pressed() == NS.N:
|
|
|
|
|
self.first_pressed = True
|
|
|
|
|
self.advance_prompt.set_frameset("half")
|
|
|
|
|
elif self.first_pressed and self.get_game().platform.get_edge_pressed() == NS.NW:
|
|
|
|
|
if dialogue.is_playing():
|
|
|
|
|
dialogue.show_all()
|
|
|
|
|
else:
|
|
|
|
|
self.text_index += 1
|
|
|
|
|
if self.text_index == 1:
|
|
|
|
|
dialogue.set_name("Tony")
|
|
|
|
|
dialogue.show_text(self.TEXT[self.text_index])
|
|
|
|
|
self.get_game().platform.unpress()
|
|
|
|
|
self.cancel_first_press()
|
|
|
|
|
elif self.first_pressed:
|
|
|
|
|
self.first_pressed_elapsed += self.get_game().time_filter.get_last_frame_duration()
|
|
|
|
|
if self.first_pressed_elapsed > 4000:
|
|
|
|
|
self.cancel_first_press()
|
|
|
|
|
wipe = self.get_game().wipe
|
|
|
|
|
if not wipe.is_playing() and not self.is_playing(self.start) and not self.text_index == 2:
|
|
|
|
|
if self.advance_prompt.check_first_press():
|
|
|
|
|
self.advance_prompt.press_first()
|
|
|
|
|
elif self.advance_prompt.check_second_press():
|
|
|
|
|
if dialogue.is_playing():
|
|
|
|
|
dialogue.show_all()
|
|
|
|
|
else:
|
|
|
|
|
if self.text_index < len(self.TEXT) - 1:
|
|
|
|
|
self.text_index += 1
|
|
|
|
|
if self.text_index == 1:
|
|
|
|
|
dialogue.set_name("Tony")
|
|
|
|
|
self.give_board()
|
|
|
|
|
elif self.text_index == 2:
|
|
|
|
|
self.slime_bag.hide()
|
|
|
|
|
self.halt(self.move_board)
|
|
|
|
|
self.take_board()
|
|
|
|
|
platform = self.get_game().platform
|
|
|
|
|
platform.activate()
|
|
|
|
|
platform.set_glowing(platform.get_buttons_from_edges(
|
|
|
|
|
[self.TUTORIAL_MOVES[self.tutorial_index]]))
|
|
|
|
|
self.get_game().chemtrails.activate()
|
|
|
|
|
dialogue.show_text(self.TEXT[self.text_index])
|
|
|
|
|
else:
|
|
|
|
|
self.start_wipe()
|
|
|
|
|
self.get_game().platform.unpress()
|
|
|
|
|
self.advance_prompt.cancel_first_press()
|
|
|
|
|
elif self.text_index == 2:
|
|
|
|
|
platform = self.get_game().platform
|
|
|
|
|
if platform.get_edge_pressed() == self.TUTORIAL_MOVES[self.tutorial_index]:
|
|
|
|
|
self.tutorial_index += 1
|
|
|
|
|
if self.tutorial_index == len(self.TUTORIAL_MOVES):
|
|
|
|
|
self.text_index += 1
|
|
|
|
|
self.advance_prompt.cancel_first_press()
|
|
|
|
|
platform.set_glowing([])
|
|
|
|
|
dialogue.show_text(self.TEXT[self.text_index])
|
|
|
|
|
else:
|
|
|
|
|
platform.set_glowing(platform.get_buttons_from_edges(
|
|
|
|
|
[self.TUTORIAL_MOVES[self.tutorial_index]]))
|
|
|
|
|
self.get_display_surface().blit(self.tony, (0, 0))
|
|
|
|
|
self.slime_bag.update()
|
|
|
|
|
self.skateboard.update()
|
|
|
|
|
self.get_game().platform.update()
|
|
|
|
|
self.get_game().dialogue.update()
|
|
|
|
|
if not self.is_playing(self.start) and not dialogue.is_playing():
|
|
|
|
|
if not wipe.is_playing() and not self.is_playing(self.start) and \
|
|
|
|
|
not self.text_index == 2:
|
|
|
|
|
self.advance_prompt.update()
|
|
|
|
|
if not self.text_index == 2:
|
|
|
|
|
self.skip_prompt.update()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SkipPrompt(Sprite):
|
|
|
|
|
|
|
|
|
|
def __init__(self, parent, callback):
|
|
|
|
|
Sprite.__init__(self, parent)
|
|
|
|
|
self.callback = callback
|
|
|
|
|
for ii in xrange(3):
|
|
|
|
|
self.load_from_path(self.get_resource("Skip_%i.png" % ii), True)
|
|
|
|
|
self.add_frameset([ii])
|
|
|
|
|
|
|
|
|
|
def reset(self):
|
|
|
|
|
self.press_index = 0
|
|
|
|
|
self.press_elapsed = 0
|
|
|
|
|
self.set_frameset(1)
|
|
|
|
|
|
|
|
|
|
def update(self):
|
|
|
|
|
platform = self.get_game().platform
|
|
|
|
|
if self.press_index == 0 and platform.get_edge_pressed() == NS.S:
|
|
|
|
|
self.press_index += 1
|
|
|
|
|
self.set_frameset(2)
|
|
|
|
|
elif self.press_index == 1 and platform.get_edge_pressed() == NS.NE:
|
|
|
|
|
self.press_index += 1
|
|
|
|
|
self.set_frameset(3)
|
|
|
|
|
elif self.press_index == 2 and platform.get_edge_pressed() == NS.W:
|
|
|
|
|
self.callback()
|
|
|
|
|
elif self.press_index > 0:
|
|
|
|
|
self.press_elapsed += self.get_game().time_filter.get_last_frame_duration()
|
|
|
|
|
if self.press_elapsed > 4000:
|
|
|
|
|
self.reset()
|
|
|
|
|
Sprite.update(self)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AdvancePrompt(Sprite):
|
|
|
|
|
|
|
|
|
|
def __init__(self, parent):
|
|
|
|
|
Sprite.__init__(self, parent)
|
|
|
|
|
self.load_from_path(self.get_resource("Dialogue_buttons_full.png"), True,
|
|
|
|
|
False, (255, 255, 255))
|
|
|
|
|
self.load_from_path(self.get_resource("Dialogue_buttons_half.png"), True,
|
|
|
|
|
False, (255, 255, 255))
|
|
|
|
|
self.add_frameset([0], name="full", switch=True)
|
|
|
|
|
self.add_frameset([1], name="half")
|
|
|
|
|
dsr = self.get_display_surface().get_rect()
|
|
|
|
|
self.location.bottomright = dsr.right - 3, dsr.bottom - 3
|
|
|
|
|
|
|
|
|
|
def reset(self):
|
|
|
|
|
self.cancel_first_press()
|
|
|
|
|
|
|
|
|
|
def cancel_first_press(self):
|
|
|
|
|
self.first_pressed = False
|
|
|
|
|
self.first_pressed_elapsed = 0
|
|
|
|
|
self.set_frameset("full")
|
|
|
|
|
|
|
|
|
|
def check_first_press(self):
|
|
|
|
|
return not self.first_pressed and self.get_game().platform.get_edge_pressed() == NS.N
|
|
|
|
|
|
|
|
|
|
def press_first(self):
|
|
|
|
|
self.first_pressed = True
|
|
|
|
|
self.set_frameset("half")
|
|
|
|
|
|
|
|
|
|
def check_second_press(self):
|
|
|
|
|
return self.first_pressed and self.get_game().platform.get_edge_pressed() == NS.NW
|
|
|
|
|
|
|
|
|
|
def update(self):
|
|
|
|
|
if self.first_pressed:
|
|
|
|
|
self.first_pressed_elapsed += self.get_game().time_filter.get_last_frame_duration()
|
|
|
|
|
if self.first_pressed_elapsed > 4000:
|
|
|
|
|
self.cancel_first_press()
|
|
|
|
|
Sprite.update(self)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Wipe(Animation):
|
|
|
|
@ -459,14 +585,17 @@ class Platform(GameChild):
|
|
|
|
|
def __init__(self, parent):
|
|
|
|
|
GameChild.__init__(self, parent)
|
|
|
|
|
self.lights = [
|
|
|
|
|
Light(self, "cyan", NS.NW),
|
|
|
|
|
Light(self, "magenta", NS.NE),
|
|
|
|
|
Light(self, "yellow", NS.SE),
|
|
|
|
|
Light(self, "white", NS.SW)
|
|
|
|
|
Light(self, "cyan", NS.LNW),
|
|
|
|
|
Light(self, "magenta", NS.LNE),
|
|
|
|
|
Light(self, "yellow", NS.LSE),
|
|
|
|
|
Light(self, "white", NS.LSW)
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
def reset(self):
|
|
|
|
|
self.deactivate()
|
|
|
|
|
self.reset_lights()
|
|
|
|
|
|
|
|
|
|
def reset_lights(self):
|
|
|
|
|
for light in self.lights:
|
|
|
|
|
light.reset()
|
|
|
|
|
|
|
|
|
@ -485,19 +614,43 @@ class Platform(GameChild):
|
|
|
|
|
|
|
|
|
|
def get_edge_pressed(self):
|
|
|
|
|
pressed = self.get_pressed()
|
|
|
|
|
if NS.NW in pressed and NS.NE in pressed:
|
|
|
|
|
if NS.LNW in pressed and NS.LNE in pressed:
|
|
|
|
|
return NS.N
|
|
|
|
|
elif NS.NE in pressed and NS.SW in pressed:
|
|
|
|
|
elif NS.LNE in pressed and NS.LSW in pressed:
|
|
|
|
|
return NS.NE
|
|
|
|
|
elif NS.NE in pressed and NS.SE in pressed:
|
|
|
|
|
elif NS.LNE in pressed and NS.LSE in pressed:
|
|
|
|
|
return NS.E
|
|
|
|
|
elif NS.NW in pressed and NS.SE in pressed:
|
|
|
|
|
elif NS.LNW in pressed and NS.LSE in pressed:
|
|
|
|
|
return NS.NW
|
|
|
|
|
elif NS.SE in pressed and NS.SW in pressed:
|
|
|
|
|
elif NS.LSE in pressed and NS.LSW in pressed:
|
|
|
|
|
return NS.S
|
|
|
|
|
elif NS.SW in pressed and NS.NW in pressed:
|
|
|
|
|
elif NS.LSW in pressed and NS.LNW in pressed:
|
|
|
|
|
return NS.W
|
|
|
|
|
|
|
|
|
|
def get_buttons_from_edges(self, edges):
|
|
|
|
|
buttons = set()
|
|
|
|
|
for edge in edges:
|
|
|
|
|
if edge == NS.N:
|
|
|
|
|
buttons = buttons.union((NS.LNW, NS.LNE))
|
|
|
|
|
elif edge == NS.NE:
|
|
|
|
|
buttons = buttons.union((NS.LNE, NS.LSW))
|
|
|
|
|
elif edge == NS.E:
|
|
|
|
|
buttons = buttons.union((NS.LNE, NS.LSE))
|
|
|
|
|
elif edge == NS.NW:
|
|
|
|
|
buttons = buttons.union((NS.LNW, NS.LSE))
|
|
|
|
|
elif edge == NS.S:
|
|
|
|
|
buttons = buttons.union((NS.LSE, NS.LSW))
|
|
|
|
|
elif edge == NS.W:
|
|
|
|
|
buttons = buttons.union((NS.LSW, NS.LNW))
|
|
|
|
|
return list(buttons)
|
|
|
|
|
|
|
|
|
|
def set_glowing(self, selected):
|
|
|
|
|
for ii, light in enumerate(self.lights):
|
|
|
|
|
light.glow_index = 0
|
|
|
|
|
light.halt(light.glow)
|
|
|
|
|
if ii in selected:
|
|
|
|
|
light.play(light.glow)
|
|
|
|
|
|
|
|
|
|
def update(self):
|
|
|
|
|
if self.active:
|
|
|
|
|
for light in self.lights:
|
|
|
|
@ -507,9 +660,13 @@ class Platform(GameChild):
|
|
|
|
|
|
|
|
|
|
class Light(Animation):
|
|
|
|
|
|
|
|
|
|
MAX_GLOW_INDEX = 16
|
|
|
|
|
INTRODUCTION_OFFSET = 80
|
|
|
|
|
|
|
|
|
|
def __init__(self, parent, color, position):
|
|
|
|
|
Animation.__init__(self, parent)
|
|
|
|
|
self.color = Color(color)
|
|
|
|
|
self.color.a = 225
|
|
|
|
|
self.position = position
|
|
|
|
|
self.pressed = False
|
|
|
|
|
ds = self.get_display_surface()
|
|
|
|
@ -524,45 +681,67 @@ class Light(Animation):
|
|
|
|
|
backright = ds.get_width() / 2 + NS.BACK_WIDTH / 2, NS.FRONT + NS.LENGTH
|
|
|
|
|
right_step = get_step_relative(frontright, backright, NS.STEP)
|
|
|
|
|
midright = frontright[0] + right_step[0], frontright[1] + right_step[1]
|
|
|
|
|
if self.position == NS.NW:
|
|
|
|
|
if self.position == NS.LNW:
|
|
|
|
|
self.points = frontleft, frontmid, mid, midleft
|
|
|
|
|
elif self.position == NS.NE:
|
|
|
|
|
elif self.position == NS.LNE:
|
|
|
|
|
self.points = frontmid, frontright, midright, mid
|
|
|
|
|
elif self.position == NS.SE:
|
|
|
|
|
elif self.position == NS.LSE:
|
|
|
|
|
self.points = mid, midright, backright, backmid
|
|
|
|
|
elif self.position == NS.SW:
|
|
|
|
|
elif self.position == NS.LSW:
|
|
|
|
|
self.points = midleft, mid, backmid, backleft
|
|
|
|
|
self.register(self.blink, interval=300)
|
|
|
|
|
self.register(self.glow)
|
|
|
|
|
|
|
|
|
|
def reset(self):
|
|
|
|
|
self.hidden = False
|
|
|
|
|
self.halt(self.blink)
|
|
|
|
|
self.halt(self.glow)
|
|
|
|
|
self.reset_timer()
|
|
|
|
|
self.glow_index = 0
|
|
|
|
|
|
|
|
|
|
def blink(self):
|
|
|
|
|
self.hidden = not self.hidden
|
|
|
|
|
|
|
|
|
|
def glow(self):
|
|
|
|
|
self.glow_index += 1
|
|
|
|
|
if self.glow_index > self.MAX_GLOW_INDEX:
|
|
|
|
|
self.glow_index = 0
|
|
|
|
|
|
|
|
|
|
def update(self):
|
|
|
|
|
Animation.update(self)
|
|
|
|
|
boss = self.get_game().boss
|
|
|
|
|
chemtrails = self.get_game().chemtrails
|
|
|
|
|
if boss.queue and boss.brandish_complete and not self.is_playing(self.blink) \
|
|
|
|
|
and self.in_orientation(boss.queue[chemtrails.queue_index]):
|
|
|
|
|
self.play(self.blink)
|
|
|
|
|
elif self.is_playing(self.blink) and (not boss.queue or
|
|
|
|
|
not self.in_orientation(boss.queue[chemtrails.queue_index])):
|
|
|
|
|
self.reset()
|
|
|
|
|
if not self.get_game().introduction.active:
|
|
|
|
|
boss = self.get_game().boss
|
|
|
|
|
chemtrails = self.get_game().chemtrails
|
|
|
|
|
if boss.queue and boss.brandish_complete and not self.is_playing(self.blink) \
|
|
|
|
|
and self.in_orientation(boss.queue[chemtrails.queue_index]):
|
|
|
|
|
self.play(self.blink)
|
|
|
|
|
elif self.is_playing(self.blink) and (not boss.queue or
|
|
|
|
|
not self.in_orientation(boss.queue[chemtrails.queue_index])):
|
|
|
|
|
self.reset()
|
|
|
|
|
points = self.points
|
|
|
|
|
else:
|
|
|
|
|
points = []
|
|
|
|
|
for point in self.points:
|
|
|
|
|
points.append((point[0], point[1] - self.INTRODUCTION_OFFSET))
|
|
|
|
|
if not self.hidden:
|
|
|
|
|
aa_filled_polygon(self.get_display_surface(), self.points, self.color)
|
|
|
|
|
ds = self.get_display_surface()
|
|
|
|
|
aa_filled_polygon(ds, points, self.color)
|
|
|
|
|
for ii in reversed(xrange(self.glow_index)):
|
|
|
|
|
shifted = []
|
|
|
|
|
for point in points:
|
|
|
|
|
shifted.append((point[0], point[1] - 1 * (ii + 1)))
|
|
|
|
|
alpha = (1 - float(ii + 1) / (self.MAX_GLOW_INDEX + 1)) * 255
|
|
|
|
|
color = Color(self.color.r, self.color.g, self.color.b, int(alpha))
|
|
|
|
|
aapolygon(ds, shifted, color)
|
|
|
|
|
|
|
|
|
|
def in_orientation(self, orientation):
|
|
|
|
|
if self.position == NS.NW:
|
|
|
|
|
if self.position == NS.LNW:
|
|
|
|
|
return orientation in (NS.N, NS.NW, NS.W)
|
|
|
|
|
elif self.position == NS.NE:
|
|
|
|
|
elif self.position == NS.LNE:
|
|
|
|
|
return orientation in (NS.N, NS.NE, NS.E)
|
|
|
|
|
elif self.position == NS.SE:
|
|
|
|
|
elif self.position == NS.LSE:
|
|
|
|
|
return orientation in (NS.NW, NS.E, NS.S)
|
|
|
|
|
elif self.position == NS.SW:
|
|
|
|
|
elif self.position == NS.LSW:
|
|
|
|
|
return orientation in (NS.S, NS.NE, NS.W)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -594,21 +773,22 @@ class Chemtrails(GameChild):
|
|
|
|
|
def update(self):
|
|
|
|
|
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()
|
|
|
|
|
if not self.get_game().introduction.active:
|
|
|
|
|
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
|
|
|
|
@ -620,43 +800,49 @@ class Chemtrails(GameChild):
|
|
|
|
|
if self.queue_index == len(queue):
|
|
|
|
|
self.timer_remaining = self.TIME_LIMIT
|
|
|
|
|
self.get_game().boss.combo()
|
|
|
|
|
self.get_game().platform.reset()
|
|
|
|
|
self.get_game().platform.reset_lights()
|
|
|
|
|
|
|
|
|
|
def orient(self):
|
|
|
|
|
ds = self.get_display_surface()
|
|
|
|
|
edge = self.get_game().platform.get_edge_pressed()
|
|
|
|
|
dy = -Light.INTRODUCTION_OFFSET if self.get_game().introduction.active else 0
|
|
|
|
|
if edge == NS.N:
|
|
|
|
|
rect = self.image.get_rect()
|
|
|
|
|
rect.center = ds.get_width() / 2, NS.FRONT - 30
|
|
|
|
|
rect.center = ds.get_width() / 2, NS.FRONT - 30 + dy
|
|
|
|
|
ds.blit(self.image, rect.topleft)
|
|
|
|
|
self.orientation = NS.N
|
|
|
|
|
elif edge == NS.E:
|
|
|
|
|
image = rotate(self.image, 270)
|
|
|
|
|
rect = image.get_rect()
|
|
|
|
|
rect.center = ds.get_width() / 2 + NS.FRONT_WIDTH / 2, NS.FRONT + NS.LENGTH * NS.STEP + 10
|
|
|
|
|
rect.center = ds.get_width() / 2 + NS.FRONT_WIDTH / 2, \
|
|
|
|
|
NS.FRONT + NS.LENGTH * NS.STEP + 10 + dy
|
|
|
|
|
ds.blit(image, rect.topleft)
|
|
|
|
|
self.orientation = NS.E
|
|
|
|
|
elif edge == NS.S:
|
|
|
|
|
rect = self.image.get_rect()
|
|
|
|
|
rect.center = ds.get_width() / 2, NS.FRONT + NS.LENGTH - NS.LENGTH * NS.STEP - 20
|
|
|
|
|
rect.center = ds.get_width() / 2, \
|
|
|
|
|
NS.FRONT + NS.LENGTH - NS.LENGTH * NS.STEP - 20 + dy
|
|
|
|
|
ds.blit(self.image, rect.topleft)
|
|
|
|
|
self.orientation = NS.S
|
|
|
|
|
elif edge == NS.W:
|
|
|
|
|
image = rotate(self.image, 270)
|
|
|
|
|
rect = image.get_rect()
|
|
|
|
|
rect.center = ds.get_width() / 2 - NS.FRONT_WIDTH / 2 + 70, NS.FRONT + NS.LENGTH * NS.STEP + 10
|
|
|
|
|
rect.center = ds.get_width() / 2 - NS.FRONT_WIDTH / 2 + 70, \
|
|
|
|
|
NS.FRONT + NS.LENGTH * NS.STEP + 10 + dy
|
|
|
|
|
ds.blit(image, rect.topleft)
|
|
|
|
|
self.orientation = NS.W
|
|
|
|
|
elif edge == NS.NW:
|
|
|
|
|
image = rotate(self.image, 315)
|
|
|
|
|
rect = image.get_rect()
|
|
|
|
|
rect.center = ds.get_width() / 2 + 45, NS.FRONT + NS.LENGTH * NS.STEP - 40
|
|
|
|
|
rect.center = ds.get_width() / 2 + 45, \
|
|
|
|
|
NS.FRONT + NS.LENGTH * NS.STEP - 40 + dy
|
|
|
|
|
ds.blit(image, rect.topleft)
|
|
|
|
|
self.orientation = NS.NW
|
|
|
|
|
elif edge == NS.NE:
|
|
|
|
|
image = rotate(self.image, 45)
|
|
|
|
|
rect = image.get_rect()
|
|
|
|
|
rect.center = ds.get_width() / 2 - 30, NS.FRONT + NS.LENGTH * NS.STEP - 50
|
|
|
|
|
rect.center = ds.get_width() / 2 - 30, \
|
|
|
|
|
NS.FRONT + NS.LENGTH * NS.STEP - 50 + dy
|
|
|
|
|
ds.blit(image, rect.topleft)
|
|
|
|
|
self.orientation = NS.NE
|
|
|
|
|
else:
|
|
|
|
@ -695,15 +881,33 @@ class Life(GameChild):
|
|
|
|
|
class Boss(RainbowSprite):
|
|
|
|
|
|
|
|
|
|
def __init__(self, parent):
|
|
|
|
|
RainbowSprite.__init__(self, parent, load("resource/Koolaid.png").convert_alpha(), 30)
|
|
|
|
|
RainbowSprite.__init__(self, parent, load("resource/Kool_man.png").convert_alpha(), 30)
|
|
|
|
|
self.health = Health(self)
|
|
|
|
|
self.sword = Sword(self)
|
|
|
|
|
self.register(self.brandish, self.cancel_flash)
|
|
|
|
|
self.register(self.brandish, self.cancel_flash, self.show_dialogue)
|
|
|
|
|
self.add_frameset([0], name="normal")
|
|
|
|
|
self.kool_man_avatar = load(self.get_resource("resource/Kool_man_avatar.png")).convert()
|
|
|
|
|
self.advance_prompt = AdvancePrompt(self)
|
|
|
|
|
|
|
|
|
|
def cancel_flash(self):
|
|
|
|
|
self.set_frameset("normal")
|
|
|
|
|
|
|
|
|
|
def start_level(self):
|
|
|
|
|
self.activate()
|
|
|
|
|
dialogue = self.get_game().dialogue
|
|
|
|
|
dialogue.deactivate()
|
|
|
|
|
dialogue.set_avatar(self.kool_man_avatar)
|
|
|
|
|
dialogue.set_name("Kool Man")
|
|
|
|
|
self.play(self.show_dialogue, delay=3000, play_once=True)
|
|
|
|
|
self.get_game().platform.activate()
|
|
|
|
|
self.get_game().chemtrails.activate()
|
|
|
|
|
|
|
|
|
|
def show_dialogue(self):
|
|
|
|
|
dialogue = self.get_game().dialogue
|
|
|
|
|
dialogue.activate()
|
|
|
|
|
dialogue.show_text("You'll never be able to block my sword, you lizard slime!" +
|
|
|
|
|
" See if you\ncan keep up with these moves!")
|
|
|
|
|
|
|
|
|
|
def reset(self):
|
|
|
|
|
self.deactivate()
|
|
|
|
|
self.unhide()
|
|
|
|
@ -712,7 +916,8 @@ class Boss(RainbowSprite):
|
|
|
|
|
self.health.reset()
|
|
|
|
|
self.halt(self.brandish)
|
|
|
|
|
self.sword.reset()
|
|
|
|
|
self.combo()
|
|
|
|
|
self.advance_prompt.reset()
|
|
|
|
|
# self.combo()
|
|
|
|
|
self.queue = None
|
|
|
|
|
self.brandish_complete = True
|
|
|
|
|
|
|
|
|
@ -750,11 +955,29 @@ class Boss(RainbowSprite):
|
|
|
|
|
|
|
|
|
|
def update(self):
|
|
|
|
|
if self.active:
|
|
|
|
|
self.get_display_surface().fill((0, 0, 0))
|
|
|
|
|
dialogue = self.get_game().dialogue
|
|
|
|
|
if dialogue.active:
|
|
|
|
|
if self.advance_prompt.check_first_press():
|
|
|
|
|
self.advance_prompt.press_first()
|
|
|
|
|
elif self.advance_prompt.check_second_press():
|
|
|
|
|
if dialogue.is_playing():
|
|
|
|
|
dialogue.show_all()
|
|
|
|
|
else:
|
|
|
|
|
self.get_game().dialogue.deactivate()
|
|
|
|
|
self.combo()
|
|
|
|
|
RainbowSprite.update(self)
|
|
|
|
|
# self.get_display_surface().blit(self.image, (0, 0))
|
|
|
|
|
self.sword.update()
|
|
|
|
|
self.health.update()
|
|
|
|
|
|
|
|
|
|
def update_dialogue(self):
|
|
|
|
|
if self.active:
|
|
|
|
|
dialogue = self.get_game().dialogue
|
|
|
|
|
if dialogue.active:
|
|
|
|
|
self.get_game().dialogue.update()
|
|
|
|
|
self.advance_prompt.update()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Sword(Sprite):
|
|
|
|
|
|
|
|
|
|