Blink

纸上得来终觉浅,绝知此事要躬行

【转载】游戏服务器背包设计与实现

本文转载自:https://www.cnblogs.com/wgslucky/p/6079730.html

在游戏开发中,背包是一个非常重要的功能。几乎每个复杂点的游戏都会有背包的功能。不管是手游戏还是网页游戏,不管是SLG游戏,还是
ARPG
游戏,背包是必不可少的。背包的功能根据策划的要求,有的简单,有的复杂。以下我们就讨论一下几种游戏服务器背包的实现。

1,简单的游戏背包设计
简单的游戏背包到底简单到什么程度呢?那么这个游戏背包只是用来存放物品,不需要记录物品在背包中的位置,只需要记录物品的id和物品的数量即可。这样的游戏背包设计起来非常方便,在数据库中一个物品占一行即可,例如:
 《【转载】游戏服务器背包设计与实现》
当获得物品的时候,先查看这个物品是否已存在,如果不存在,则创建一个物品的对象,并插入到数据库,如果这个物品对象已存在,则只需要更新物品的数量即可。而在客户端显示的时候,是否可叠加,叠加上限是多少,由客户端自己去计算就可以了。使用物品的时候,只需要更新相应的数量即可。另外一个要求是要检测背包是否满了,我们只需要在初始化背包的时候记录一下背包的最大格子数和已使用的格子数就可以了。如果获得的物品在背包中不存在或叠加数已满,且没有剩余的格子则返回背包已满的提示。
 
2,有特殊物品的游戏背包设计
再复杂一些的背包是,有一些特殊的物品,比如装备,装备一般都是可以镶嵌宝石的,这样的话每个装备的id是不能相同的,即使是同一件名字一样的装备,它也要有一个唯一标识的
id
。这样就需要我们在放入物品的时候给物品生成一个唯一的
id
标识。生成唯一
id
的算法之前也介绍过,可以参考:
http://www.youxijishu.com/h-nd-147-0_35.html

游戏服务器生成全局唯一ID的几种方法)但是这些方法感觉用在生成背包物品唯一id上有点大材小用了。我们再提供一个方法,以供参考:

唯一id用一个
long
类型存储,
long
类型有
64
位,我们使用它的低
32
位存储策划配置的物品表中的物品
id
,高
32
用来记录每获得一个物品就自增加
1
的序列
order
,即

Int itemBaseId = 10001;//配置表中的物品
id

Int order = 1;//每获得一个物品这个序列自增加一,每个游戏背包都有自己的
order
,这样可以减少并发对
order
的增加。

Long itemUid = (((
long

order

<< 32

+
(long)itemBaseId


那么这个order怎么记录呢?这个
order
不用记录,那么当玩家退出后再进入游戏怎么得到这个
order
呢?我们在玩家登陆时第一次初始化游戏背包时,只需要从每个
itemUid
中拿出来每个物品的
order
,然后比较一个,得到最大的
order
做为起始
order
即可。这样可以从一个
itemBaseId
中获得一个
order:

Int order = itemUid >>> 32;
而那些可以叠加,不需要唯一id的物品,只需要把它们的配置
id
转化为
long
存储即可。

这样在内存中,我们可以把所有的物品放入一个Hashmap中,获得新物品和使用物品也不用遍历查找,速度很快。
3,带位置索引的游戏背包设计
更为复杂的背包,就是需要记录物品在背包中的位置索引。一般这样的游戏背包都会带物品的位置交换和整理功能。这种背包麻烦的是那些可以叠加的物品,因为同一个物品可能会占多个格子,而且还不连续。
我们还利用上面第二种背包的唯一id方式,不过这里会多增加一个物品在背包中的位置索引,唯一
id
还是
long
类型,而
long
是由:
orderId +
位置索引
+

物品配置
id
组成。

比如:高25位为
order
,中间
10
位为位置索引(一个背包有一千多个物品也差不多了),剩余的
29
位存储物品的配置
id
,这些位数可以根据实际需要自己调整。

在内存中,我们用一个数组来存储所有的物品,每个物品占一个格子,数组索引即物品的位置索引。当获取一个新物品的时候,如果这个物品是不可叠加的,直接遍历数组,找一个空位置,利用这个索引和order,物品的配置
id
组成一个唯一的
id
放入即可。如果这个物品是可叠加的,需要用数组的
0
索引到最大索引和物品配置
id
一一组成唯一
id
查找对应的物品对象,找到之后判断是否叠加已达最大数,如果已达到,直接找个空格子放入,如果没有达到,直接更新数量,更新完数理再判断是否达到最大叠加数,如果达到了,需要把多余的再占一个格子。

在使用物品的时候,客户端传过来这个物品的唯一id,我们就能拿到它的数组索引,直接操作即可。这里还有个问题,就是在使用前可能需要判断是否足够,如果只用一个数组的话,需要遍历数组,计算这个物品的总数量。如果不想遍历的话,可以另外再加一个
Hashmap
,存储一个可叠加物品的总数量,即
key
物品配置
id

value
为当前这个物品的总数量。这样判断是否足够的时候就可以直接判断了。

 
 
目前最常见的就是这三种类型的游戏背包了,我在网上还看到有的设计是一个物品要占多个格子,这样的背包做的时候再考虑怎么设计吧。
在游戏背包中,还可能遇到一种情况,就是有些特殊物品,比如某个宝石,当把这个宝石镶嵌到装备上,会额外增加这个装备的属性加成。但是具体增加多少,是在获取宝石的时候,根据一定算法随机出来的,而且影响几个属性也是随机的。一般来说一旦随机之后,这些属性加成就不会再变化了,也就是说不会再更新了。那么在背包中我们就可以增加一个字段,存储这些数据,这些数据可以是一个单独的对象,然后序列化为byte[]存储到数据库的
blob
中,可是把这个对象转为
json
直接到
text
中。

 《【转载】游戏服务器背包设计与实现》
 
这样就可以任意添加多个属性数据,而不用修改数据库各代码了。物品背包就可以统一管理
了。
点赞

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注