测试使用的是Unity5.6.5版本
对于一些特殊的场合,我们经常需要对一系列的状态设置开关,今天刚好在做游戏中Debuff状态的开发,使用了枚举的位运算实现该功能,这里做一些总结,以便自己查阅复习。
首先说一下先导的知识点--枚举类型的位运算。枚举类型的位运算在这种场合可以起到非常方便的作用。
枚举的位运算和一般的枚举定义有一定的不同,主要是定义时需要将每一项的值与二进制中的每一位相对应,换成十进制即设为2的整数幂,即1,2,4,8等等,
public enum MyEnum
{
Enum1 = 1, //1
Enum2 = 1 << 1, //2
Enum3 = 1 << 2, //4
Enum4 = 1 << 3 //8
}
这样我们就可以通过位运算实现一系列的功能了:
1、多个枚举的组合
//转换到十进制的话就是直接将两项相加(int)Enum1+(int)Enum2;
MyEnum curMyEnum = Enum1 | Enum2;
2、删除某一项
//转换到十进制的话就是直接将当前的枚举组合减去要删除的项(int)MyEnum-(int)Enum1;
curMyEnum ^= Enum1;
curMyEnum &= ~Enum2;
3、判断是否包含某一项,与位运算的结果>0表示组合中包含该项,=0表示不包含
(curMyEnum & Enum1) > 0
下面是正文
接下来就是实现要做的功能,实现各种Debuff状态组合
这里直接使用十进制,直观方便理解
代码中添加了很多注释,就不做其他说明了
/// <summary>
/// 状态位设置,设置了以下几种状态
/// </summary>
public enum DebuffStateTest
{
Normal = 0, //正常
Poison = 1, //中毒
Sleep = 2, //催眠
Paralyze = 4, //麻痹
Blind = 8, //失明
}
//这里直接在Unity上面添加了一个按钮方便测试
public class TestBitOperate : MonoBehaviour
{
DebuffStateTest curDebuff; //当前状态
Button btnTest; //开始测试的按钮,Unity端就不显示了,这里只讨论代码逻辑
// Use this for initialization
void Start()
{
//注册按钮,不懂Unity的可以忽略,只需要知道点击按钮就执行Test()函数就行
btnTest = GameObject.Find("btnTest").GetComponent<Button>();
btnTest.onClick.AddListener(()=>
{
//点击测试按钮开始执行测试
Test();
});
}
//测试函数
public void Test()
{
//添加麻痹和失明状态
Debug.Log("受死吧!我要麻痹你的神经,戳瞎你的眼睛!");
AddDebuff((int)DebuffStateTest.Paralyze+(int)DebuffStateTest.Blind);
//显示当前的状态
StateTest();
Debug.Log("。。。。。。。我是帅气的分割线。。。。。。。");
//消除中毒和麻痹状态
Debug.Log("来喝我一口毒奶,治愈你的中毒和麻痹状态,如果不存在该种状态不会有任何效果");
ClearDebuff((int)DebuffStateTest.Poison + (int)DebuffStateTest.Paralyze);
//显示当前的状态
StateTest();
}
/// <summary>
/// 添加Debuff
/// </summary>
/// <param name="debuffId">可以是一种或几种状态的叠加,如中毒+催眠,则debuffId=1+2=3</param>
public void AddDebuff(int debuffId)
{
//debuffId和curDebuff的反码做与运算,实际上是要检查要添加的这些状态位是否不存在,是则添加
int addDebuff = (debuffId & (~(int)curDebuff));
//给当前状态添加Debuff,只要把需要添加的状态直接和curDebuff相加
curDebuff = (DebuffStateTest)((int)curDebuff + debuffId);
}
/// <summary>
/// 消除Debuff
/// </summary>
/// <param name="debuffId">同上</param>
public void ClearDebuff(int debuffId)
{
//debuffId和curDebuff做与运算,实际上是要检查要消除的这些状态位是否存在,存在则消除
int clearDebuff = (debuffId & (int)curDebuff);
//消除Debuff,只需要直接用curDebuff减去要消除的状态
curDebuff = (DebuffStateTest)((int)curDebuff-clearDebuff);
}
/// <summary>
/// 用来测试的函数,拿当前状态和每一种状态做与运算,看是否存在该种状态
/// </summary>
public void StateTest()
{
if ((curDebuff & DebuffStateTest.Poison) == DebuffStateTest.Poison)
{
Debug.Log("你中毒了");
}
if ((curDebuff & DebuffStateTest.Sleep) == DebuffStateTest.Sleep)
{
Debug.Log("你被催眠了");
}
if ((curDebuff & DebuffStateTest.Paralyze) == DebuffStateTest.Paralyze)
{
Debug.Log("你被麻痹了");
}
if ((curDebuff & DebuffStateTest.Blind) == DebuffStateTest.Blind)
{
Debug.Log("你失明了");
}
}
}
运行结果:
完结撒花!!!