Files
MusicPlayer/popups/winner_popup.gd
T
Sansan e1e05f3904
Build / test (push) Successful in 38s
Build / build (push) Successful in 1m12s
Show a graph of the game on the Winner popup
The Winner popup now shows every player's score after each song as a
step line, with the winning score marked, and three facts under it: the
longest streak, the longest standstill and the song most players scored
on. The data comes from the points each song already records, through
the new ScoreHistory. The popup grows to 1600x920 with the graph across
the full width, so a 60-song game with five players stays readable.

Reset points now starts a new game: it clears the points on the songs
and the graph starts after the song that was playing. Songs already on
the server at startup count as an earlier game.

The screenshot tour has a long five-player game, and only the Winner
popup differs from before.
2026-10-07 10:40:46 +02:00

81 lines
3.0 KiB
GDScript

class_name WinnerPopup
extends BasePopup
## Shows who won, with their character, where the other players placed, and how the game
## went: a graph of everyone's score after each song and a few facts about it.
## Size of the coloured square in front of each name in the legend.
const LEGEND_SQUARE_SIZE: Vector2 = Vector2(14, 14)
@onready var winner_panel: Panel = %WinnerPanel
@onready var winner_picture: TextureRect = %WinnerPicture
@onready var winner_label: Label = %WinnerLabel
@onready var players_list: VBoxContainer = %PlayersList
@onready var legend: HBoxContainer = %Legend
@onready var score_graph: ScoreGraph = %ScoreGraph
@onready var streak_label: Label = %StreakLabel
@onready var standstill_label: Label = %StandstillLabel
@onready var shared_label: Label = %SharedLabel
func _ready() -> void:
visible = false
func show_winner(winner: PlayerObject) -> void:
visible = true
winner_label.text = winner.player_name + " won with " + str(winner.player_score) + \
" points!!"
winner_picture.texture = winner.character
# The "no character" placeholder is pixel art, which blurs when scaled up smoothly
if winner.character.resource_path == PlayerObject.NO_CHARACTER_PATH:
winner_picture.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
else:
winner_picture.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR
# Clear previous player list entries
for child: Node in players_list.get_children():
child.queue_free()
# Sort players by score (descending) and add to list
var sorted_players: Array = Settings.player_array.duplicate()
sorted_players.sort_custom(
func(a: PlayerObject, b: PlayerObject) -> bool:
return a.player_score > b.player_score
)
var placing: int = 2
for player: PlayerObject in sorted_players:
if player == winner:
continue # Skip the winner, already shown above
var label: Label = Label.new()
label.text = str(placing) + ". " + player.player_name + " - " + \
str(player.player_score) + " points"
players_list.add_child(label)
placing += 1
show_history(ScoreHistory.from_playlist(Settings.player_array))
## Shows how the game went: the score graph, its legend and the summary boxes.
func show_history(history: ScoreHistory) -> void:
score_graph.show_history(history, Settings.winning_score)
streak_label.text = history.longest_streak_text()
standstill_label.text = history.longest_standstill_text()
shared_label.text = history.most_shared_text()
for child: Node in legend.get_children():
legend.remove_child(child)
child.queue_free()
for index: int in history.players.size():
var player: PlayerObject = history.players[index]
var entry: HBoxContainer = HBoxContainer.new()
var square: ColorRect = ColorRect.new()
square.custom_minimum_size = LEGEND_SQUARE_SIZE
square.size_flags_vertical = Control.SIZE_SHRINK_CENTER
square.color = score_graph.player_color(index)
entry.add_child(square)
var name_label: Label = Label.new()
name_label.text = "%s %d" % [player.player_name, history.final_score(player.id)]
entry.add_child(name_label)
legend.add_child(entry)