optimize score drawing

This commit is contained in:
ohsqueezy 2022-11-03 22:47:01 -04:00
parent e86a3d2324
commit 0f0f771ea8
2 changed files with 45 additions and 22 deletions

62
NS.py
View File

@ -30,7 +30,7 @@ from pygame.locals import *
from lib.pgfw.pgfw.Game import Game from lib.pgfw.pgfw.Game import Game
from lib.pgfw.pgfw.GameChild import GameChild 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.Animation import Animation
from lib.pgfw.pgfw.Vector import Vector from lib.pgfw.pgfw.Vector import Vector
from lib.pgfw.pgfw.extension import ( from lib.pgfw.pgfw.extension import (
@ -268,14 +268,13 @@ class NS(Game, Animation):
self.ending = Ending(self) self.ending = Ending(self)
self.last_press = get_ticks() self.last_press = get_ticks()
self.register(self.blink_score, interval=500)
self.register(self.close_pop_up) self.register(self.close_pop_up)
self.play(self.blink_score)
self.reset() self.reset()
self.most_recent_score = None self.most_recent_score = None
self.pop_up_font = pygame.font.Font( self.pop_up_font = pygame.font.Font(
self.get_resource(Dialogue.FONT_PATH), 12) self.get_resource(Dialogue.FONT_PATH), 12)
self.pop_up_text = "" 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 = 14 blank_count = 14
@ -284,11 +283,16 @@ 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())
# 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:
for line in score_file: for line in score_file:
if line.strip(): if line.strip():
self.scores.append(NS.Score.from_string(line)) self.scores.append(NS.Score.from_string(line))
# Draw the score sprites
self.title.draw_scores()
clear() clear()
def serial_enabled(self): def serial_enabled(self):
@ -344,7 +348,6 @@ class NS(Game, Animation):
self.idle_elapsed = 0 self.idle_elapsed = 0
def reset(self, leave_wipe_running=False): def reset(self, leave_wipe_running=False):
self.score_hidden = False
self.idle_elapsed = 0 self.idle_elapsed = 0
self.suppressing_input = False self.suppressing_input = False
self.level_select.reset() self.level_select.reset()
@ -359,9 +362,6 @@ class NS(Game, Animation):
self.no_reset_elapsed = 0 self.no_reset_elapsed = 0
self.title.activate() self.title.activate()
def blink_score(self):
self.score_hidden = not self.score_hidden
def suppress_input(self): def suppress_input(self):
self.suppressing_input = True self.suppressing_input = True
# self.platform.unpress() # self.platform.unpress()
@ -426,6 +426,7 @@ class NS(Game, Animation):
def add_time_to_scores(self, milliseconds: int, level_index=None): 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. 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 milliseconds player's time in milliseconds
@param level_index the level this time corresponds to or None for a full game @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): for score in sorted(self.scores):
if not score.blank(): if not score.blank():
score_file.write(f"{score.serialize()}\n") score_file.write(f"{score.serialize()}\n")
self.title.draw_scores()
def update(self): def update(self):
Animation.update(self) Animation.update(self)
@ -988,6 +990,7 @@ class Title(Animation):
self.video.location.center = 329, 182 self.video.location.center = 329, 182
self.register(self.show_video, self.hide_video) self.register(self.show_video, self.hide_video)
self.show_video() self.show_video()
self.score_sprites = []
def reset(self): def reset(self):
self.unlock_index = 0 self.unlock_index = 0
@ -1021,32 +1024,55 @@ class Title(Animation):
self.get_game().level_select.launch(0) self.get_game().level_select.launch(0)
def draw_scores(self): 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"): 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] entries = ["BEST"] + sorted([score for score in self.get_game().scores if score.is_full()])[:15]
else: else:
entries = ["NORMAL"] + sorted([score for score in self.get_game().scores if score.level_index == 0])[:3] + \ 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] + \ ["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] ["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): for ii, entry in enumerate(entries):
# Reset y counter
if ii == 0 or ii == 8: if ii == 0 or ii == 8:
y = 20 y = 20
font = Font(self.get_resource(Dialogue.FONT_PATH), 18) font = Font(self.get_resource(Dialogue.FONT_PATH), 18)
# Parse both strings and score objects
if isinstance(entry, NS.Score): if isinstance(entry, NS.Score):
text = entry.formatted() text = entry.formatted()
else: else:
text = entry 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 = render_box(font, text, True, Color(255, 255, 255), Color(128, 128, 128), Color(0, 0, 0), padding=2)
message.set_alpha(230) message.set_alpha(230)
rect = message.get_rect()
rect.top = y # Store it in a sprite, use a blinking sprite for the most recent score
if ii < 8: if not entry == self.get_game().most_recent_score:
rect.left = -1 sprite = Sprite(self)
else: else:
rect.right = ds.get_width() + 1 sprite = BlinkingSprite(self, 500)
if not entry == self.get_game().most_recent_score or not self.get_game().score_hidden: sprite.add_frame(message)
ds.blit(message, rect) 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 y += step
def show_video(self): def show_video(self):
@ -1107,7 +1133,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)
# self.video.update() # self.video.update()
self.draw_scores() # self.draw_scores()
for score in self.score_sprites:
score.update()
class Dialogue(Animation): class Dialogue(Animation):

View File

@ -1,5 +0,0 @@
42263 0
53560 0
54265 0
64714 2
72005 2