You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何在LibGDX中用Preferences实现含用户名与分数的排行榜

嘿,我懂你现在的困境——之前只做了显示单一最高分的功能,现在想改成带用户名的排行榜,还打算用Preferences来实现,结果尝试关联用户名和分数的时候卡壳了对吧?别着急,我给你一步步捋清楚怎么搞定这个需求,结合代码示例来帮你落地。

用Preferences实现带用户名的排行榜

核心思路是把用户-分数的配对数据以结构化的方式存在Preferences里,再做排序和显示处理,具体步骤如下:

1. 设计Preferences的存储结构

Preferences是键值对存储,我们不能只存单个分数,得用一组关联的键来保存多条记录:

  • 用highscore_count记录当前排行榜的总条数(比如我们设定最多存5条高分)
  • 每条记录对应两个键:highscore_索引_name存用户名,highscore_索引_score存对应分数(比如highscore_0_name、highscore_0_score对应第一条记录)

2. 编写高分管理核心方法

下面以Unity为例写核心逻辑(其他引擎的Preferences API类似,只需替换对应方法):

using UnityEngine;
using System.Collections.Generic;

public class HighscoreManager : MonoBehaviour
{
    // 排行榜最多保存的条数
    private const int MAX_HIGHSCORE_ENTRIES = 5;
    // 记录总条数的键名
    private const string HIGHSCORE_COUNT_KEY = "highscore_total";

    // 对外暴露的添加高分方法
    public void AddNewHighscore(string username, int currentScore)
    {
        // 先获取当前所有已存的高分记录
        List<(string name, int score)> highscoreList = GetAllHighscores();
        
        // 添加新的用户-分数配对
        highscoreList.Add((username, currentScore));
        
        // 按分数从高到低排序
        highscoreList.Sort((a, b) => b.score.CompareTo(a.score));
        
        // 如果超过最大条数,移除最后一条(分数最低的)
        if (highscoreList.Count > MAX_HIGHSCORE_ENTRIES)
        {
            highscoreList.RemoveAt(highscoreList.Count - 1);
        }
        
        // 把排序后的记录存回Preferences
        SaveHighscoreList(highscoreList);
    }

    // 获取所有已存的高分记录
    public List<(string name, int score)> GetAllHighscores()
    {
        List<(string name, int score)> result = new List<(string, int)>();
        int entryCount = PlayerPrefs.GetInt(HIGHSCORE_COUNT_KEY, 0);

        for (int i = 0; i < entryCount; i++)
        {
            string nameKey = $"highscore_{i}_name";
            string scoreKey = $"highscore_{i}_score";

            string username = PlayerPrefs.GetString(nameKey, "");
            int score = PlayerPrefs.GetInt(scoreKey, 0);

            // 跳过空用户名的无效记录
            if (!string.IsNullOrEmpty(username))
            {
                result.Add((username, score));
            }
        }

        return result;
    }

    // 将整理好的高分列表存入Preferences
    private void SaveHighscoreList(List<(string name, int score)> highscoreList)
    {
        // 先清空旧的记录,避免残留数据
        int oldEntryCount = PlayerPrefs.GetInt(HIGHSCORE_COUNT_KEY, 0);
        for (int i = 0; i < oldEntryCount; i++)
        {
            PlayerPrefs.DeleteKey($"highscore_{i}_name");
            PlayerPrefs.DeleteKey($"highscore_{i}_score");
        }

        // 写入新的记录
        for (int i = 0; i < highscoreList.Count; i++)
        {
            PlayerPrefs.SetString($"highscore_{i}_name", highscoreList[i].name);
            PlayerPrefs.SetInt($"highscore_{i}_score", highscoreList[i].score);
        }

        // 更新总条数并保存到磁盘
        PlayerPrefs.SetInt(HIGHSCORE_COUNT_KEY, highscoreList.Count);
        PlayerPrefs.Save();
    }
}

3. 在游戏结束界面显示排行榜

接下来在你的游戏结束UI脚本里,调用上面的方法获取数据并显示出来:

using UnityEngine;
using TMPro; // 假设用TextMeshPro显示文本

public class GameEndPanel : MonoBehaviour
{
    public HighscoreManager highscoreManager;
    public TMP_Text leaderboardDisplayText;

    void Start()
    {
        // 界面加载时就显示排行榜
        RefreshLeaderboardDisplay();
    }

    // 更新排行榜显示内容
    public void RefreshLeaderboardDisplay()
    {
        var highscores = highscoreManager.GetAllHighscores();
        string displayContent = "🏆 高分排行榜 🏆\n\n";

        for (int i = 0; i < highscores.Count; i++)
        {
            displayContent += $"{i+1}. {highscores[i].name} - {highscores[i].score}分\n";
        }

        // 如果没有记录,显示提示
        if (highscores.Count == 0)
        {
            displayContent += "暂无记录,快来创造第一个高分吧!";
        }

        leaderboardDisplayText.text = displayContent;
    }

    // 用户输入用户名并提交时调用
    public void OnUsernameSubmitted(string username)
    {
        // 空用户名不提交
        if (string.IsNullOrEmpty(username.Trim()))
        {
            return;
        }

        // 替换成你获取当前游戏得分的方法
        int currentGameScore = GameManager.Instance.GetCurrentScore();
        highscoreManager.AddNewHighscore(username.Trim(), currentGameScore);
        // 提交后刷新显示
        RefreshLeaderboardDisplay();
    }
}

几个需要注意的细节

  • 如果你之前存过单一的最高分键(比如highscore),记得先调用PlayerPrefs.DeleteKey("highscore")清理掉,避免数据冲突
  • 可以给用户名输入加个长度限制,比如最多10个字符,避免显示溢出
  • 如果是其他引擎(比如Godot),把PlayerPrefs换成对应引擎的Preferences API即可,核心逻辑完全一致

内容的提问来源于stack exchange,提问作者yetx95

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:08:04