pre-render platform glow, slightly optimize dialogue
This commit is contained in:
parent
0b3e09f807
commit
63a7ddf51f
168
NS.py
168
NS.py
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# This is the main file containing all the pygame code.
|
||||
|
||||
import argparse, pathlib, operator, subprocess, sys
|
||||
import argparse, pathlib, operator, subprocess, sys, os
|
||||
from random import randint, choice, random
|
||||
from math import pi
|
||||
from copy import copy
|
||||
|
@ -585,10 +585,10 @@ class LevelSelect(Animation):
|
|||
platform.view.frames[ii] = scaled
|
||||
platform.view.get_current_frameset().measure_rect()
|
||||
platform.view.update_location_size()
|
||||
for corner in platform.glow_masks:
|
||||
for ii, frame in enumerate(corner):
|
||||
scaled = pygame.transform.smoothscale(frame, (int(frame.get_width() * scale), int(frame.get_height() * scale)))
|
||||
corner[ii] = scaled
|
||||
# for corner in platform.glow_masks:
|
||||
# for ii, frame in enumerate(corner):
|
||||
# scaled = pygame.transform.smoothscale(frame, (int(frame.get_width() * scale), int(frame.get_height() * scale)))
|
||||
# corner[ii] = scaled
|
||||
self.platforms[0].view.location.left = dsr.left + indent
|
||||
self.platforms[1].view.location.centerx = dsr.centerx
|
||||
self.platforms[2].view.location.right = dsr.right - indent
|
||||
|
@ -929,14 +929,15 @@ class Tony(Sprite):
|
|||
Sprite.update(self)
|
||||
|
||||
# Blend the effect frame with the sprite frame
|
||||
if self.get_configuration("display", "alpha-effect-title"):
|
||||
self.display_surface = save
|
||||
self.location = location_save
|
||||
self.effect.display_surface = intermediate_surface
|
||||
self.effect.update(flags=BLEND_RGBA_SUB)
|
||||
self.get_display_surface().blit(intermediate_surface, self.location.topleft)
|
||||
else:
|
||||
self.effect.update(flags=BLEND_RGBA_SUB)
|
||||
if not self.get_configuration("system", "minimize-load-time"):
|
||||
if self.get_configuration("display", "alpha-effect-title"):
|
||||
self.display_surface = save
|
||||
self.location = location_save
|
||||
self.effect.display_surface = intermediate_surface
|
||||
self.effect.update(flags=BLEND_RGBA_SUB)
|
||||
self.get_display_surface().blit(intermediate_surface, self.location.topleft)
|
||||
else:
|
||||
self.effect.update(flags=BLEND_RGBA_SUB)
|
||||
|
||||
# Update title screen objects that are drawn over this sprite
|
||||
if self.get_game().title.active:
|
||||
|
@ -1165,9 +1166,9 @@ class Title(Animation):
|
|||
arrow.set_colorkey((255, 0, 255))
|
||||
arrow.fill((255, 0, 255))
|
||||
if screen_pos[0] == 0:
|
||||
points = 0, arrow.get_height() // 2, arrow.get_width(), 0, arrow.get_width(), arrow.get_height()
|
||||
points = 0, arrow.get_height() // 2, arrow.get_width() - 1, 0, arrow.get_width() - 1, arrow.get_height() - 1
|
||||
else:
|
||||
points = 0, 0, 0, arrow.get_height(), arrow.get_width(), arrow.get_height() // 2
|
||||
points = 0, 0, 0, arrow.get_height() - 1, arrow.get_width() - 1, arrow.get_height() // 2
|
||||
pygame.gfxdraw.filled_trigon(arrow, points[0], points[1], points[2], points[3], points[4], points[5], bg)
|
||||
pygame.gfxdraw.trigon(arrow, points[0], points[1], points[2], points[3], points[4], points[5], (0, 0, 0))
|
||||
self.score_indicator.add_frame(arrow)
|
||||
|
@ -1352,6 +1353,8 @@ class Dialogue(Animation):
|
|||
self.name_box.add_frame(frame)
|
||||
self.name_box.location.bottomleft = self.avatar_box.location.bottomright
|
||||
self.speech_channel = None
|
||||
self.base_message_frame = Surface((self.text_box.location.w - 10, 30 * 2))
|
||||
self.base_message_frame.fill(self.BACKGROUND)
|
||||
|
||||
def reset(self):
|
||||
self.stop_speech()
|
||||
|
@ -1410,13 +1413,13 @@ class Dialogue(Animation):
|
|||
font = pygame.font.Font(self.get_resource(self.FONT_PATH), self.FONT_SIZE)
|
||||
message = Sprite(self)
|
||||
lines = self.full_text[:self.text_index].split("\n")
|
||||
frame = Surface((self.text_box.location.w - 10, 30 * len(lines)), SRCALPHA)
|
||||
frame = self.base_message_frame.copy()
|
||||
for ii, line in enumerate(lines):
|
||||
surface = font.render(line, True, self.TEXT_COLOR).convert_alpha()
|
||||
surface = font.render(line, True, self.TEXT_COLOR, self.BACKGROUND).convert()
|
||||
frame.blit(surface, (0, 30 * ii))
|
||||
message.add_frame(frame)
|
||||
message.location.topleft = self.text_box.location.left + 9, self.text_box.location.top + 8
|
||||
message.update()
|
||||
message.add_frame(frame)
|
||||
message.location.topleft = self.text_box.location.left + 9, self.text_box.location.top + 8
|
||||
message.update()
|
||||
|
||||
|
||||
class SkipPrompt(GameChild):
|
||||
|
@ -1647,44 +1650,49 @@ class Platform(GameChild):
|
|||
def __init__(self, parent, center):
|
||||
"""
|
||||
Initialize four lights, one for each pad on the platform. Initialize a Sprite for the pad graphics with one
|
||||
frameset per six possible combinations of lights. Initialize masks for creating a glow effect on the pads.
|
||||
frameset per six possible combinations of lights.
|
||||
|
||||
@param parent PGFW game object that initialized this object
|
||||
@param center tuple that gives the (x, y) screen coordinates of this platform
|
||||
"""
|
||||
GameChild.__init__(self, parent)
|
||||
|
||||
# Create objects for tracking the individual pad lights
|
||||
self.lights = [
|
||||
Light(self, self.get_configuration("pads", "nw_color"), NS.LNW),
|
||||
Light(self, self.get_configuration("pads", "ne_color"), NS.LNE),
|
||||
Light(self, self.get_configuration("pads", "se_color"), NS.LSE),
|
||||
Light(self, self.get_configuration("pads", "sw_color"), NS.LSW)
|
||||
]
|
||||
|
||||
# Create a sprite which will display the pad
|
||||
self.view = Sprite(self)
|
||||
self.view.load_from_path("pad", True)
|
||||
self.view.load_from_path(os.path.join(self.get_resource("pad"), "pad_0.png"), True)
|
||||
self.view.add_frameset([0], name="neutral")
|
||||
self.view.add_frameset([1], name=str(NS.N))
|
||||
self.view.add_frameset([2], name=str(NS.E))
|
||||
self.view.add_frameset([3], name=str(NS.NW))
|
||||
self.view.add_frameset([4], name=str(NS.NE))
|
||||
self.view.add_frameset([5], name=str(NS.W))
|
||||
self.view.add_frameset([6], name=str(NS.S))
|
||||
self.view.location.center = center
|
||||
self.glow_masks = []
|
||||
base_images = load_frames(self.get_resource("pad_mask"), True)
|
||||
for image in base_images:
|
||||
self.glow_masks.append([image])
|
||||
for mask in self.glow_masks:
|
||||
|
||||
# For each of the six combinations of lights, create a glowing frameset
|
||||
light_masks = load_frames(self.get_resource("pad_mask"), True)
|
||||
for orientation_index, orientation in enumerate((NS.N, NS.E, NS.NW, NS.NE, NS.W, NS.S)):
|
||||
pad_base_frame = load_frames(os.path.join(self.get_resource("pad"), f"pad_{orientation_index + 1}.png"), True)[0]
|
||||
self.view.add_frame(pad_base_frame)
|
||||
frameset = [len(self.view.frames) - 1]
|
||||
intensity_resolution = 12
|
||||
for intensity in range(1, intensity_resolution):
|
||||
copy = mask[0].copy()
|
||||
pixels = pygame.PixelArray(copy)
|
||||
color = pygame.Color(0, 0, 0)
|
||||
h, s, l, a = color.hsla
|
||||
l = int(intensity / intensity_resolution * 100)
|
||||
color.hsla = h, s, l, a
|
||||
pixels.replace(pygame.Color(0, 0, 0), color)
|
||||
del pixels
|
||||
mask.append(copy)
|
||||
next_pad_frame = pad_base_frame.copy()
|
||||
for light_orientation in self.get_buttons_from_edges([orientation]):
|
||||
copy = light_masks[light_orientation].copy()
|
||||
pixels = pygame.PixelArray(copy)
|
||||
color = pygame.Color(0, 0, 0)
|
||||
h, s, l, a = color.hsla
|
||||
l = int(intensity / intensity_resolution * 100)
|
||||
color.hsla = h, s, l, a
|
||||
pixels.replace(pygame.Color(0, 0, 0), color)
|
||||
del pixels
|
||||
next_pad_frame.blit(copy, (0, 0), None, BLEND_RGBA_ADD)
|
||||
self.view.add_frame(next_pad_frame)
|
||||
frameset.append(len(self.view.frames) - 1)
|
||||
self.view.add_frameset(frameset, name=str(orientation))
|
||||
self.view.location.center = center
|
||||
|
||||
def reset(self):
|
||||
"""
|
||||
|
@ -1878,9 +1886,9 @@ class Platform(GameChild):
|
|||
"""
|
||||
for ii, light in enumerate(self.lights):
|
||||
light.glow_index = 0
|
||||
light.halt(light.glow)
|
||||
light.unglow()
|
||||
if ii in selected:
|
||||
light.play(light.glow)
|
||||
light.glow()
|
||||
|
||||
def update(self):
|
||||
"""
|
||||
|
@ -1897,11 +1905,6 @@ class Platform(GameChild):
|
|||
else:
|
||||
self.view.set_frameset(str(glowing))
|
||||
self.view.update()
|
||||
if not self.view.is_hidden() and not self.view.is_playing(self.view.wipe_out):
|
||||
for light in self.lights:
|
||||
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:
|
||||
|
@ -1914,11 +1917,10 @@ class Platform(GameChild):
|
|||
self.press_elapsed = 0
|
||||
|
||||
|
||||
class Light(Animation):
|
||||
class Light(GameChild):
|
||||
"""
|
||||
This class represents a pad on the platform. Typically there are four instances for a platform, one for each corner of the
|
||||
platform. Each light stores its color and position on the platform. This class contains methods for glowing the light and
|
||||
getting its properties.
|
||||
platform. Each light stores its color, position on the platform, and state of glowing.
|
||||
"""
|
||||
|
||||
TITLE_OFFSET = 0
|
||||
|
@ -1931,7 +1933,7 @@ class Light(Animation):
|
|||
@param color pygame color object
|
||||
@param position the light's position on the platform, one of NS.LNW, NS.LNE, NS.LSE, NS.LSW
|
||||
"""
|
||||
Animation.__init__(self, parent)
|
||||
GameChild.__init__(self, parent)
|
||||
self.color = Color(color)
|
||||
self.color.a = 225
|
||||
self.position = position
|
||||
|
@ -1956,39 +1958,46 @@ class Light(Animation):
|
|||
self.points = mid, midright, backright, backmid
|
||||
elif self.position == NS.LSW:
|
||||
self.points = midleft, mid, backmid, backleft
|
||||
self.register(self.glow)
|
||||
|
||||
def reset(self):
|
||||
"""
|
||||
Unhide, halt glow animation
|
||||
"""
|
||||
self.hidden = False
|
||||
self.halt(self.glow)
|
||||
self.reset_timer()
|
||||
self.glow_index = 0
|
||||
self.unglow()
|
||||
|
||||
def glow(self):
|
||||
"""
|
||||
Moves the glow animation forward a frame by incrementing an index
|
||||
Set the glow state to True
|
||||
"""
|
||||
self.glow_index += 1
|
||||
if self.glow_index >= len(self.parent.glow_masks[0]):
|
||||
self.glow_index = 0
|
||||
self.is_glowing = True
|
||||
|
||||
def unglow(self):
|
||||
"""
|
||||
Set the glow state to False
|
||||
"""
|
||||
self.is_glowing = False
|
||||
|
||||
def glowing(self):
|
||||
"""
|
||||
Returns True if this light is glowing, False otherwise
|
||||
|
||||
@return True | False
|
||||
"""
|
||||
return self.is_glowing
|
||||
|
||||
def update(self):
|
||||
"""
|
||||
Checks the attack state to determine whether to start or stop glowing
|
||||
"""
|
||||
Animation.update(self)
|
||||
if not self.get_game().title.active and not self.get_game().level_select.active:
|
||||
boss = self.get_game().boss
|
||||
chemtrails = self.get_game().chemtrails
|
||||
# checks the boss attack queue and chameleon queue index to see if the glow should be started now
|
||||
if boss.queue and not self.is_playing(self.glow) and self.in_orientation(boss.queue[chemtrails.queue_index]):
|
||||
self.play(self.glow)
|
||||
if boss.queue and self.in_orientation(boss.queue[chemtrails.queue_index]):
|
||||
self.glow()
|
||||
# turns off the glow
|
||||
elif self.is_playing(self.glow) and (not boss.queue or not self.in_orientation(boss.queue[chemtrails.queue_index])):
|
||||
self.reset()
|
||||
elif not boss.queue or not self.in_orientation(boss.queue[chemtrails.queue_index]):
|
||||
self.unglow()
|
||||
|
||||
def get_points(self):
|
||||
if self.get_game().title.active:
|
||||
|
@ -1999,21 +2008,6 @@ class Light(Animation):
|
|||
else:
|
||||
return self.points
|
||||
|
||||
def draw_glow(self):
|
||||
for ii, y in enumerate(range(0, self.glow_index, 3)):
|
||||
shifted = []
|
||||
for point in self.get_points():
|
||||
shifted.append((point[0], point[1] - y))
|
||||
if self.position == NS.LSW:
|
||||
saturation = 0
|
||||
else:
|
||||
saturation = int((self.color.hsla[1] + 80) % 100)
|
||||
if not ii % 2:
|
||||
lightness = 0
|
||||
else:
|
||||
lightness = 40
|
||||
lines(self.get_display_surface(), get_hsla_color(int(self.color.hsla[0]), saturation, lightness), True, shifted, 3)
|
||||
|
||||
def in_orientation(self, orientation):
|
||||
"""
|
||||
Returns True if this light is contained in the given edge
|
||||
|
@ -2030,14 +2024,6 @@ class Light(Animation):
|
|||
elif self.position == NS.LSW:
|
||||
return orientation in (NS.S, NS.NE, NS.W)
|
||||
|
||||
def glowing(self):
|
||||
"""
|
||||
Returns True if this light is glowing, False otherwise
|
||||
|
||||
@return True | False
|
||||
"""
|
||||
return self.is_playing(self.glow)
|
||||
|
||||
|
||||
class Chemtrails(Sprite):
|
||||
"""
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
41802 0
|
||||
41903 0
|
||||
42153 0
|
||||
47259 0
|
||||
48935 0
|
||||
50940 0
|
||||
51245 0
|
||||
|
|
Loading…
Reference in New Issue