首页 > 其他分享 >【专栏精选】实战:使用LeanCloud上传玩家分数,实现排行榜

【专栏精选】实战:使用LeanCloud上传玩家分数,实现排行榜

时间:2023-04-28 16:40:35浏览次数:45  
标签:www string text json 专栏 var LeanCloud 上传 public


本文节选自洪流学堂公众号技术专栏《大话Unity2019》,未经允许不可转载。

洪流学堂公众号回复专栏,查看更多专栏文章。

洪流学堂,让你快人几步。你好,我是郑洪智。

小新:“有了用户登录后,我们总要拿来做点什么事情吧?”
大智:“有了用户登陆信息之后,就可以针对用户来存储他自己的信息了,比如说装备、个人数据、闯关信息等等。”
小新:“是不是类似本地的存档,只不过存到了服务器上?”
大智:“可以这么理解,今天我们来尝试下存储玩家的最高分,并且获取全服的排行榜。”

LeanCloud存储玩家分数

LeanCloud中存储数据的需要用到“对象”,文档在这里:https://leancloud.cn/docs/rest_api.html#hash735965996

如果你熟悉数据库的话,对象类似数据库中的一个表,但是这个对象没有固定的字段,不需要提前标注每个对象上有哪些 key,你你只需要随意设置键值对就可以,后端会保存它。

创建LeanCloud对象

要想使用LeanCloud的对象,可以先在LeanCloud网站的控制台创建对象,也可以不事先创建对象,而通过代码创建。

事先创建的话,可以设置权限:

写入LeanCloud对象

写入LeanCloud对象直接上代码喽:

using System;
using System.Collections;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using Random = UnityEngine.Random;

// 上传分数的Score类,用于序列化成json
[Serializable]
public class Score
{
    public int score;
}

// 用于解析登陆后的token,这个token用来代表已登录的用户
[Serializable]
public class LoginToken{
    public string sessionToken;
}

public class LeanCloudUser : MonoBehaviour
{
    public string AppId;
    public string AppKey;

    public InputField Username;
    public InputField Password;

    private string Token;

    public void Reg()
    {
        var jsonObj = new RegJson()
        {
            username = Username.text,
            password = Password.text
        };
        var json = JsonUtility.ToJson(jsonObj);
        Debug.Log(json);
        StartCoroutine(Request("/users", json));
    }

    public void Login()
    {
        var jsonObj = new RegJson()
        {
            username = Username.text,
            password = Password.text
        };
        var json = JsonUtility.ToJson(jsonObj);
        Debug.Log(json);
        StartCoroutine(Request("/login", json, text =>
        {
            var obj = JsonUtility.FromJson<LoginToken>(text);
            Token = obj.sessionToken;

            UploadMyScore(Random.Range(1, 100));
        }));
    }

    // 重构了请求的类,现在可以更好地适用各种请求
    IEnumerator Request(string path, string json, Action<string> cb = null)
    {

        var url = "https://5jmvfx9e.api.lncld.net/1.1" + path;

        var www = UnityWebRequest.Put(url, json);
        www.method = "POST";
        www.SetRequestHeader("X-LC-Id", AppId);
        www.SetRequestHeader("X-LC-Key", AppKey);
        www.SetRequestHeader("Content-Type", "application/json");
        if (!string.IsNullOrEmpty(Token)) 
            www.SetRequestHeader("X-LC-Session", Token);

        yield return www.SendWebRequest();

        if (www.isHttpError || www.isNetworkError)
        {
            Debug.LogError(www.error);
            Debug.LogError(www.downloadHandler.text);
        }
        else
        {
            Debug.Log(www.downloadHandler.text);
            if (cb != null) cb(www.downloadHandler.text);
        }
    }

    // 上传分数的方法
    private void UploadMyScore(int score)
    {
        var json = JsonUtility.ToJson(new Score(){
            score = score
        });

        StartCoroutine(Request("/classes/Score", json));
    }
}

上面的代码是基于昨天小新重构后的代码又进行了一次重构,现在可以更好地满足不同的请求了。

执行后,就可以在后台看到上传上去的分数了。

LeanCloud排行榜

现在我们有了分数了,怎么获取到排行榜的数据呢?这就需要用到LeanCloud中的对象查询。

文档在这:https://leancloud.cn/docs/rest_api.html#hash860317

排行榜的查询呢,会稍微有一些复杂, 因为我们需要根据玩家的分数进行倒序排列,并取出前10个。

由于取数据使用的HTTP方法是GET,所以需要对代码进行不小的重构,最后代码如下:

using System;
using System.Collections;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using Random = UnityEngine.Random;

// 上传分数的Score类,用于序列化成json
[Serializable]
public class Score
{
    public string username;
    public string userId;
    public int score;
}

// 用于解析登陆后的token,这个token用来代表已登录的用户
[Serializable]
public class UserInfo{
    public string sessionToken;
    public string username;
    public string objectId;
}

public class LeanCloudUser : MonoBehaviour
{
    public string AppId;
    public string AppKey;

    public InputField Username;
    public InputField Password;

    private UserInfo User;

    public void Reg()
    {
        var jsonObj = new RegJson()
        {
            username = Username.text,
            password = Password.text
        };
        var json = JsonUtility.ToJson(jsonObj);
        Debug.Log(json);
        StartCoroutine(Request("/users", "POST", json));
    }

    public void Login()
    {
        var jsonObj = new RegJson()
        {
            username = Username.text,
            password = Password.text
        };
        var json = JsonUtility.ToJson(jsonObj);
        Debug.Log(json);
        StartCoroutine(Request("/login", "POST", json, text =>
        {
            var obj = JsonUtility.FromJson<UserInfo>(text);
            User = obj;

            UploadMyScore(Random.Range(1, 100));
        }));
    }

    // 重构了请求的类,现在可以更好地适用各种请求
    IEnumerator Request(string path, string method = "POST", string data = "", Action<string> cb = null)
    {

        var url = "https://5jmvfx9e.api.lncld.net/1.1" + path;

        var downloadHandler = new DownloadHandlerBuffer();
        UploadHandlerRaw uploadHandler = null;
        if (!string.IsNullOrEmpty(data))
         uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(data));
        var www = new UnityWebRequest(url, method, downloadHandler, uploadHandler);
        www.SetRequestHeader("X-LC-Id", AppId);
        www.SetRequestHeader("X-LC-Key", AppKey);
        www.SetRequestHeader("Content-Type", "application/json");


        yield return www.SendWebRequest();

        if (www.isHttpError || www.isNetworkError)
        {
            Debug.LogError(www.error);
            Debug.LogError(www.downloadHandler.text);
        }
        else
        {
            Debug.Log(www.downloadHandler.text);
            if (cb != null) cb(www.downloadHandler.text);
        }
    }

    // 上传分数的方法
    private void UploadMyScore(int score)
    {
        var json = JsonUtility.ToJson(new Score(){
            score = score,
            username = User.username,
            userId = User.objectId
        });

        StartCoroutine(Request("/classes/Score", "POST", json, _=>{
            GetLeaderboard();
        }));
    }

    public void GetLeaderboard(){
        var path = "/classes/Score?";
        path += "order=-score&limit=10";

        StartCoroutine(Request(path, "GET"));
    }
}

在这由于取出排行榜中的数据要用GET,终于我们没办法使用取巧的请求方式了,老老实实地改回来正常的请求方法。

总结

小新:“其实代码看下来,请求的方式都是类似的,比较重要的是先好好看懂LeanCloud的文档,然后构造相应的请求就可以了。”
大智:“没错,读文档的能力是很重要的,以后写出一份好文档的能力是更重要的。”

思考题

大智:“取到排行榜的数据以后,看看能不能显示到UI上面?”
小新:“好嘞!”
大智:“收获别忘了分享出来!也别忘了分享给你学Unity的朋友,也许能够帮到他。”

  • 洪流学堂公众号回复专栏,查看更多专栏文章。

《大话Unity2019》,大智带小新学Unity2019的有趣经历,让你学Unity更简单。


标签:www,string,text,json,专栏,var,LeanCloud,上传,public
From: https://blog.51cto.com/u_5746184/6234777

相关文章

  • 【专栏精选】网络封包神器protobuf简介
    本文节选自洪流学堂公众号技术专栏《大话Unity2019》,未经允许不可转载。洪流学堂公众号回复专栏,查看更多专栏文章。洪流学堂,让你快人几步。你好,我是郑洪智。大智:“上次我们在学习如何进行数据包封包的时候说到:在网络传输时数据包需要定义好格式,这个格式就是数据在字节流中是如何排......
  • 【专栏精选】使用LeanCloud实现玩家登陆
    本文节选自洪流学堂公众号技术专栏《大话Unity2019》,未经允许不可转载。洪流学堂公众号回复专栏,查看更多专栏文章。洪流学堂,让你快人几步。你好,我是郑洪智。小新:“今天我们是不是该学习登陆了?”大智:“没错,不过登陆我不准备给你讲,你自己学,有啥问题再问我。”小新:“好的吧,正好考验......
  • 【专栏精选】实战:百度语音合成
    本文节选自洪流学堂公众号技术专栏《大话Unity2019》,未经允许不可转载。洪流学堂公众号回复语音识别获取源码工程。洪流学堂,让你快人几步。你好,我是郑洪智。大智:“昨天我们实战了语音识别,在人工智能的语音领域,还有很大一块是语音合成,也就是TexttoSpeech,文字转语音。”小新:“是不......
  • 【专栏精选】热更新之xLua
    本文节选自洪流学堂公众号技术专栏《大话Unity2019》,未经允许不可转载。洪流学堂公众号回复专栏,查看更多专栏文章。洪流学堂,让你快人几步。你好,我是郑洪智。小新:“之前你提到过,Unity热更新有两大流派,C#派和lua派,那lua派是啥样的呢?”大智:“lua是一门历史悠久的脚本语言,从端游那个年......
  • 【专栏精选】Unity热更新之ILRuntime
    本文节选自洪流学堂公众号技术专栏《大话Unity2019》,未经允许不可转载。洪流学堂公众号回复专栏,查看更多专栏文章。洪流学堂,让你快人几步。你好,我是郑洪智。小新:“热更新真的是打开了一片天啊,现在我越发感觉热更新能做的事情太多了。之前做了一个项目,每次打包都好花费半小时,如果有......
  • 【专栏精选】Unity中的HTTP网络通信
    本文节选自洪流学堂公众号技术专栏《大话Unity2019》,未经允许不可转载。洪流学堂公众号回复专栏,查看更多专栏文章。洪流学堂,让你快人几步。你好,我是郑洪智。大智:“小新,今天开始,我们来学习Unity中的HTTP通信。”小新:“为啥不先学Tcp和Udp呢?这俩不是基础么?”大智:“虽然这俩是基础,但......
  • 【专栏精选】实战:百度语音识别
    本文节选自洪流学堂公众号技术专栏《大话Unity2019》,未经允许不可转载。洪流学堂公众号回复语音识别获取源码工程。洪流学堂,让你快人几步。你好,我是郑洪智。大智:“今天给你来点刺激的。”小新满面红光:“啥刺激的?人家可还是个小孩子。”大智:“带你实战!”小新:“啊?智哥你变了!”大......
  • idea 上传项目到gitee
    1、创建一个本地仓库2、选择上传项目作为仓库目录3、将项目添加到缓冲区选中上传项目-->鼠标右键-->Git-->Add https://blog.csdn.net/m0_67677436/article/details/124676742 ......
  • paramiko遍历嵌套文件夹上传到linux服务器,并执行sh脚本
    场景:由于工作原因,开发打包后都要上传包到对应linux服务器,并执行对应shell脚本,替换包内配置文件,启动服务。换包频率过于频繁,因此需要实现一种不用打开xshell、xftp的方法,直接将包放在本地文件,双击exe运行所有操作,以节省时间,想到使用python的paramiko、pyinstaller模块实现。功......
  • 超大文件上传和断点续传的技术
    ​ 以ASP.NETCoreWebAPI 作后端 API ,用 Vue 构建前端页面,用 Axios 从前端访问后端 API,包括文件的上传和下载。 准备文件上传的API #region 文件上传  可以带参数        [HttpPost("upload")]        publicJsonResultuploadProject(I......