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.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):

View File

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