前言
我们一般制作选服列表都是从数据库到服务器,再从服务器到客户端。我们一般想要的效果,一般MMORPG类游戏的效果都是区服,也就是区和服,有几个大区,大区内有几个服务器,这样把几个服分为一组到一个区里。
流程
我们首先从客户端发起服务器区页签的请求附带上推荐服的列表,拿到页签信息后设置页签对应的UI,然后将推荐的服务器列表放在初始服务器列表UI上,然后我们点击页签UI后请求对应页签的服务器列表,服务器把对应的列表发回来显示在UI上。
实现
我们在实现选服时,主要的分区的逻辑都在服务器,在服务器上我们要定好几个服为一个区,通过这样的方式我们可以省去客户端的操作,降低客户端处理逻辑上的压力,那么首先我们就来制作如何分区。
分区:一般页签上都会有从xxx--xxx服,比如10服到20服等等,也有第几大区的。我们就先拿第一种情况来说,因为第二种情况相对简单。比如我们有40个服务器,每个区分10个服,那我们服务器页签上的显示就是“1-10服”,“11-20服”,“21-30服”,“31-40服”,所以我们设置一个页签序列,遍历所有服务器,每遍历10个,页签序列加1,并记录第一个和每个页签最后一个的名字,用字符串拼接起来就是我们的服务器页签的名字。
具体实现如下:
public
List
<
RetGameServerPageEntity
> GetGameServerPageList()
{
List
<
RetGameServerPageEntity
> lst =
new
List
<
RetGameServerPageEntity
>();
List
<
GameServerEntity
> gameServerLst = GetList(isDesc:
false
);
RetGameServerPageEntity
entity =
null
;
int
pageIndex = 1;
for
(
int
i = 0; i < gameServerLst.Count; i++)
{
//每10个服务器一组
if
(i % 10 == 0)
{
entity =
new
RetGameServerPageEntity
();
entity.PageIndex = pageIndex;
pageIndex++;
entity.Name = gameServerLst[i].Id.ToString();
lst.Add(entity);
}
if
((i + 1) % 10 == 0 || i == gameServerLst.Count - 1)
{
//
if
(entity !=
null
)
{
entity.Name +=
"-"
+ gameServerLst[i].Id.ToString() +
"服"
;
}
}
}
return
lst.OrderByDescending(p => p.PageIndex).ToList();
}
这样就将页签的数据放在了一个列表里,接下来就是将这些数据合理的显示在UI上。
然后每次点击页签都会出现对应的服务器组,所以我们还要实现获取服务器列表的方法,我们刚刚说过,如果刚打开服务器列表,页签都还未点击,那么显示哪组服务器列表呢?我们就在获取服务器列表时添加一个组,用来放推荐的服务器或者已经使用过的服务器,这样设置就比较合适了,实现如下:
using
Mmcoy.Framework;
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Web;
public
partial
class
GameServerCacheModel
{
public
List
<
RetGameServerPageEntity
> GetGameServerPageList()
{
List
<
RetGameServerPageEntity
> lst =
new
List
<
RetGameServerPageEntity
>();
List
<
GameServerEntity
> gameServerLst = GetList(isDesc:
false
);
RetGameServerPageEntity
entity =
null
;
int
pageIndex = 1;
for
(
int
i = 0; i < gameServerLst.Count; i++)
{
//每10个服务器一组
if
(i % 10 == 0)
{
entity =
new
RetGameServerPageEntity
();
entity.PageIndex = pageIndex;
pageIndex++;
entity.Name = gameServerLst[i].Id.ToString();
lst.Add(entity);
}
if
((i + 1) % 10 == 0 || i == gameServerLst.Count - 1)
{
//
if
(entity !=
null
)
{
entity.Name +=
"-"
+ gameServerLst[i].Id.ToString() +
"服"
;
}
}
}
return
lst.OrderByDescending(p => p.PageIndex).ToList();
}
public
List
<
RetGameServerEntity
> GetGameServerList(
int
pageIndex)
{
List
<
RetGameServerEntity
> retLst =
new
List
<
RetGameServerEntity
>();
if
(pageIndex == 0)
{
//推荐服务器 新区 玩家有账号的区
MFReturnValue
<
List
<
GameServerEntity
>> retValue = GetPageList(pageSize: 3, pageIndex: 1);
if
(!retValue.HasError)
{
List
<
GameServerEntity
> lst = retValue.Value;
for
(
int
i = 0; i < lst.Count; i++)
{
retLst.Add(
new
RetGameServerEntity
()
{
Id = lst[i].Id.Value,
RunStatus = lst[i].RunStatus,
IsCommand = lst[i].IsCommand,
IsNew = lst[i].IsNew,
Name = lst[i].Name,
Ip = lst[i].Ip,
Port = lst[i].Port
});
}
}
}
else
{
MFReturnValue
<
List
<
GameServerEntity
>> retValue = GetPageList(pageSize: 10, pageIndex: pageIndex, isDesc:
false
);
if
(!retValue.HasError)
{
List
<
GameServerEntity
> lst = retValue.Value;
for
(
int
i = 0; i < lst.Count; i++)
{
RetGameServerEntity
entity =
new
RetGameServerEntity
();
entity.Id = lst[i].Id.Value;
entity.RunStatus = lst[i].RunStatus;
entity.IsCommand = lst[i].IsCommand;
entity.IsNew = lst[i].IsNew;
entity.Name = lst[i].Name;
entity.Ip = lst[i].Ip;
entity.Port = lst[i].Port;
retLst.Add(entity);
}
}
}
return
retLst;
}
}
这样,服务器的页签和服务器列表都能获取到了,选服这一边也就基本完成了,剩下的就是客户端将获取的数据显示在UI上,不同的UI框架下的方法调用不一样,所以这里就不详细解释如何显示在UI上了。
有的时候,我们再次登录时要默认记录上一次登录的服务器,所以我们在对账户的数据库进行设计时,一定要加上上一次的服务器ID、名字以及时间,还有一些其他的项要根据情况自行设计,总之具体需求具体分析,选服主要就这么多逻辑,到时候还有的话再补充。