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.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
self.scores = []
blank_count = 25
@ -317,6 +310,7 @@ class NS(Game, Animation):
self.scores.append(NS.Score.blank_level(level_index))
for _ in range(blank_count):
self.scores.append(NS.Score.blank_full())
self.most_recent_score = None
# Add existing scores to the list from file
with open(self.get_resource("scores"), "rt") as score_file:
@ -327,6 +321,11 @@ class NS(Game, Animation):
# Draw the score sprites
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()
def pi_enabled(self):
@ -957,6 +956,9 @@ class Tony(Sprite):
class Video(Sprite):
"""
Attract mode pop-up that rotates through GIFs.
"""
def __init__(self, parent, diameter, next_video_chance=.01):
Sprite.__init__(self, parent, 100)
@ -1009,12 +1011,13 @@ class Video(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):
"""
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)
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):
if x != 0 or y != 0:
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):
"""
Scroll the tiles, wrapping at the edges of the screen.
Draw the background, disable parent update (performance hack)
"""
# Wrap around motion effect
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)
self.get_display_surface().blit(self.background, (0, 0))
class Title(Animation):
@ -1101,9 +1102,19 @@ class Title(Animation):
self.get_game().tony.set_frameset("static")
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):
self.active = False
self.halt()
self.get_display_surface().set_clip(None)
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)
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:
self.score_blanker = BlinkingSprite(self, 500)
blank = pygame.surface.Surface(score_surface.get_size())
blank.fill(bg)
self.score_blanker.add_frame(blank)
self.score_blanker.location = screen_pos
self.score_indicator = BlinkingSprite(self, 500)
arrow = pygame.surface.Surface([score_surface.get_height()] * 2)
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()
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
return score_surface.get_height()
@ -1174,11 +1196,11 @@ class Title(Animation):
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
them evenly into categories: normal, advanced, and expert. Draw the two columns to the display surface, with the expectation that they will be
removed from the clip and will not be drawn over. Note that this doesn't support non-level select mode anymore.
them evenly into categories: normal, advanced, and expert. Save the columns as sprites. Note that this doesn't support non-level select mode
anymore.
"""
ds = self.get_display_surface()
self.score_blanker = None
self.score_indicator = None
heading_width, heading_height = self.heading_font.size("ADVANCED")
heading_width += 10
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.location.topleft = x, 0
self.score_sprites = [left_column_sprite, right_column_sprite]
for sprite in self.score_sprites:
sprite.update()
def show_video(self):
self.video.unhide()
@ -1251,9 +1271,6 @@ class Title(Animation):
ds = self.get_display_surface()
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
self.get_game().logo.update()
@ -1295,11 +1312,9 @@ class Title(Animation):
self.halt()
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
ds.set_clip(None)
if self.score_blanker:
self.score_blanker.update()
# Indicate most recent score
if self.score_indicator is not None:
self.score_indicator.update()
class Dialogue(Animation):
"""
@ -1599,13 +1614,26 @@ class Wipe(Animation):
Animation.update(self)
ds = self.get_display_surface()
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):
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:
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.set_clip(None)
# Restore clip
ds.set_clip(existing_clip)
class Platform(GameChild):

1
config
View File

@ -23,6 +23,7 @@ data-exclude = local/, *.pyc, .git*, README, build/, dist/, *.egg-info, *.py, MA
[display]
caption = Scrapeboard
show-framerate = yes
framerate-position = 600, 0
dimensions = 800, 450
fullscreen = no
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
50940 0
51245 0
51355 0
51372 0
51754 0
52110 0
@ -70,7 +74,9 @@
87726 0
90718 0
91883 0
73379 1
80500 1
81857 1
89673 1
93372 1
93427 1
@ -90,5 +96,7 @@
119812 1
120058 1
120493 1
66801 2
85743 2
86038 2
103819 2