天天看點

遊戲伺服器背包設計與實作

在遊戲開發中,背包是一個非常重要的功能。幾乎每個複雜點的遊戲都會有背包的功能。不管是手遊戲還是網頁遊戲,不管是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中。

這樣就可以任意添加多個屬性資料,而不用修改資料庫各代碼了。物品背包就可以統一管理了。

技術交流,歡迎留言,也可添加QQ交流群:66728073,197321069

繼續閱讀