使用BitMap实现游戏任务,成就的信息同步

来源:互联网 发布:淘宝卖衣服需要什么证 编辑:程序博客网 时间:2024/06/08 18:32

前言:

现在手游一般都有类似于任务,成就的系统。我们假设成就有很多很多条, 那服务器和客户端之间同步状态的流量会比较大。 有什么好的办法能减少流量消耗呢,我们可以使用BitMap。


正文

BitMap
  • 定义:用一个bit位来标记某个元素对应的Value, 而Key即是该元素。
  • 优点:
    • 运算效率高(不需进行比较和移位)
    • 占用内存少(0和1都是油意义的)
  • 缺点:
    • 所有的数据不能重复。
  • 用途:可进行数据的快速查找,判重,删除
  • 适用范围:一般来说数据范围是int的10倍以下
  • 对于成就系统来说,成就是有自己的id,所以肯定不会重复。

  • 实现思路:

    • 总数为N, 所需内存空间:int [1 + N/32]
    • 存入时:
      • 十进制数0-N对应的在数组a中的下标:index_loc = N / 32
      • i >> 5 等价 i / 32
      • 求十进制数0-N对应的bit位: bit_loc = N % 32
      • n & 31 等价 n % 32
  • 代码实现:

class BitMap{    const int BITSPERWORD = 32;    const int SHIFT = 5;    const int MASK = 0x1F; // 31    const int N = 10000000;    private int[] a;    //申请内存的大小      public BitMap() {        a = new int[1 + N / BITSPERWORD];     }    public BitMap(int totalCount) {        a = new int[1 + totalCount / BITSPERWORD];    }    public void SetBit(int i)    {        a[i >> SHIFT] |= (1 << (i & MASK));    }    //Clear 初始化所有的bit位为0      public void Clear(int i)    {        a[i >> SHIFT] &= ~(1 << (i & MASK));    }    //test 测试所在的bit为是否为1      public bool GetIsTrue(int i)    {        int index = i & MASK;        return (a[i >> SHIFT] & (1 << index)) != 0 ;    }}
  • 使用例子:
int count = 10000;int randomCount = 10;BitMap bitMap = new BitMap(count);Random random = new Random();for (int i = 0; i < randomCount; i++){    int num = random.Next(count);    Console.WriteLine(num);    bitMap.SetBit(num);}Console.WriteLine("");Console.WriteLine("");Console.WriteLine("");for (int i = 0; i < count; i++){    if (bitMap.GetIsTrue(i))    {        Console.WriteLine(i);    }}Console.ReadKey();
  • 效果:

  • 成就系统的设计思路:
    • 所有的成就信息都是表格配置数据,包括奖励和达成条件。
    • 当检测某个成就是否达成时, 客户端和服务端都是实时去算的。
    • 成就ID配置时可以有个偏移值,比如说10000,而SC真正通信时id可以减去这个偏移值,从0开始。
    • 使用BitMap记录下成就奖励是否领取, 同步这个状态,配合客户端本地计算,就能得到某个具体成就的状态:待达成,已达成还是已领取。

扩展:

https://github.com/lemire/javaewah
bitmap的开源实现有EWAH,采用RLE(Run Length Encoding)压缩,很好地解决了存储空间的浪费。


如有错误,欢迎指出。

email:dxmdxm1992#gmail.com

blog: http://blog.csdn.net/david_dai_1108

阅读全文
0 0
原创粉丝点击