位運算 游戲開發中的應用


位運算的定義:

通俗點說,位運算就是對一個整數在計算機中二進制進行操作。
位運算的原理是很簡單的,百度百科里就能找到它的一些基本的用法,以及相關的運算符號。
大部分剛剛進入到游戲行業里的程序員,你問他什么叫位運算,他都懂,但實際中往往卻不記得去使用它。
任何一個整數都可以用二進度的方式來表示的,不同類型的整數它的位數的長度也不一樣,INT8或者char是由8個2進度位表示,INT16或者short是由16個2進度位表示,INT32是由32位狀態位表示。

 

位運算在游戲中的應用

往往,在游戲開發中做位運算的時候,我關注的主要是某一位的值是0,還是1,而並不是去關注這個整數的值是多少。
比如:00100010,這個8位的整數從右到左,它的第一位為0,第二位為1,第三位為0,第六位為1。
怎么知道這個整數的某一位的值,怎樣把一個整數的某一位由0變為1或由1變為0呢,看以下代碼:

//檢查state的第pos位是否為1
int bitCheck(int state, int pos)
{
    return state & 1<< pos - 1;
}

//將state的第pos位的值設為1
int bitAdd(int state, int pos)
{
    return state | (1 << (pos - 1));
}

//將state的第pos位的值設為0
int bitDel(int state, int pos)
{
    return state & (~(1 << (pos - 1)));
}

 

位運算往往在游戲用來記錄一些狀態,一個32位的整數,就能記錄32種狀態,並且只需要一個int就夠了。

例子:

假設一個NPC有以下幾種狀態,行走狀態,站立狀態,普通攻擊狀態,技能攻擊狀態,根據這個NPC的不同狀態,客戶端需要播放不同的動作。
很多同學馬上聯想到的是用枚舉,然后就開始寫代碼,很快就把程序寫好了。
這個時候,策划又提了一個新的需求,說攻擊的時候可能會產生爆擊,爆擊的時候普通攻擊和技能攻擊都需要有不同的表現。
然后這個同學想了想,於是加了一個BOOL來記錄這次攻擊是否產生爆擊,於是很快又把代碼寫好了。
策划又提一個需求,攻擊的時候還有命中。
於是又加了一個BOOL來記錄命中。
如果還有BUFF效果,這就坑爹了!

真的是大部分剛招進來的同學都是這么干的,一個模塊萬多個BOOL,關鍵很氣人的是這些BOOL還用一個INT8的方式一個一個地發往客戶端。

還遇到過這么干的,把攻擊且爆擊狀態,技能攻擊爆擊狀態,記錄成一個新的枚舉值。

解決方案:

用狀態位來記錄NPC的狀態,一個8位的整數即可記錄8種狀態,16位,32位就可以記錄更多的狀態。

//偽代碼
#define STATE_ATTACK 1 //普通攻擊
#define STATE_SKILL 2 //技能攻擊
#define STATE_DODGE 3  //爆擊
#define STATE_HIT 4  //命中

INT8 state = 0; //默認無任何狀態

state = bitAdd(state,STATE_ATTACK); //發起普通攻擊
state = bitAdd(state,STATE_HIT);  //命中目標
state = bitAdd(state,STATE_DODGE); //產生爆擊

if(bitCheck(state,STATE_HIT) == 0) //如果未命中目標
{
}

 

位運算 與 類似枚舉 的操作,主要的區別在於位運算可以用一個變量來記錄多種狀態共同存在的情況。

 

位運算在游戲開發領域是用到的很多的,比如在游戲中的獎勵系統,游戲中有很多種獎勵,每日登錄,排位賽,競技場,公會獎勵,在線獎勵,簽到獎勵等,策划需要每一種獎勵可以領取的時候,客戶端在相應的功能按鈕需要開啟光效表現來引起玩家注意,讓玩家知道某某獎勵現在是可以領取的。我看到很多開發人員都是客戶端把所有系統的數據都拿到了,然后再根據數據的相應情況來決定是否讓這個按鈕開啟光效。其實我們只需要用一個整數,在服務器端算好每一種獎勵是否可以被領取,客戶端收到這個數據后,根據每一個狀態的情況來開啟相應的光效,讓玩家點擊進入相應的系統的時候,才去拿相應的數據。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM