程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> [C++基礎]位運算 游戲開發中的應用

[C++基礎]位運算 游戲開發中的應用

編輯:C++入門知識

[C++基礎]位運算 游戲開發中的應用


位運算的定義:通俗點說,位運算就是對一個整數在計算機中二進制進行操作。
任何一個整數都可以用二進度的方式來表示的,不同類型的整數它的位數的長度也不一樣,INT8或者char是由8個2進度
位表示,INT16或者short是由16個2進度位表示,INT32是由32位狀態位表示。

位運算在游戲中的應用

往往,在游戲開發中做位運算的時候,我關注的主要是某一位的值是0,還是1,而並不是去關注這個整數的值是多少。
比如:00100010,這個8位的整數從右到左,它的第一位為0,第二位為1,第三位為0,第六位為1。

//檢查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) //如果未命中目標
{
}

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

位運算在游戲開發領域是用到的很多的,比如在游戲中的獎勵系統,游戲中有很多種獎勵,每日登錄,排位賽,競技場,公會獎勵,在線獎勵,簽到獎勵等,策劃需要每一種獎勵可以領取的時候,客戶端在相應的功能按鈕都需要光效表現來引起玩家注意,讓玩家知道某某獎勵現在是可以領取的。

我看到很多開發人員都是客戶端把所有系統的數據都拿到了,然後再根據數據的相應情況來決定是否讓這個按鈕開啟光效。其實我們只需要用一個整數,在服務器端算好每一種獎勵是否可以被領取,客戶端收到這個數據後,根據每一個狀態的情況來開啟相應的光效,讓玩家點擊進入相應的系統的時候,才去拿相應的數據。

位運算常用的是狀態位、權限位、自定義加密

&位運算符號的應用

清零 清零:快速對某一段數據單元的數據清零,即將其全部的二進制位為0。例如整型數a=321對其全部數據清零的操作為a=a&0x0。 (321=0000 0001 0100 0001) &0=0000 0000 0000 0000= 0000 0000 0000 0000
獲取一個數據的指定位 例如獲得整型數a=321的低八位數據的操作為a=a&0xFF。(321=0000 0001 0100 0001) & (0xFF = 0000 0000 1111 11111)
= 0000 0000 0100 0001
獲得整型數a=321的高八位數據的操作為a=a&0xFF00。(321=0000 0001 0100 0001) & (0XFF00=1111 1111 0000 0000)
= 0000 0001 0000 0000
保留數據區的特定位 例如獲得整型數a=321的第7-8位(從0開始)位的數據操作為: a=a&110000000
(321=0000 0001 0100 0001) & (384=0000 0001 1000 0000)=0000 0001 0000 0000

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved