在游戲開發中,背包是一個非常重要的功能。幾乎每個復雜點的游戲都會有背包的功能。不管是手游戲還是網頁游戲,不管是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中。
這樣就可以任意添加多個屬性數據,而不用修改數據庫各代碼了。物品背包就可以統一管理 了。
如果覺得有用,請稍微打賞一點吧