add logo and tony glow effects to toggleable effects

This commit is contained in:
ohsqueezy 2022-11-02 19:21:24 -04:00
parent a94dfbedcf
commit 57168817b9
2 changed files with 73 additions and 35 deletions

106
NS.py
View File

@ -536,13 +536,7 @@ class LevelSelect(Animation):
text_rect.midleft = preview_rect.midleft text_rect.midleft = preview_rect.midleft
frame = self.get_game().boss.backgrounds[level_index].frames[0] frame = self.get_game().boss.backgrounds[level_index].frames[0]
frame_rect = (preview_rect.w - text_rect.w - padding, preview_rect.h - padding * 2) frame_rect = (preview_rect.w - text_rect.w - padding, preview_rect.h - padding * 2)
environment = pygame.transform.smoothscale(frame, frame_rect)
# Smooth scaling is not available on some platforms, so fallback to regular scale
try:
environment = pygame.transform.smoothscale(frame, frame_rect)
except ValueError:
environment = pygame.transform.scale(frame, frame_rect)
environment_rect = environment.get_rect() environment_rect = environment.get_rect()
environment_rect.midright = preview_rect.right - padding, preview_rect.centery environment_rect.midright = preview_rect.right - padding, preview_rect.centery
boss = pygame.transform.smoothscale(self.get_game().boss.level_sprite(level_index).frames[0], boss = pygame.transform.smoothscale(self.get_game().boss.level_sprite(level_index).frames[0],
@ -777,14 +771,23 @@ class Meter(GameChild):
class Tony(Sprite): class Tony(Sprite):
"""
A fullscreen-sized sprite of Tony Hawk the Birdman with animation and glow effects.
"""
def __init__(self, parent): def __init__(self, parent):
"""
Load board animation, create a glow effect, and load taunt sound effects.
"""
Sprite.__init__(self, parent, 100, False) Sprite.__init__(self, parent, 100, False)
dsr = self.get_display_surface().get_rect()
self.board = Sprite(self, 100) self.board = Sprite(self, 100)
self.board.load_from_path(self.get_resource("newTony/TonyArms"), True) self.board.load_from_path(self.get_resource("newTony/TonyArms"), True)
self.effect = Sprite(self)
dsr = self.get_display_surface().get_rect() # Create a glowing effect object by adding glow frames to a blank Sprite. It can then be applied to the main Tony Sprite frame
if self.get_configuration("display", "effects"): # using `pygame.BLEND_RGBA_SUB`. Skip this if fast load is requested.
if not self.get_configuration("system", "minimize-load-time"):
self.effect = Sprite(self)
for offset in range(12): for offset in range(12):
w, h = dsr.w + 40, int(dsr.h * .65) w, h = dsr.w + 40, int(dsr.h * .65)
glow = Surface((w, h), SRCALPHA) glow = Surface((w, h), SRCALPHA)
@ -797,7 +800,8 @@ class Tony(Sprite):
ellipse(glow, w // 2, y, w // 2 - 4, h // 20, color) ellipse(glow, w // 2, y, w // 2 - 4, h // 20, color)
filled_ellipse(glow, w // 2, y, w // 2 - 4, h // 20, color) filled_ellipse(glow, w // 2, y, w // 2 - 4, h // 20, color)
self.effect.add_frame(glow) self.effect.add_frame(glow)
self.effect.location.topleft = -20, int(dsr.h * .35) self.effect.location.topleft = -20, int(dsr.h * .35)
self.add_frame(load(self.get_resource("Big_Tony.png")).convert_alpha()) self.add_frame(load(self.get_resource("Big_Tony.png")).convert_alpha())
self.load_from_path(self.get_resource("newTony/TonyShirtHead"), True) self.load_from_path(self.get_resource("newTony/TonyShirtHead"), True)
self.add_frameset([0], name="static") self.add_frameset([0], name="static")
@ -828,21 +832,36 @@ class Tony(Sprite):
self.get_audio().play_sfx(choice(self.taunts)) self.get_audio().play_sfx(choice(self.taunts))
def update(self): def update(self):
save = self.get_display_surface() """
intermediate_surface = Surface(self.location.size, SRCALPHA) Apply the glow effect using an intermediate surface to blend the glow effect with the current main sprite frame. Skip the effect if
self.display_surface = intermediate_surface effects are off. Update title screen objects. Update the board sub-animation if it is active.
location_save = self.location.copy() """
self.location.topleft = 0, 0 # Create an intermediate surface for blending the glow with the sprite frame
if self.get_configuration("display", "effects"):
save = self.get_display_surface()
intermediate_surface = Surface(self.location.size, SRCALPHA)
self.display_surface = intermediate_surface
location_save = self.location.copy()
self.location.topleft = 0, 0
# Do a regular Sprite animation update
Sprite.update(self) Sprite.update(self)
self.display_surface = save
self.location = location_save # Blend the effect frame with the sprite frame
self.effect.display_surface = intermediate_surface if self.get_configuration("display", "effects"):
self.effect.update(flags=BLEND_RGBA_SUB) self.display_surface = save
self.get_display_surface().blit(intermediate_surface, self.location.topleft) 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)
# Update title screen objects that are drawn over this sprite
if self.get_game().title.active: if self.get_game().title.active:
self.get_game().title.video.update() self.get_game().title.video.update()
self.get_game().platform.update() self.get_game().platform.update()
self.get_game().chemtrails.update() self.get_game().chemtrails.update()
# Update the board sub-animation
frameset = self.get_current_frameset() frameset = self.get_current_frameset()
if frameset.name == "board": if frameset.name == "board":
self.board.get_current_frameset().current_index = frameset.current_index self.board.get_current_frameset().current_index = frameset.current_index
@ -905,8 +924,15 @@ class Video(Sprite):
class Logo(Sprite): class Logo(Sprite):
"""
A screen-sized layer that is itself two layers, displaying the logo, scrolling infinitely, with a glowing effect.
"""
def __init__(self, parent): def __init__(self, parent):
"""
Load the logo and add locations at regular offsets until the screen is covered to create a tile fill effect. Create a second
Sprite that will display a glow effect that can be blended into the main layer.
"""
Sprite.__init__(self, parent) Sprite.__init__(self, parent)
dsr = self.get_display_surface().get_rect() dsr = self.get_display_surface().get_rect()
self.load_from_path(self.get_resource("Title_tile.png"), True) self.load_from_path(self.get_resource("Title_tile.png"), True)
@ -914,24 +940,36 @@ class Logo(Sprite):
for x in range(0, dsr.w + self.location.w, self.location.w): for x in range(0, dsr.w + self.location.w, self.location.w):
if x != 0 or y != 0: if x != 0 or y != 0:
self.add_location((x, y)) self.add_location((x, y))
self.effect = Sprite(self, 100)
palette = (255, 255, 255), (255, 255, 128), (255, 255, 0) # Create a screen sized Sprite to create a glowing animation drawn onto blank frames
thickness = 8 if self.get_configuration("display", "effects"):
for offset in range(len(palette)): self.effect = Sprite(self, 100)
frame = Surface(dsr.size) palette = (255, 255, 255), (255, 255, 128), (255, 255, 0)
for x in range(0, dsr.w, thickness): thickness = 8
frame.fill(palette[(offset + x) % len(palette)], (x, 0, thickness, dsr.h)) for offset in range(len(palette)):
self.effect.add_frame(frame) frame = Surface(dsr.size)
for x in range(0, dsr.w, thickness):
frame.fill(palette[(offset + x) % len(palette)], (x, 0, thickness, dsr.h))
self.effect.add_frame(frame)
def update(self): def update(self):
self.effect.update() """
# tiled background Scroll the tiles, wrapping at the edges of the screen. Draw the effect layer beneath the logo tile and blend with the logo
if effects are on.
"""
# Wrap around motion effect
self.move(-2, 2) self.move(-2, 2)
if self.location.right < 0: if self.location.right < 0:
self.move(self.location.w) self.move(self.location.w)
if self.location.top > 0: if self.location.top > 0:
self.move(dy=-self.location.h) self.move(dy=-self.location.h)
Sprite.update(self, flags=BLEND_RGBA_MIN)
# Blend with the effect layer if effects are on
if self.get_configuration("display", "effects"):
self.effect.update()
Sprite.update(self, flags=BLEND_RGBA_MIN)
else:
Sprite.update(self)
class Title(Animation): class Title(Animation):
@ -2765,8 +2803,8 @@ class Sword(Animation):
self.swords.append([[], [], [], [], [], []]) self.swords.append([[], [], [], [], [], []])
self.spinning_swords.append([[], [], [], [], [], []]) self.spinning_swords.append([[], [], [], [], [], []])
base_image_paths = sorted(iglob(join(self.get_resource(root), "*.png"))) base_image_paths = sorted(iglob(join(self.get_resource(root), "*.png")))
# If effects are turned off, use a single frame # If fast load is requested, use a single frame
if not self.get_configuration("display", "effects"): if not self.get_configuration("system", "minimize-load-time"):
base_image_paths = [base_image_paths[0]] base_image_paths = [base_image_paths[0]]
# Create a square surface that can be used to blit the rotated sword centered so each frame is the same size # Create a square surface that can be used to blit the rotated sword centered so each frame is the same size
size = max(*load(self.get_resource(base_image_paths[0])).get_size()) size = max(*load(self.get_resource(base_image_paths[0])).get_size())

2
config
View File

@ -26,7 +26,7 @@ show-framerate = no
dimensions = 800, 450 dimensions = 800, 450
fullscreen = no fullscreen = no
attract-gif-alpha = 0.95 attract-gif-alpha = 0.95
effects = yes effects = True
[system] [system]
# will force set display->effects to off # will force set display->effects to off