排行榜的制作

功能效果展示

 

运行环境

Win7,Win8,Win10

Reworld版本 体验版vc_redist.x64 运行环境

针对零基础读者的补充

下载安装 Reworld对应版本

ReWorld官网链接http://www.reworlder.com/

ReWorld创作者之家论坛:http://bbs.reworlder.com

下载后安装后注册账号打开空地图

下载安装 vc_redist.x64.rar运行环境

思路分析

排行榜根据玩家的某个数据进行排序,然后在客户端界面上进行显示。首先每个玩家都有自己的一个值,采用值对象的方式进行数据的记录和更改。将值对象加在玩家对象下即可实现每个玩家都有自己的数据记录,这种数据管理方式更为方便。在多人的情况下,将所有玩家的名称、数据值录入为一个表并使用排序算法进行排序。之后将排完序的表传输到所有客户端。在每个客户端根据收到的数据表,遍历显示玩家的名称和对应的排行数据值。玩家的数据如果是一直更新或者变化比较快,则一直重复数据传输和显示的过程。

金币的搭建

一、搭建过程

制作排行首先要有用来排行的数据,所以首先需要来制作一种数据。这里选用金币这种大众性游戏道具作为排行的数据。

1.1 在工作区中添加一个圆柱零件,通过缩放调成成金币形状,然后为零件增加贴花,这样就制作好了一个金币。如下图所示:

1.2 金币的功能是,在角色触碰后增加玩家的金币数。金币被触碰后会消失,一段时间后在原位置重新出现一个金币。金币需要漂浮在空中,并且有旋转效果,所以取消金币的重力,并且为金币增加一个保持角速度,调整保持角速度的属性让金币旋转起来。如下图所示:

1.3 玩家的金币数需要存储在玩家相关的对象上,才能实现每个玩家都有自己的金币。这里选择将数值用值对象的方式存储在玩家对象下。在玩家初始化->玩家初始化脚本->玩家操作脚本中,添加整数值对象,命名为金币数。如下图所示:

1.4 在金币下添加一个服务器脚本。如下图所示:

编写金币的脚本如下:

local coin = script.Parent
local delaytime = 10
coin.TriggerEnter:Connect(function(res)
        if res:IsClass("Avatar") then
            coroutine.start(function()
                local setpos  = coin.Position    --记录金币的位置
                coin:Destroy()
                local player = Players:GetPlayerByUserId(res.PlayerId)--通过角色的id获取玩家
                local coinshad = player.玩家脚本.玩家操作脚本.金币数--找到玩家下用来记录金币数的值
                coinshad.Value = coinshad.Value + 1--金币数增加
                local key = res.PlayerId.."coin"
                PlayerStoreData:SetValue(res.PlayerId, key, coinshad.Value)--将数值存储下来
                coroutine.wait(delaytime)
                local newcoin = ServerStorage.金币:Clone()
                newcoin.Position = setpos --将克隆的金币放在记录位置上
                newcoin.Parent = WorkSpace
            end)
        end       
end)

1.5 将制作好的金币在服务器存储中放入副本。如下图所示:

1.6 制作好了用来排行的数据,希望每次进入游戏时都可以保留上次的数据,所以需要将金币数存储为玩家的数据,使用玩家信息存储。在工作区或者服务器逻辑中创建服务器脚本,编写代码如下:

Players.PlayerAdded:Connect(function(Uid) --玩家加载时触发
    local player = Players:GetPlayerByUserId(Uid)
    local leaderstats  = player:WaitForChild("玩家脚本"):WaitForChild("玩家操作脚本"):WaitForChild("金币数")
    local key = Uid.."coin"
    if PlayerStoreData:GetValue(Uid, key) then--如果存储过金币值
        leaderstats.Value = PlayerStoreData:GetValue(Uid, key)
    else
        leaderstats.Value = 1
    end
    PlayerStoreData:SetValue(Uid, key, leaderstats.Value)--重新存储在服务器中的金币值
end)

 

二、补充说明

1.什么是工作区?

工作区中的对象是会被可视化显示到3D场景中的,并且只有在工作区中的对象才会发生物理交互。

服务对象。

不可创建。

不可复制。

不可删除。

2.什么是服务器脚本?

只会在服务器运行的Lua脚本代码,用于编写服务器逻辑。

3.为什么要使用服务器脚本?

排行版功能用于单人和多人等不同环境,所以采用通用的服务器脚本。

  1. 服务器脚本与客户端脚本不同,客户端执行的操作只有本地客户端,也就是玩家自己有效。而服务器执行的操作不仅针对单人有效,还针对与服务器相连的所有客户端同步生效。
  2. 在多人游戏中,如果这个对象的变化是针对一个人的,必须在客户端脚本进行编写;如果这个对象的变化是针对所有人的,那就必须在服务器脚本进行编写。
  3. 对于只能在客户端脚本修改的对象,如何让服务器知晓变化结果是很重要的。这里采用传统游戏的制作流程,也就是在客户端进行修改,把修改后的结果通过与服务器通信的方式发送到服务器,再通过服务器进行逻辑运算,把执行结果再同步给所有客户端。

排行榜界面的搭建

一、搭建过程

2.1在界面初始化下添加2D容器界面,命名为榜单,调整大小和位置后,添加滑动层控件,命名为排行。如下图所示:

2.2调整滑动层控件的大小和位置,去除水平滑动条。如下图所示:

2.3在滑动层控件的观察区->滑动内容下创建内容尺寸剪裁控件、竖直布局控件。创建图像控件来承载每

条排行要显示的数据,命名为排行框。如下图所示:

2.4 排行框下依次创建三个文本控件,横排摆放好,分别命名为榜单名次、榜单昵称、榜单金币。如下图所示:

2.5 界面制作完毕,下面来编写排行的脚本:

2.5.1 首先在编写服务器脚本,因为需要将数据显示,所以需要与客户端通信,在客户端存储中创建事件对

象,命名为排名更新,然后在服务器逻辑中添加服务器脚本。如下图所示:

编写服务器脚本如下:

local rankupdate = ClientStorage.排名更新
wait(3)
while true do ---一直运行排行程序
    local players = Players:GetAllPlayers()--获取玩家
    if #players > 0 then
        local playerdata = {}
        for _,player in pairs(players) do 
            if player.玩家脚本.玩家操作脚本.金币数 then
                local coinnum = player.玩家脚本.玩家操作脚本.金币数.Value
                local playerName = player.Name
                local rankdata = {}
                rankdata[1] = playerName
                rankdata[2] = coinnum
                table.insert(playerdata,rankdata)
            end
        end
        wait(0.1)
        if #playerdata > 1 then--玩家数量大于1,对玩家的金币数进行冒泡排序
            for i=1,#playerdata +1,1 do        
              for j=1,#playerdata-i,1 do
                if (playerdata[j][2]<playerdata[j+1][2]) then
                    local c=playerdata[j];
                    playerdata[j]=playerdata[j+1]
                    playerdata[j+1]=c
                end
              end        
            end
        end
        rankupdate:FireAllClient(playerdata)
    end
    wait(0.5)
end

2.5.2 在榜单中添加客户端脚本,如下图所示:

编写客户端脚本如下:

local rankupdate = ClientStorage.排名更新
local rankdata = GameUI:WaitForChild("榜单"):WaitForChild("排行"):WaitForChild("观察区"):WaitForChild("滑动内容")
local ranktext = rankdata:WaitForChild("排行框")
local function UpdateRank(table)
    coroutine.start(function()    
        local rankbox = rankdata:GetAllChild()
        if #rankbox -2 > #table  then--匹配排行框的数量,将多余的排行框删掉
            local length = #rankbox-#table+3
            for i = length,#rankbox,-1 do
                if rankbox[i] then
                    rankbox[i]:Destroy()
                end
            end
        elseif #rankbox -2 < #table then--匹配排行框的数量,排行框如果缺少就增加
            local slength = #table+2
            for i = 4,slength,1 do
                if not rankbox[i] then
                    local newrank = rankbox[3]:Clone()
                    newrank.Parent = rankdata
                end
            end
        end
        coroutine.wait(0.1)
        local currankbox = rankdata:GetAllChild()
        for i= 1,#table do--依次显示玩家排行
            currankbox[i+2].榜单名次.Text = i
            currankbox[i+2].榜单昵称.Text = table[i][1]
            currankbox[i+2].榜单金币.Text = table[i][2]
        end
    end)
end
rankupdate.ClientEventCallBack:Connect(UpdateRank)

3. 将游戏发布后测试。

二、补充说明

1.什么是2D容器界面?

2D容器界面是显示在玩家屏幕上的2DUI对象的主要存储对象。UI对象若要显示在编辑器中,必须作为容器控件的子级。

游戏运行后,存放在界面初始化StarterUI下的界面会复制到玩家界面下,只有在玩家界面GameUI下的界面才能在游戏中显示。

1.什么是滑动层控件?

滑动层控件是响应滑动的控件。

1.什么是图像控件?

图像控件显示非交互图像,经常用于装饰或者图标使用。

1.什么是文本控件?

文本控件显示非交互文本,经常用于标题或者标签使用。

1.什么是客户端脚本?

只会在客户端执行的脚本,执行的逻辑和表现也只会在本地客户端展现;可在以下几个文件目录下自动执行,客户端脚本在“工作区”下不会自动执行,需要放在以下对象里面:
1. 客户端最先加载 。
2. 工作区中的角色模型玩家初始化中的角色初始化脚本,在运行后会自动移动到角色模型下。
3. 玩家列表中的玩家玩家初始化中的玩家初始化脚本,在运行后会自动移动到玩家下
4. 玩家玩家界面界面初始化的脚本,在运行后会自动移动到玩家界面下。
5. 玩家的背包,例如工具里面的。

好了,接下来我们点击开始游戏就可以了,如果有什么问题或者有更好的实现方式,大家可以在下方积极交流讨论,我们也会参与进来和大家一起分享经验,期望能和大家共同进步~~

发布了35 篇原创文章 · 获赞 2 · 访问量 5834

猜你喜欢

转载自blog.csdn.net/weixin_41987154/article/details/102463231