Files
MusicPlayer/PlayerObject.gd
T
Sansan c7d49bc5cc Rework popups and fix blurry text and player list layout
Popups:
- All nine popups now extend a shared PopupWindow class with open(),
  close() and toggle(), instead of each copying its own close-on-click
  code. Popups that need cleanup override close().
- A click outside a popup closed it and also pressed whatever was
  underneath, e.g. Reset playlist. The closing click is now consumed.
- Popups used Godot's see-through default panel, so the song list and
  titles showed through. They now use an opaque popup theme, and a
  backdrop dims the window behind them.
- The main window root now fills the screen, so the backdrop covers it.

Text and images:
- Many labels and buttons forced nearest filtering, which made text and
  icons jagged when the window is not 1920x1080. They now use the
  default smooth filtering. Only the pixel-art "no character" picture
  keeps nearest filtering when the winner window enlarges it.

Player list:
- A long player name pushed that row's character and buttons to the
  right. Names now take the free space and shorten with an ellipsis, so
  all rows line up and use the full width of the panel.
2026-10-06 08:32:56 +02:00

67 lines
1.9 KiB
GDScript

extends RefCounted
class_name PlayerObject
signal first_point_triggerd
signal match_point_triggerd
signal winner_triggerd
signal point_given_sound
signal player_point_given
signal player_point_taken
## Unique id that never changes, unlike the player's position in Settings.player_array.
var id: String = _generate_uuid()
@export
var player_name: String
@export
var player_score: int
var is_first_point: bool = true
## Picture shown until the player picks a character.
const NO_CHARACTER_PATH: String = "res://noCharacter.png"
var character: Texture = load(NO_CHARACTER_PATH)
func _init(new_name: String) -> void:
player_name = new_name
player_score = 0
## Returns a random version 4 UUID, e.g. "3f2b8c1e-9a4d-4e7f-b2c6-5d8e1f0a7b93".
static func _generate_uuid() -> String:
var bytes: PackedByteArray = Crypto.new().generate_random_bytes(16)
bytes[6] = (bytes[6] & 0x0f) | 0x40
bytes[8] = (bytes[8] & 0x3f) | 0x80
var hex: String = bytes.hex_encode()
return "%s-%s-%s-%s-%s" % [hex.substr(0, 8), hex.substr(8, 4), hex.substr(12, 4), hex.substr(16, 4), hex.substr(20, 12)]
func add_point() -> void:
if player_score < Settings.winning_score:
player_score += 1
player_point_given.emit()
var first_point: bool = player_score == 1 && is_first_point
if player_score == 1:
is_first_point = false
# With a low winning score the first point can also be match point or the win,
# so the more important event is checked first
if player_score == Settings.winning_score:
winner_triggerd.emit()
elif player_score == Settings.winning_score - 1:
match_point_triggerd.emit()
elif first_point:
first_point_triggerd.emit()
else:
point_given_sound.emit()
func minus_point() -> void:
if player_score > 0:
player_score -= 1
player_point_taken.emit()
if player_score == 0:
is_first_point = true
func reset_points() -> void:
player_score = 0
is_first_point = true