|
|
|
@ -159,9 +159,15 @@ class NS(Game, Animation):
|
|
|
|
|
"time":
|
|
|
|
|
{
|
|
|
|
|
"int": ["timer-max-time", "timer-start-time", "timer-addition", "sword-delay", "attract-gif-length",
|
|
|
|
|
"attract-board-length", "attract-reset-countdown", "level-select-reset-countdown"],
|
|
|
|
|
"attract-board-length", "attract-reset-countdown", "level-select-reset-countdown",
|
|
|
|
|
"level-select-press-length"],
|
|
|
|
|
"float": "timer-warning-start"
|
|
|
|
|
},
|
|
|
|
|
"boss":
|
|
|
|
|
{
|
|
|
|
|
"float": ["damage-per-hit-level-1", "damage-per-hit-level-2", "damage-per-hit-level-3"],
|
|
|
|
|
"int": ["cooldown-level-1", "cooldown-level-2", "cooldown-level-3"]
|
|
|
|
|
},
|
|
|
|
|
"input":
|
|
|
|
|
{
|
|
|
|
|
"bool": "serial"
|
|
|
|
@ -511,6 +517,7 @@ class LevelSelect(Animation):
|
|
|
|
|
self.deactivate()
|
|
|
|
|
self.level_index_selected = None
|
|
|
|
|
self.zoom = 1.0
|
|
|
|
|
self.grow_sound_channel = None
|
|
|
|
|
for level_index in range(3):
|
|
|
|
|
self.platforms[level_index].view.unhide()
|
|
|
|
|
self.previews[level_index].unhide()
|
|
|
|
@ -547,7 +554,6 @@ class LevelSelect(Animation):
|
|
|
|
|
Launch an animation on a delay that will reset the game after the delay. If the countdown is already active, reset the
|
|
|
|
|
countdown.
|
|
|
|
|
"""
|
|
|
|
|
print("start")
|
|
|
|
|
self.halt(self.timeout)
|
|
|
|
|
self.play(self.timeout, delay=self.get_configuration("time", "level-select-reset-countdown"), play_once=True)
|
|
|
|
|
|
|
|
|
@ -555,19 +561,40 @@ class LevelSelect(Animation):
|
|
|
|
|
"""
|
|
|
|
|
Reset to the title screen
|
|
|
|
|
"""
|
|
|
|
|
print("timeout")
|
|
|
|
|
self.get_game().wipe.start(self.get_game().reset, leave_wipe_running=True)
|
|
|
|
|
|
|
|
|
|
def update(self):
|
|
|
|
|
if self.active:
|
|
|
|
|
Animation.update(self)
|
|
|
|
|
self.get_game().logo.update()
|
|
|
|
|
for ii, preview in enumerate(self.previews):
|
|
|
|
|
if ii != self.level_index_selected:
|
|
|
|
|
preview.update()
|
|
|
|
|
if self.level_index_selected is None:
|
|
|
|
|
for level_index, platform in enumerate(self.platforms):
|
|
|
|
|
if platform.get_glowing_edge() == self.get_game().platform.get_edge_pressed():
|
|
|
|
|
self.level_index_selected = level_index
|
|
|
|
|
break
|
|
|
|
|
if self.get_game().platform.press_elapsed > self.get_configuration("time", "level-select-press-length"):
|
|
|
|
|
# This will cause the level to launch
|
|
|
|
|
self.level_index_selected = level_index
|
|
|
|
|
if self.grow_sound_channel is not None:
|
|
|
|
|
self.grow_sound_channel.stop()
|
|
|
|
|
self.grow_sound_channel = None
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
if self.grow_sound_channel is None:
|
|
|
|
|
self.grow_sound_channel = self.get_audio().play_sfx("grow", -1, x=platform.view.location.centerx)
|
|
|
|
|
# Draw a growing ring around the currently pressed level
|
|
|
|
|
angle = self.get_game().platform.press_elapsed / self.get_configuration("time", "level-select-press-length") * 2 * pi
|
|
|
|
|
diameter = self.previews[level_index].location.height + 21
|
|
|
|
|
rect = pygame.Rect(0, 0, diameter, diameter)
|
|
|
|
|
rect.center = self.previews[level_index].location.center
|
|
|
|
|
offset = 0
|
|
|
|
|
while offset < .2:
|
|
|
|
|
if offset < angle:
|
|
|
|
|
pygame.draw.arc(self.get_display_surface(), (255, 255, 255), rect, offset, angle, 14)
|
|
|
|
|
offset += .01
|
|
|
|
|
if self.level_index_selected is not None:
|
|
|
|
|
# Launch the level
|
|
|
|
|
for level_index in range(3):
|
|
|
|
|
if level_index != self.level_index_selected:
|
|
|
|
|
self.platforms[level_index].view.play(self.platforms[level_index].view.wipe_out)
|
|
|
|
@ -577,9 +604,6 @@ class LevelSelect(Animation):
|
|
|
|
|
self.get_game().wipe.start(self.launch_selected_index)
|
|
|
|
|
for platform in self.platforms:
|
|
|
|
|
platform.update()
|
|
|
|
|
for ii, preview in enumerate(self.previews):
|
|
|
|
|
if ii != self.level_index_selected:
|
|
|
|
|
preview.update()
|
|
|
|
|
if self.level_index_selected is not None:
|
|
|
|
|
preview = self.previews[self.level_index_selected]
|
|
|
|
|
self.zoom += 0.1
|
|
|
|
@ -591,8 +615,10 @@ class LevelSelect(Animation):
|
|
|
|
|
self.get_display_surface().blit(frame, rect)
|
|
|
|
|
# If input in the player's platform detected reset the automatic game reset countdown
|
|
|
|
|
if self.get_game().platform.get_pressed():
|
|
|
|
|
print("reset")
|
|
|
|
|
self.start_timeout_countdown()
|
|
|
|
|
elif self.grow_sound_channel is not None:
|
|
|
|
|
self.grow_sound_channel.stop()
|
|
|
|
|
self.grow_sound_channel = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Button(Sprite):
|
|
|
|
@ -1287,8 +1313,8 @@ class Platform(GameChild):
|
|
|
|
|
"""
|
|
|
|
|
This class contains methods for manipulating and getting information about the platform the player is standing on,
|
|
|
|
|
both the real one and on-screen representation. It initializes four Light objects, one for each pad on the platform.
|
|
|
|
|
It can set lights to glowing, return the states of individual lights or pairs of lights, reset lights, and draw the
|
|
|
|
|
on-screen representation.
|
|
|
|
|
It can set lights to glowing, return the states of individual lights or pairs of lights, reset lights, draw the
|
|
|
|
|
on-screen representation, and track how long an edge has been continuously pressed.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def __init__(self, parent, center):
|
|
|
|
@ -1335,10 +1361,12 @@ class Platform(GameChild):
|
|
|
|
|
|
|
|
|
|
def reset(self):
|
|
|
|
|
"""
|
|
|
|
|
Deactivate this object and reset each light
|
|
|
|
|
Deactivate this object and reset each light. Reset press elapsed tracker.
|
|
|
|
|
"""
|
|
|
|
|
self.deactivate()
|
|
|
|
|
self.reset_lights()
|
|
|
|
|
self.previously_pressed_edge = None
|
|
|
|
|
self.press_elapsed = 0
|
|
|
|
|
|
|
|
|
|
def reset_lights(self):
|
|
|
|
|
for light in self.lights:
|
|
|
|
@ -1547,6 +1575,15 @@ class Platform(GameChild):
|
|
|
|
|
if light.glowing():
|
|
|
|
|
self.get_display_surface().blit(
|
|
|
|
|
self.glow_masks[light.position][light.glow_index], self.view.location, None, BLEND_RGBA_ADD)
|
|
|
|
|
# track how long an edge has been pressed
|
|
|
|
|
if self.get_edge_pressed() is not None:
|
|
|
|
|
if self.get_edge_pressed() != self.previously_pressed_edge:
|
|
|
|
|
self.previously_pressed_edge = self.get_edge_pressed()
|
|
|
|
|
else:
|
|
|
|
|
self.press_elapsed += self.get_game().time_filter.get_last_frame_duration()
|
|
|
|
|
else:
|
|
|
|
|
self.previously_pressed_edge = None
|
|
|
|
|
self.press_elapsed = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Light(Animation):
|
|
|
|
@ -1747,11 +1784,11 @@ class Chemtrails(Sprite):
|
|
|
|
|
if self.orientation == queue[self.queue_index]:
|
|
|
|
|
self.timer.add_time(self.get_configuration("time", "timer-addition"))
|
|
|
|
|
if boss.level_index == 0:
|
|
|
|
|
boss.health.decrease(4)
|
|
|
|
|
boss.health.decrease(self.get_configuration("boss", "damage-per-hit-level-1"))
|
|
|
|
|
elif boss.level_index == 1:
|
|
|
|
|
boss.health.decrease(3)
|
|
|
|
|
boss.health.decrease(self.get_configuration("boss", "damage-per-hit-level-2"))
|
|
|
|
|
elif boss.level_index == 2:
|
|
|
|
|
boss.health.decrease(2)
|
|
|
|
|
boss.health.decrease(self.get_configuration("boss", "damage-per-hit-level-3"))
|
|
|
|
|
self.queue_index += 1
|
|
|
|
|
boss.last_attack = self.orientation
|
|
|
|
|
boss.sword.block()
|
|
|
|
@ -2330,7 +2367,12 @@ class Boss(Animation):
|
|
|
|
|
def end_dialogue(self):
|
|
|
|
|
self.get_game().dialogue.deactivate()
|
|
|
|
|
if not self.battle_finished:
|
|
|
|
|
self.combo(delay=1300)
|
|
|
|
|
if self.level_index == 0:
|
|
|
|
|
self.combo(self.get_configuration("boss", "cooldown-level-1"))
|
|
|
|
|
elif self.level_index == 1:
|
|
|
|
|
self.combo(self.get_configuration("boss", "cooldown-level-2"))
|
|
|
|
|
elif self.level_index == 2:
|
|
|
|
|
self.combo(self.get_configuration("boss", "cooldown-level-3"))
|
|
|
|
|
else:
|
|
|
|
|
self.get_game().wipe.start(self.transition_after_battle)
|
|
|
|
|
|
|
|
|
|