diff --git a/NS.py b/NS.py index 2039d97..f69664f 100644 --- a/NS.py +++ b/NS.py @@ -30,7 +30,7 @@ from pygame.locals import * from lib.pgfw.pgfw.Game import Game from lib.pgfw.pgfw.GameChild import GameChild -from lib.pgfw.pgfw.Sprite import Sprite, RainbowSprite +from lib.pgfw.pgfw.Sprite import Sprite, RainbowSprite, BlinkingSprite from lib.pgfw.pgfw.Animation import Animation from lib.pgfw.pgfw.Vector import Vector from lib.pgfw.pgfw.extension import ( @@ -268,14 +268,13 @@ class NS(Game, Animation): self.ending = Ending(self) self.last_press = get_ticks() - self.register(self.blink_score, interval=500) self.register(self.close_pop_up) - self.play(self.blink_score) 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 = 14 @@ -284,11 +283,16 @@ 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()) + # Add existing scores to the list from file with open(self.get_resource("scores"), "rt") as score_file: for line in score_file: if line.strip(): self.scores.append(NS.Score.from_string(line)) + + # Draw the score sprites + self.title.draw_scores() + clear() def serial_enabled(self): @@ -344,7 +348,6 @@ class NS(Game, Animation): self.idle_elapsed = 0 def reset(self, leave_wipe_running=False): - self.score_hidden = False self.idle_elapsed = 0 self.suppressing_input = False self.level_select.reset() @@ -359,9 +362,6 @@ class NS(Game, Animation): self.no_reset_elapsed = 0 self.title.activate() - def blink_score(self): - self.score_hidden = not self.score_hidden - def suppress_input(self): self.suppressing_input = True # self.platform.unpress() @@ -426,6 +426,7 @@ class NS(Game, Animation): def add_time_to_scores(self, milliseconds: int, level_index=None): """ Add a time to the list of scores. This method will build a score object, add it to the list, and write to the scores file. + It will also call on the title screen object to draw the sprites. @param milliseconds player's time in milliseconds @param level_index the level this time corresponds to or None for a full game @@ -440,6 +441,7 @@ class NS(Game, Animation): for score in sorted(self.scores): if not score.blank(): score_file.write(f"{score.serialize()}\n") + self.title.draw_scores() def update(self): Animation.update(self) @@ -988,6 +990,7 @@ class Title(Animation): self.video.location.center = 329, 182 self.register(self.show_video, self.hide_video) self.show_video() + self.score_sprites = [] def reset(self): self.unlock_index = 0 @@ -1021,32 +1024,55 @@ class Title(Animation): self.get_game().level_select.launch(0) def draw_scores(self): - step = 56 - ds = self.get_display_surface() + """ + Draw frames for a sprite object for each score and store the sprite in a list to be drawn each frame. + """ + # Create a list of strings in order of which to draw if not self.get_configuration("system", "enable-level-select"): entries = ["BEST"] + sorted([score for score in self.get_game().scores if score.is_full()])[:15] else: entries = ["NORMAL"] + sorted([score for score in self.get_game().scores if score.level_index == 0])[:3] + \ ["ADVANCED"] + sorted([score for score in self.get_game().scores if score.level_index == 1])[:3] + \ ["EXPERT"] + sorted([score for score in self.get_game().scores if score.level_index == 2])[:7] + + # Create a sprite object for each score and place on the screen in two columns on the left and right edges the screen + step = 56 + ds = self.get_display_surface() + self.score_sprites = [] for ii, entry in enumerate(entries): + + # Reset y counter if ii == 0 or ii == 8: y = 20 + font = Font(self.get_resource(Dialogue.FONT_PATH), 18) + + # Parse both strings and score objects if isinstance(entry, NS.Score): text = entry.formatted() else: text = entry + + # Create a surface as a box around the score message = render_box(font, text, True, Color(255, 255, 255), Color(128, 128, 128), Color(0, 0, 0), padding=2) message.set_alpha(230) - rect = message.get_rect() - rect.top = y - if ii < 8: - rect.left = -1 + + # Store it in a sprite, use a blinking sprite for the most recent score + if not entry == self.get_game().most_recent_score: + sprite = Sprite(self) else: - rect.right = ds.get_width() + 1 - if not entry == self.get_game().most_recent_score or not self.get_game().score_hidden: - ds.blit(message, rect) + sprite = BlinkingSprite(self, 500) + sprite.add_frame(message) + self.score_sprites.append(sprite) + + # Place the sprite along the column + sprite.location.top = y + if ii < 8: + sprite.location.left = -1 + else: + sprite.location.right = ds.get_width() + 1 + + # Move to the next sprite location y += step def show_video(self): @@ -1107,7 +1133,9 @@ class Title(Animation): self.halt() self.play(self.show_video, delay=self.get_configuration("time", "attract-reset-countdown"), play_once=True) # self.video.update() - self.draw_scores() + # self.draw_scores() + for score in self.score_sprites: + score.update() class Dialogue(Animation): diff --git a/resource/scores b/resource/scores index 2cdf428..e69de29 100644 --- a/resource/scores +++ b/resource/scores @@ -1,5 +0,0 @@ -42263 0 -53560 0 -54265 0 -64714 2 -72005 2