游戏规则说明:
玩家进入游戏杀怪获得10分,被怪物击杀则扣5分,按照得分从高到低进行排序,排行榜展示前3名玩家信息。
游戏逻辑说明:
实现步骤:
1、变量库配置排行榜表,玩家信息表
在开发者工具 -> 变量库 -> 全局变量 ->新增变量 在弹窗中选择“排行榜”,“表”
创建排行榜:在全局变量中新增的排行榜中,将名称命名为“分数排行榜”,脚本引用名称设置为“rank_yang_001”, 后面lua脚本中将会使用它,进行获取云端排行榜数据。
创建玩家信息表:在全局变量中新增的表中,将名称命名为“玩家信息表”,脚本引用名称设置为“user_yang_001”,后面lua脚本中将会使用它,进行获取云端玩家信息数据。
在私有变量中创建一个数值私有变量用于存放得分,一个字符串私有变量用于存放排名名称
2、设置界面显示
创建2个界面,一个只有排行榜操作的按钮,此处使用奖杯代替;一个是包含具体排行榜的列表。如下图
3、设置游戏中的击杀触发器
在触发器中,创建一个击杀触发器,用于击杀了怪物,玩家的私有变量score增加 10分
4、开发者工具中新增脚本
在开发者工具中的脚本中,创建一个脚本,用于处理玩家进入游戏请求自己的数据,以及排行榜数据,定时30秒上传玩家数据,离开游戏,结束游戏时上传玩家数据的脚本。
详细的脚本及解释说明如下,开发者可以根据自己的情况修改脚本中的变量,以便实现自己的逻辑
--定义一个收集玩家的数组
local userAll ={}
local isOver = false
--用于记录当前进入的玩家迷你号
local current_enter_player_id = 0
--获取云服中存储的玩家用户信息回调
--ret 返回结果
--k 当前的迷你号
--v 当前的用户信息表中返回的内容,实例中的格式为: rank:2 score:120
local get_UserData_callback = function(ret,k,v)
if ret == true then
--拿到数据后,进行字符串分割
local myValue = v
print('当前获取到的用户信息' ..myValue )
local my_rank, my_score = string.match(myValue, 'rank:([0-9]+)score:([0-9]+)')
if(my_rank == 0 and my_rank == 0 )then
print('用户信息表中获得到的数据得分为0,初始值不处理')
return
end
--当前玩家的迷你号
local objid=tonumber(k)
local actionattr=3 --变量类型:数值
--score为变量库中命名的得分,开发者可以根据自己在变量库中设定的内容,进行修改此处
local msg="score"
--设置私有数值“score”的值为my_score
local score_result = VarLib2:setPlayerVarByName(objid,actionattr,msg,my_score)
if(score_result == ErrorCode.OK)then
print('设置私有数值“score”的值为my_score 成功~~~~')
else
print('设置私有数值“score”的值为my_score 失败~~~~')
end
local rank_actionattr=4 --变量类型:字符串
--rank为变量库中声明的排行榜,开发者可以根据自己在变量库中设定的内容,进行修改此处变量名
local rank_msg="rank"
--设置私有数值“rank”为my_rank
local rank_result = VarLib2:setPlayerVarByName(objid,rank_actionattr,rank_msg,my_rank)
if (rank_result == ErrorCode.OK)then
print('设置私有数值“rank”为my_rank 成功~~~~')
else
print('设置私有数值“rank”为my_rank 失败~~~~')
end
else
print('返回用户信息数据失败')
end
end
--请求用户信息表中的数据
local getUserTableInfo = function()
--user_yang_001 为变量库中 创建的 用户信息表的脚本索引名称,开发者根据自己的设定进行修改
local libvarname = 'user_yang_001'
--将当前进入游戏的玩家迷你号作为请求条件
local str_player_id = tostring(current_enter_player_id)
--获取玩家的用户信息
local ret = CloudSever:getDataListByKey(libvarname,str_player_id,get_UserData_callback)
if ret == ErrorCode.OK then
print('game 中请求玩家用户数据成功')
else
print("game 请求求玩家用户数据失败")
end
end
--获取自己的排名情况返回函数
--ret 返回结果
--k 是迷你号
--v 是得分
--ix 是排名
local get_my_data_callback = function(ret,k,v,ix)
if ret == true then
--获取数据成功
local actionattr=3 --变量类型:数值
--score为变量库中命名的得分,类型为数值
local msg="score"--变量名
--获取私有数值“数值score”的值,赋值给score_value
local numb_player_id = tonumber(k)
local actionattr2=4--变量类型:字符串
local msg2="rank"--变量名
local my_score = v
--设置当前玩家的私有变量:score得分数据,开发者可以根据自己的设定名称进行更改
local myscore_result = VarLib2:setPlayerVarByName(numb_player_id,actionattr,msg,my_score)
if myscore_result == ErrorCode.OK then
--设置成功
print('game 中 设置得分成功...')
else
--设置失败
print('game 中 设置得分失败...')
end
local actionattr_rank=4 --变量类型:字符串
--rank 为变量库中命名的排名,类型为字符
local msg_rank="rank" --变量名,可修改
--获取私有数值“rank”的值,为myrank
local myrank = ix
if ix == nil or ix == 0 then
myrank = "暂未上榜"
end
local myrand_sult = VarLib2:setPlayerVarByName(numb_player_id,actionattr_rank,msg_rank,myrank)
if myrand_sult == ErrorCode.OK then
--设置成功
print('设置排名成功...')
else
--设置失败
print('设置排名失败...')
end
else
--没有获取到信息,则从用户信息表中获取
getUserTableInfo()
end
end
--设置目前最新的本地数据到云端排行榜
--new_value: 当前得分
--pl_id: 当前玩家迷你号
local function setNewDataToCloud(new_value,pl_id)
local libvarname = 'rank_yang_001'
local player_id = tostring(pl_id)
local ret = CloudSever:setOrderDataBykey(libvarname,player_id,new_value)
if ret == ErrorCode.OK then
print('Game中 setNewDataToCloud设置排行榜值成功 玩家ID = ' .. player_id .. '当前得分: ' .. new_value)
else
print('Game中 setNewDataToCloud设置排行榜值失败')
end
end
--给用户信息表上传数据
--user_id 玩家迷你号
--user_rank 当前排行
--user_score 当前得分
local function setUserInfoDataCloud(user_id,user_rank, user_score)
--user_yang_001 为变量库中定义的用户信息表的 脚本引用名称,开发者可以根据自己的设定,修改此名称
local libvarname = 'user_yang_001'
--将数据组合成 rank:20 score:120 格式进行保存
local m_text = 'rank:'.. user_rank .. 'score:'.. user_score
local uid = tostring(user_id)
--调用接口,进行保存信息到云端的用户信息表中
local ret = CloudSever:setDataListBykey(libvarname,uid,m_text)
if ret == ErrorCode.OK then
print('setUserInfoDataCloud设置用户信息值成功 保存信息:' .. m_text)
else
print('设置用户信息值失败')
end
end
--离开和结束公共的设置玩家信息方法
--pl 为迷你号
local function setUserInfoAll(pl)
--如果传来的参数为空,则直接终止
if pl == nil then
return
end
local num_palyer_id = tonumber(pl)
local actionattr=3--变量类型:数值
--score为变量库中定义的得分,开发者可以根据自己的设定内容,进行修改此处变量名
local msg="score"
--获取私有数值“score”的值,赋值给value
print('Game中 setUserInfoAll中 玩家迷你号==' .. num_palyer_id )
local result,value = VarLib2:getPlayerVarByName(num_palyer_id,actionattr,msg)
if(result == ErrorCode.ok)then
print('Game中 setUserInfoAll中获取数据本地数据前,value==' .. value .. ' num_palyer_id==' .. num_palyer_id )
end
-- 获取私有排行榜
--rank为变量库定义的排行榜,开发者可以根据自己的设定内容,进行修改此处变量名
local msg2="rank"
local actionattr2=4 --变量类型:字符串
local result2,re_rank = VarLib2:getPlayerVarByName(num_palyer_id,actionattr2,msg2)
if (value ~= nil and re_rank ~= nil and value ~= 0 )then
--当前得分不是0,即不是初始值
--如果自己的本地数据比最后一名的得分都高,则将分数上传到排行榜服务器.
--如果分数小于最后一名的得分,则没有必要上传到服务器的排行榜,只需要在离开,或者游戏结束的时候将信息上传到用户信息中即可
setNewDataToCloud(value,pl)
local str_rank = re_rank
if(re_rank == "暂未上榜")then
str_rank = 0
end
--设置到用户信息表
if isOver == true then
--如果是离开游戏,或者游戏结束,则向服务器上传用户信息进行保存
setUserInfoDataCloud(pl,str_rank, value)
else
print('Game中 定时器中,不需要设置用户信息,设置了排行榜就可以了')
end
else
--这里就是初始化的时候,无需处理
print('Game中 获取本地私有变量数据都为空的时候,说明本地没有数据' )
end
end
--玩家进入游戏,获取排名,获取玩家信息,并设置本地数据rank,score
local function the_EnterGame_callback(e)
local pl = e.eventobjid
table.insert(userAll,pl)
--将当前进入玩家迷你号,临时存在变量中,后面回调函数中使用
current_enter_player_id = pl
--rank_yang_001 为设置的排行榜中脚本的引用名称,开发者可以根据自己的设定,进行修改此命名
local libvarname = 'rank_yang_001'
-- 请求当前进入玩家的排行榜数据
local my_ret = CloudSever:getOrderDataByKey(libvarname,pl,get_my_data_callback)
if my_ret == ErrorCode.OK then
print('请求自己的排行榜数据成功my_ret == ErrorCode.OK')
else
print("请求自己的排行榜数据失败")
--没有自己的排行榜,则需要去用户信息表中获取信息,进行展示
getUserTableInfo()
end
end
--{{{ 游戏开始后,时钟每(30ms)执行一次 ,向服务器排行榜进行上传玩家的数据
--[==[
--]==]
--}}}
local function dingShiSetDataForCloud(e)
local current = e.second
--定时30秒上传一次数据到云端
if(current ~= nil and current >=30 and (current- 30)%30==0) then
for kv, v in ipairs(userAll)do
setUserInfoAll(v)
end
end
end
--如果比赛结束,将玩家的信息保存到云端(排行榜和用户信息表)
local function thegame_end_callback()
isOver = true
for kv, v in pairs(userAll)do
setUserInfoAll(v)
end
end
local function the_TeaveGame_callback(e)
local pl = e.eventobjid
isOver = true
setUserInfoAll(pl)
--从本地数据中移除离开玩家的uin
table.remove(userAll,pl)
end
--向服务器提交数据
ScriptSupportEvent:registerEvent("Game.RunTime",dingShiSetDataForCloud)
--监听游戏结束的事件
ScriptSupportEvent:registerEvent([=[Game.End]=], thegame_end_callback)
--监听玩家离开事件
ScriptSupportEvent:registerEvent([=[Game.AnyPlayer.LeaveGame]=], the_TeaveGame_callback)
--监听玩家进入
ScriptSupportEvent:registerEvent([=[Game.AnyPlayer.EnterGame]=], the_EnterGame_callback)
5、UI编辑器中新增脚本
--用于存放当前点击的玩家迷你号
local current_click_player_id = 0
--用于存放获取到的云端数据
local cloud_data = nil
--昵称文本控件ID
--开发者可以修改为自己的排行榜界面中第一、二、三...名昵称称控件ID
local txt_name_id = {
[1] = '7124235295204530136_13',
[2] = '7124235295204530136_16',
[3] = '7124235295204530136_17',
}
--得分文本控件ID
--开发者可以修改为自己的排行榜界面中第一、二、三...名得分控件ID
local txt_score_id = {
[1] = '7124235295204530136_14',
[2] = '7124235295204530136_18',
[3] = '7124235295204530136_19',
}
--统一设置第一名~第三名的数据展示
--开发者可以再此处设置自己的排行榜界面数据
local function setNewDataForUI()
if(cloud_data ~= nil)then
local v_value = cloud_data
local uiid="7124235295204530136"
--将当前点击的玩家迷你号,转换为数值类型
local nu_current_player_id = tonumber(current_click_player_id)
for ix, v in ipairs(v_value) do
local v_score = v.v
local current_name = v.nick --这里为获取玩家昵称,开发者可以直接通过v.nick获取到存储在排行榜中对应玩家的昵称
Customui:setText(nu_current_player_id,uiid,txt_score_id[ix], v_score)
Customui:setText(nu_current_player_id,uiid,txt_name_id[ix], current_name)
end
end
end
--请求排行榜返回的数据
local get_now_data_callback = function (ret,value) -- 返回结果不一定有排名
if ret ~= false and value ~= nil then
--设置排行榜中的界面数据
--将获取到的数据进行临时存储,以便后面使用
cloud_data = value
--测试
setNewDataForUI()
--获取到了数据,开始将数据显示到界面层
--setUIData()
--有了数据后,显示排行榜界面
local result = Player:openUIView(current_click_player_id,'7124235295204530136')
end
end
--设置玩家自己的数据,展示在界面
local function setMy_Data_InLocal()
--当前需要设置的界面ID,7124235295204530136为排行榜所显示的界面ID,开发者根据自己的界面ID进行修改此处
local uiid="7124235295204530136"
--7124235295204530136_21 为排行榜中排行的控件ID,开发者根据自己的控件ID修改此处
local element_rank_id='7124235295204530136_21'
--7124235295204530136_24 为排行榜中玩家的名称的控件ID,开发者根据自己的控件ID修改此处
local element_nick_id='7124235295204530136_24'
local numb_player_id = tonumber(current_click_player_id)
--获取变量值
local actionattr=3--变量类型:数值
----score为变量库中设置的得分名称,开发者可以根据自己的设置进行修改此处
local msg="score"
--获取私有数值“score”的值,赋值给value
local myscore_result,value = VarLib2:getPlayerVarByName(numb_player_id,actionattr,msg)
if (myscore_result == ErrorCode.OK) then
print('请求玩家的得分数据正确,得分 ==' .. value)
else
print('请求玩家的得分数据出错')
end
local rank_actionattr=4 --变量类型:字符串
--rank 为变量库中设置排行名称,开发者可以根据自己的设置进行修改此处
local rank_msg="rank"--变量名
--获取私有数值“rank”的值,赋值给value
local my_rank_result,my_rank_value = VarLib2:getPlayerVarByName(numb_player_id,rank_actionattr,rank_msg)
if(my_rank_result == ErrorCode.OK) then
print('请求玩家的排名数据正确 my_rank_value==' .. my_rank_value)
else
print('请求玩家的排名数据出错')
end
--开始设置私有数据到界面
--7124235295204530136_27为界面层 得分的控件ID,开发者可以根据自己的界面,设置控件ID
local element_score_id='7124235295204530136_27'
local set_score_result = Customui:setText(numb_player_id, uiid, element_score_id, value)
if set_score_result == ErrorCode.OK then
print('UI脚本中设置自己的得分成功score_value=' .. value)
else
print('UI脚本中设置自己的 得分失败 score_value=' .. value)
end
--设置名字
local name_result, my_name = Player:getNickname(numb_player_id)
local set_name_result = Customui:setText(numb_player_id,uiid,element_nick_id, my_name)
if(set_name_result == ErrorCode.OK)then
print('脚本中,设置自己的名称成功my_name ==' .. my_name)
else
print('脚本中,设置自己的名称成功')
end
--设置排名
if(my_rank_value == 0 or my_rank_value == nil) then
my_rank_value = "暂未上榜"
end
local rank_set_result = Customui:setText(numb_player_id,uiid,element_rank_id, my_rank_value)
if rank_set_result == ErrorCode.OK then
print('UI脚本中 自己的排行榜设置正常 rank_value .. ' .. my_rank_value)
else
print('UI脚本中 自己的排行榜设置失败 rank_value .. ' .. my_rank_value)
end
end
--奖杯点击事件
--开发者可以设置自己的排行榜按钮事件
local function jiangbei_click(e)
local pl = e.eventobjid
--是不是自己设置的排行榜按钮,如果不是就直接不处理
--7124254390629128152_1 为界面层上排行榜按钮,用于点击,开发者根据自己的排行榜按钮进行修改此处
if( e.btnelenemt ~= '7124254390629128152_1')then
return
end
--当前点击的玩家迷你号,用于回调的时候使用
current_click_player_id = pl
-- rank_yang_001 为变量库中设置的排行榜表的,脚本接口引用名称,开发者根据自己的设置,修改此处
local libvarname = 'rank_yang_001'
--玩家进入游戏,请求从大到小排序的前3名的数据;如果需要从小到大的排序,则将-3修改为3.
--开发者可以根据自己的设置的排行榜一共是多少名来设置该数字,直接取到前面多少名。
local ret = CloudSever:getOrderDataIndexArea(libvarname,-3,get_now_data_callback)
if ret == ErrorCode.OK then
print('请求排行榜数据成功ret == ErrorCode.OK')
else
print("请求排行榜数据失败")
end
--设置进入的玩家自己的信息
setMy_Data_InLocal()
end
--监听点击事件
ScriptSupportEvent:registerEvent([=[UI.Button.Click]=],jiangbei_click)