From 8390fb27942cac8fdd1e508d5b8584757185a017 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Fri, 9 Aug 2024 14:55:45 +0800 Subject: [PATCH] :sparkles: Leaderboard --- Scenes/Root.tscn | 7 +++- Scenes/UI/HUD.tscn | 2 +- Scenes/UI/Leaderboard.tscn | 36 ++++++++++++++++++ Scenes/UI/LeaderboardRecord.tscn | 53 +++++++++++++++++++++++++++ Scripts/Logic/World.cs | 7 ++++ Scripts/UI/BootScreen.cs | 2 +- Scripts/UI/Leaderboard.cs | 63 ++++++++++++++++++++++++++++++++ Scripts/UI/LeaderboardRecord.cs | 19 ++++++++++ project.godot | 5 +++ 9 files changed, 191 insertions(+), 3 deletions(-) create mode 100644 Scenes/UI/Leaderboard.tscn create mode 100644 Scenes/UI/LeaderboardRecord.tscn create mode 100644 Scripts/UI/Leaderboard.cs create mode 100644 Scripts/UI/LeaderboardRecord.cs diff --git a/Scenes/Root.tscn b/Scenes/Root.tscn index 654793f..d8d7c53 100644 --- a/Scenes/Root.tscn +++ b/Scenes/Root.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=10 format=3 uid="uid://bjhmjrldq4lkt"] +[gd_scene load_steps=11 format=3 uid="uid://bjhmjrldq4lkt"] [ext_resource type="PackedScene" uid="uid://b3gx0bl43lku3" path="res://Scenes/Player.tscn" id="1_vby0g"] [ext_resource type="PackedScene" uid="uid://dk8x2aeq1eevf" path="res://Scenes/UI/BootScreen.tscn" id="2_7aede"] @@ -8,6 +8,7 @@ [ext_resource type="Script" path="res://Scripts/Logic/World.cs" id="3_xwguj"] [ext_resource type="PackedScene" uid="uid://bb704b0kpwwkr" path="res://Scenes/UI/PlayerDiedScreen.tscn" id="5_pimes"] [ext_resource type="PackedScene" uid="uid://c7w5sgq0bshk0" path="res://Scenes/UI/HUD.tscn" id="5_qvun1"] +[ext_resource type="PackedScene" uid="uid://dfoy57v3q4of5" path="res://Scenes/UI/Leaderboard.tscn" id="7_j24m7"] [sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_gyspy"] properties/0/path = NodePath(".:RoundProgress") @@ -37,6 +38,10 @@ script = ExtResource("3_as2wg") [node name="OverlayLayer" type="CanvasLayer" parent="."] +[node name="Leaderboard" parent="OverlayLayer" node_paths=PackedStringArray("Scoreboard") instance=ExtResource("7_j24m7")] +visible = false +Scoreboard = NodePath("../../ScoreboardNode") + [node name="Hud" parent="OverlayLayer" node_paths=PackedStringArray("World") instance=ExtResource("5_qvun1")] visible = false World = NodePath("../../World") diff --git a/Scenes/UI/HUD.tscn b/Scenes/UI/HUD.tscn index 2107f46..b9fcf4e 100644 --- a/Scenes/UI/HUD.tscn +++ b/Scenes/UI/HUD.tscn @@ -94,7 +94,7 @@ text = "(0, 0)" [node name="RoundLabel" type="Label" parent="BottomBox/HBox"] layout_mode = 2 size_flags_horizontal = 3 -text = "Round 1" +text = "Round 01/20" horizontal_alignment = 1 [node name="ScoreLabel" type="Label" parent="BottomBox/HBox"] diff --git a/Scenes/UI/Leaderboard.tscn b/Scenes/UI/Leaderboard.tscn new file mode 100644 index 0000000..6e7e342 --- /dev/null +++ b/Scenes/UI/Leaderboard.tscn @@ -0,0 +1,36 @@ +[gd_scene load_steps=3 format=3 uid="uid://dfoy57v3q4of5"] + +[ext_resource type="PackedScene" uid="uid://b8s2m7gujfmp6" path="res://Scenes/UI/LeaderboardRecord.tscn" id="1_mr7v4"] +[ext_resource type="Script" path="res://Scripts/UI/Leaderboard.cs" id="1_sbkyu"] + +[node name="Leaderboard" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_sbkyu") + +[node name="Label" type="Label" parent="."] +layout_mode = 0 +offset_left = 16.0 +offset_top = 21.0 +offset_right = 1136.0 +offset_bottom = 85.0 +theme_override_font_sizes/font_size = 24 +text = "Leaderboard" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="List" type="VBoxContainer" parent="."] +layout_mode = 0 +offset_left = 16.0 +offset_top = 97.0 +offset_right = 1136.0 +offset_bottom = 631.0 +theme_override_constants/separation = 16 + +[node name="LeaderboardRecord" parent="List" instance=ExtResource("1_mr7v4")] +custom_minimum_size = Vector2(2.08165e-12, 80) +layout_mode = 2 diff --git a/Scenes/UI/LeaderboardRecord.tscn b/Scenes/UI/LeaderboardRecord.tscn new file mode 100644 index 0000000..df00585 --- /dev/null +++ b/Scenes/UI/LeaderboardRecord.tscn @@ -0,0 +1,53 @@ +[gd_scene load_steps=2 format=3 uid="uid://b8s2m7gujfmp6"] + +[ext_resource type="Script" path="res://Scripts/UI/LeaderboardRecord.cs" id="1_jc2uj"] + +[node name="LeaderboardRecord" type="Control"] +layout_mode = 3 +anchor_left = 0.014 +anchor_top = 0.025 +anchor_right = 0.986 +anchor_bottom = 0.148 +offset_left = -0.128 +offset_top = -0.2 +offset_right = 0.12793 +offset_bottom = 0.0959988 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_jc2uj") + +[node name="Panel" type="Panel" parent="."] +layout_mode = 0 +offset_right = 1120.0 +offset_bottom = 80.0 + +[node name="VBoxContainer" type="HBoxContainer" parent="Panel"] +layout_mode = 0 +offset_right = 1120.0 +offset_bottom = 80.0 + +[node name="PlaceTag" type="Label" parent="Panel/VBoxContainer"] +custom_minimum_size = Vector2(80, 80) +layout_mode = 2 +size_flags_horizontal = 0 +theme_override_font_sizes/font_size = 32 +text = "1" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="NameTag" type="Label" parent="Panel/VBoxContainer"] +custom_minimum_size = Vector2(80, 80) +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_font_sizes/font_size = 24 +text = "Player" +vertical_alignment = 1 + +[node name="ScoreTag" type="Label" parent="Panel/VBoxContainer"] +custom_minimum_size = Vector2(80, 80) +layout_mode = 2 +size_flags_horizontal = 8 +theme_override_font_sizes/font_size = 32 +text = "0" +horizontal_alignment = 1 +vertical_alignment = 1 diff --git a/Scripts/Logic/World.cs b/Scripts/Logic/World.cs index bde4be9..053d920 100644 --- a/Scripts/Logic/World.cs +++ b/Scripts/Logic/World.cs @@ -8,6 +8,7 @@ public partial class World : Node2D [Export] public PackedScene PlayerScene; [Export] public int RoundCount = 1; + [Export] public int RoundTotalCount = 20; [Export] public double RoundDuration = 60; [Export] public double RoundProgress; [Export] public double RoundTimeLeft; @@ -106,6 +107,12 @@ public partial class World : Node2D private void NewRound() { + if (RoundCount >= RoundTotalCount) + { + // TODO End this game + return; + } + RoundCount++; foreach (var child in GetChildren()) { diff --git a/Scripts/UI/BootScreen.cs b/Scripts/UI/BootScreen.cs index fd0811f..f8ce002 100644 --- a/Scripts/UI/BootScreen.cs +++ b/Scripts/UI/BootScreen.cs @@ -33,7 +33,7 @@ public partial class BootScreen : Control EmitSignal(SignalName.StartGame); var name = string.IsNullOrEmpty(PlayerNameInput.Text) ? null : PlayerNameInput.Text; // TODO Fix this I don't know why the first round player's name won't fully apply - World.Scoreboard.SetName(Multiplayer.GetUniqueId(), name); + World.Scoreboard.SetName(Multiplayer.GetUniqueId(), name ?? $"Player#{Multiplayer.GetUniqueId()}"); World.StartGame(currentPlayerName: name); Hide(); } diff --git a/Scripts/UI/Leaderboard.cs b/Scripts/UI/Leaderboard.cs new file mode 100644 index 0000000..5364d49 --- /dev/null +++ b/Scripts/UI/Leaderboard.cs @@ -0,0 +1,63 @@ +using AceField.Scripts.Logic; +using Godot; + +namespace AceField.Scripts.UI; + +public partial class Leaderboard : Control +{ + [Export] public Scoreboard Scoreboard; + + public override void _Process(double delta) + { + Visible = Input.IsActionPressed("ui_leaderboard"); + + if (!Visible) return; + + if (GetNode("List").GetChildCount() != Scoreboard.Players.Count) + { + CleanNodes(); + CreateNodes(); + return; + } + + var place = 1; + foreach (var node in GetNode("List").GetChildren()) + { + if (node is not LeaderboardRecord record) continue; + + var data = Scoreboard.GetData(record.PlayerId); + if (data == null) continue; + + record.Place = place; + record.Score = data.Score; + record.PlayerName = data.Name; + + place++; + } + } + + private void CleanNodes() + { + foreach (var child in GetNode("List").GetChildren()) + { + child.QueueFree(); + } + } + + private void CreateNodes() + { + var blueprint = GD.Load("res://Scenes/UI/LeaderboardRecord.tscn"); + var place = 1; + foreach (var record in Scoreboard.Players) + { + var instance = blueprint.Instantiate(); + instance.Place = place; + instance.PlayerName = record.Value.Name; + instance.Score = record.Value.Score; + instance.PlayerId = record.Key; + instance.CustomMinimumSize = new Vector2(0, 80); + GetNode("List").AddChild(instance); + place++; + } + } +} diff --git a/Scripts/UI/LeaderboardRecord.cs b/Scripts/UI/LeaderboardRecord.cs new file mode 100644 index 0000000..8c4f4aa --- /dev/null +++ b/Scripts/UI/LeaderboardRecord.cs @@ -0,0 +1,19 @@ +using Godot; + +namespace AceField.Scripts.UI; + +public partial class LeaderboardRecord : Control +{ + [Export] public int Place; + [Export] public string PlayerName; + [Export] public int Score; + + [Export] public int PlayerId; + + public override void _Process(double delta) + { + GetNode