背包设计

 

 

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为当前这个物品的总数量。这样判断是否足够的时候就可以直接判断了。

posted @ 2019-09-27 14:19  sina小木木  阅读(288)  评论(0编辑  收藏  举报