blit scores once and set clip; apply existing clip to wipe; disable background logo effects

This commit is contained in:
ohsqueezy 2022-12-02 13:43:39 -05:00
parent 3deb552325
commit 0b3e09f807
4 changed files with 77 additions and 40 deletions

106
NS.py
View File

@ -302,13 +302,6 @@ class NS(Game, Animation):
self.level_select = LevelSelect(self) self.level_select = LevelSelect(self)
self.ending = Ending(self) self.ending = Ending(self)
self.last_press = get_ticks()
self.register(self.close_pop_up)
self.reset()
self.most_recent_score = None
self.pop_up_font = pygame.font.Font(self.get_resource(Dialogue.FONT_PATH), 12)
self.pop_up_text = ""
# Start the score list with all blank scores # Start the score list with all blank scores
self.scores = [] self.scores = []
blank_count = 25 blank_count = 25
@ -317,6 +310,7 @@ class NS(Game, Animation):
self.scores.append(NS.Score.blank_level(level_index)) self.scores.append(NS.Score.blank_level(level_index))
for _ in range(blank_count): for _ in range(blank_count):
self.scores.append(NS.Score.blank_full()) self.scores.append(NS.Score.blank_full())
self.most_recent_score = None
# Add existing scores to the list from file # Add existing scores to the list from file
with open(self.get_resource("scores"), "rt") as score_file: with open(self.get_resource("scores"), "rt") as score_file:
@ -327,6 +321,11 @@ class NS(Game, Animation):
# Draw the score sprites # Draw the score sprites
self.title.draw_scores() self.title.draw_scores()
self.last_press = get_ticks()
self.register(self.close_pop_up)
self.reset()
self.pop_up_font = pygame.font.Font(self.get_resource(Dialogue.FONT_PATH), 12)
self.pop_up_text = ""
clear() clear()
def pi_enabled(self): def pi_enabled(self):
@ -957,6 +956,9 @@ class Tony(Sprite):
class Video(Sprite): class Video(Sprite):
"""
Attract mode pop-up that rotates through GIFs.
"""
def __init__(self, parent, diameter, next_video_chance=.01): def __init__(self, parent, diameter, next_video_chance=.01):
Sprite.__init__(self, parent, 100) Sprite.__init__(self, parent, 100)
@ -1009,12 +1011,13 @@ 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. A screen-sized layer displaying the logo tile-filled. Hacked into displaying only a single frame for performance.
""" """
def __init__(self, parent): def __init__(self, parent):
""" """
Load the logo and create a glowing version by creating multiple frames, each with a glow effect blended onto it. Load the logo and create a glowing version by creating multiple frames, each with a glow effect blended onto it. But disable the
glow and create a static background frame as a hack.
""" """
Sprite.__init__(self, parent, 60) Sprite.__init__(self, parent, 60)
dsr = self.get_display_surface().get_rect() dsr = self.get_display_surface().get_rect()
@ -1030,18 +1033,16 @@ 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.background = pygame.surface.Surface(self.get_display_surface().get_size())
self.display_surface = self.background
Sprite.update(self)
self.display_surface = self.get_screen()
def update(self): def update(self):
""" """
Scroll the tiles, wrapping at the edges of the screen. Draw the background, disable parent update (performance hack)
""" """
# Wrap around motion effect self.get_display_surface().blit(self.background, (0, 0))
self.move(-2, 2)
if self.location.right < 0:
self.move(self.location.w)
if self.location.top > 0:
self.move(dy=-self.location.h)
Sprite.update(self)
class Title(Animation): class Title(Animation):
@ -1101,9 +1102,19 @@ class Title(Animation):
self.get_game().tony.set_frameset("static") self.get_game().tony.set_frameset("static")
self.get_audio().play_bgm("title") self.get_audio().play_bgm("title")
# Blit the scores
for sprite in self.score_sprites:
sprite.update()
# Optimize by setting a clip that excludes the area where the scores are drawn
self.get_display_surface().set_clip(
(self.score_sprites[0].location.right, 0, self.score_sprites[1].location.left - self.score_sprites[0].location.right,
self.get_display_surface().get_height()))
def deactivate(self): def deactivate(self):
self.active = False self.active = False
self.halt() self.halt()
self.get_display_surface().set_clip(None)
def start_game(self): def start_game(self):
""" """
@ -1147,13 +1158,24 @@ class Title(Animation):
score_surface = render_box(self.score_font, text, width=column.get_width(), background=bg) score_surface = render_box(self.score_font, text, width=column.get_width(), background=bg)
column.blit(score_surface, (0, screen_pos[1])) column.blit(score_surface, (0, screen_pos[1]))
# Create a blink effect for the most recent score # Create a blinking indicator for the most recent score
if score == self.get_game().most_recent_score: if score == self.get_game().most_recent_score:
self.score_blanker = BlinkingSprite(self, 500) self.score_indicator = BlinkingSprite(self, 500)
blank = pygame.surface.Surface(score_surface.get_size()) arrow = pygame.surface.Surface([score_surface.get_height()] * 2)
blank.fill(bg) arrow.set_colorkey((255, 0, 255))
self.score_blanker.add_frame(blank) arrow.fill((255, 0, 255))
self.score_blanker.location = screen_pos if screen_pos[0] == 0:
points = 0, arrow.get_height() // 2, arrow.get_width(), 0, arrow.get_width(), arrow.get_height()
else:
points = 0, 0, 0, arrow.get_height(), arrow.get_width(), 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)
self.score_indicator.location.top = screen_pos[1]
if screen_pos[0] == 0:
self.score_indicator.location.left = score_surface.get_width() + 5
else:
self.score_indicator.location.right = screen_pos[0] - 5
# The height is used to move the draw location # The height is used to move the draw location
return score_surface.get_height() return score_surface.get_height()
@ -1174,11 +1196,11 @@ class Title(Animation):
def draw_scores(self): def draw_scores(self):
""" """
Create two columns, one for each side of the screen. Draw as many scores as can fit along each column, in order from best to worst, separating Create two columns, one for each side of the screen. Draw as many scores as can fit along each column, in order from best to worst, separating
them evenly into categories: normal, advanced, and expert. Draw the two columns to the display surface, with the expectation that they will be them evenly into categories: normal, advanced, and expert. Save the columns as sprites. Note that this doesn't support non-level select mode
removed from the clip and will not be drawn over. Note that this doesn't support non-level select mode anymore. anymore.
""" """
ds = self.get_display_surface() ds = self.get_display_surface()
self.score_blanker = None self.score_indicator = None
heading_width, heading_height = self.heading_font.size("ADVANCED") heading_width, heading_height = self.heading_font.size("ADVANCED")
heading_width += 10 heading_width += 10
score_height = self.score_font.size("0")[1] score_height = self.score_font.size("0")[1]
@ -1226,8 +1248,6 @@ class Title(Animation):
right_column_sprite.add_frame(right_column) right_column_sprite.add_frame(right_column)
right_column_sprite.location.topleft = x, 0 right_column_sprite.location.topleft = x, 0
self.score_sprites = [left_column_sprite, right_column_sprite] self.score_sprites = [left_column_sprite, right_column_sprite]
for sprite in self.score_sprites:
sprite.update()
def show_video(self): def show_video(self):
self.video.unhide() self.video.unhide()
@ -1251,9 +1271,6 @@ class Title(Animation):
ds = self.get_display_surface() ds = self.get_display_surface()
dsr = ds.get_rect() dsr = ds.get_rect()
# Optimize by setting a clip that excludes the area where the scores are drawn
ds.set_clip((self.score_sprites[0].location.right, 0, self.score_sprites[1].location.left - self.score_sprites[0].location.right, dsr.height))
# Draw the background # Draw the background
self.get_game().logo.update() self.get_game().logo.update()
@ -1295,11 +1312,9 @@ class Title(Animation):
self.halt() self.halt()
self.play(self.show_video, delay=self.get_configuration("time", "attract-reset-countdown"), play_once=True) self.play(self.show_video, delay=self.get_configuration("time", "attract-reset-countdown"), play_once=True)
# Disable clip and draw blanker which creates a blinking affect for a single score # Indicate most recent score
ds.set_clip(None) if self.score_indicator is not None:
if self.score_blanker: self.score_indicator.update()
self.score_blanker.update()
class Dialogue(Animation): class Dialogue(Animation):
""" """
@ -1599,13 +1614,26 @@ class Wipe(Animation):
Animation.update(self) Animation.update(self)
ds = self.get_display_surface() ds = self.get_display_surface()
dsr = ds.get_rect() dsr = ds.get_rect()
# Save the existing clip
existing_clip = ds.get_clip()
if existing_clip is not None:
left = existing_clip.left
width = existing_clip.width
else:
left = 0
width = dsr.w
# Draw blinds
for y in range(0, dsr.h, dsr.h // self.BLIND_COUNT): for y in range(0, dsr.h, dsr.h // self.BLIND_COUNT):
if self.up: if self.up:
ds.set_clip((0, y, dsr.w, dsr.h // self.BLIND_COUNT - self.blind_height)) ds.set_clip((left, y, width, dsr.h // self.BLIND_COUNT - self.blind_height))
else: else:
ds.set_clip((0, y + self.blind_height, dsr.w, dsr.h // self.BLIND_COUNT - self.blind_height)) ds.set_clip((left, y + self.blind_height, width, dsr.h // self.BLIND_COUNT - self.blind_height))
ds.blit(self.image, (0, 0)) ds.blit(self.image, (0, 0))
ds.set_clip(None)
# Restore clip
ds.set_clip(existing_clip)
class Platform(GameChild): class Platform(GameChild):

1
config
View File

@ -23,6 +23,7 @@ data-exclude = local/, *.pyc, .git*, README, build/, dist/, *.egg-info, *.py, MA
[display] [display]
caption = Scrapeboard caption = Scrapeboard
show-framerate = yes show-framerate = yes
framerate-position = 600, 0
dimensions = 800, 450 dimensions = 800, 450
fullscreen = no fullscreen = no
attract-gif-alpha = 1.0 attract-gif-alpha = 1.0

@ -1 +1 @@
Subproject commit 314b722528a65e6f0053f8be1844c2d8818319f4 Subproject commit d00e434c633f8ca45ab4fd1fb56e19d876027a1d

View File

@ -1,6 +1,10 @@
41802 0
41903 0
42153 0
48935 0 48935 0
50940 0 50940 0
51245 0 51245 0
51355 0
51372 0 51372 0
51754 0 51754 0
52110 0 52110 0
@ -70,7 +74,9 @@
87726 0 87726 0
90718 0 90718 0
91883 0 91883 0
73379 1
80500 1 80500 1
81857 1
89673 1 89673 1
93372 1 93372 1
93427 1 93427 1
@ -90,5 +96,7 @@
119812 1 119812 1
120058 1 120058 1
120493 1 120493 1
66801 2
85743 2 85743 2
86038 2
103819 2 103819 2