HOME / 第 6 部分 · 数据与进阶开发 / 第 66 课
MODULE 6 · 数据与进阶开发

第 66 课 · 排行榜系统

⏱ 预计时长 40 分钟📊 难度 进阶📚 模块 第 6 部分 · 数据与进阶开发

🎯 本课学习目标

「最高分」是玩家动力。本课实现本地排行榜。

📖 详细教学步骤

排行榜数据设计

本地排行榜存数组,按分数降序:

GDSCRIPT# 结构: [{name, score, time}, ...]
var leaderboard: Array = []
var MAX_ENTRIES: int = 10

插入新成绩代码

新成绩插入并保持排序:

GDSCRIPTfunc add_score(name: String, score: int):
    var entry = {"name": name, "score": score,
                 "time": Time.get_datetime_string_from_system()}
    leaderboard.append(entry)
    # 按分数降序排序
    leaderboard.sort_custom(func(a, b): return a["score"] > b["score"])
    # 只保留前 10
    if leaderboard.size() > MAX_ENTRIES:
        leaderboard.resize(MAX_ENTRIES)
    save_leaderboard()

保存与加载代码

排行榜持久化到 JSON:

GDSCRIPTfunc save_leaderboard():
    var file = FileAccess.open("user://leaderboard.json", FileAccess.WRITE)
    file.store_string(JSON.stringify(leaderboard))
    file.close()

func load_leaderboard():
    if FileAccess.file_exists("user://leaderboard.json"):
        var file = FileAccess.open("user://leaderboard.json", FileAccess.READ)
        var parsed = JSON.parse_string(file.get_as_text())
        file.close()
        if parsed is Array:
            leaderboard = parsed

检查是否上榜代码

游戏结束时判断是否值得展示输入姓名:

GDSCRIPTfunc qualifies(score: int) -> bool:
    if leaderboard.size() < MAX_ENTRIES:
        return true
    return score > leaderboard[leaderboard.size() - 1]["score"]

排行榜 UI搭建

  1. 做 Leaderboard 面板:Panel + VBoxContainer
  2. 每行一个 HBox:名次 + 名字 + 分数
  3. 刷新时清空重建:
GDSCRIPT@onready var list: VBoxContainer = $Panel/VBox

func refresh():
    for child in list.get_children():
        child.queue_free()   # 清空旧行
    for i in range(leaderboard.size()):
        var e = leaderboard[i]
        var row = Label.new()
        row.text = "%d. %s  %d分" % (i + 1, e["name"], e["score"])
        row.add_theme_font_size_override("font_size", 22)
        list.add_child(row)

输入玩家名字进阶

上榜时用 LineEdit 输入名字:

GDSCRIPTfunc _on_name_entered(text: String):
    if text == "":
        text = "玩家"
    Globals.add_score(text, Globals.last_score)
    refresh()
    name_input.visible = false   # 隐藏输入框
⚠️
排序后顺序乱了?

sort_custom 返回 true 表示 a 排在 b 前。写 > 是降序、< 是升序。

⚠️
排行榜显示空?

确认 load_leaderboard 在启动时被调用,且数据文件存在。

🧪 动手试一试

🏋️ 课后练习

给滚球游戏加排行榜:通关时若上榜则输入名字,榜单显示前 10 名。

qualifies 判断 + LineEdit 输入 + add_score 插入 + refresh 渲染。

💡

榜单行用 HBox + 等宽字体对齐更整齐。

💡

本地排行榜为起点,联网排行榜第 71 课可升级。

🎓 本课小结

排行榜 = 数组 + sort_custom 降序 + JSON 持久化 + qualifies 判断上榜 + UI 动态渲染;最多保留 10 条。