国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

Game中的狀態(tài)機(jī)

2019-11-17 02:22:52
字體:
供稿:網(wǎng)友

Game中的狀態(tài)機(jī)

我相信大多數(shù)博友都會玩游戲

玩游戲,牽涉到狀態(tài)包含 登陸,正常,死亡,復(fù)活,下線,

在上面狀態(tài)的基礎(chǔ)上。同時包含 站立,走動,跑動,不可移動施法狀態(tài),

              戰(zhàn)斗狀態(tài),

通常這是三個不同的分組。也就說可以同時存在的狀態(tài)和不可同時存在的狀態(tài)。

通常情況下也許你會這么定義,

//分組1public bool 登陸 = false;public bool 死亡 = false;public bool 復(fù)活 = false;public bool 下線 = false;public bool 正常 = false;public bool 打坐 = false;//分組2public bool 站立 = false;public bool 走動 = false;public bool 跑動 = false;public bool 施法 = false;//分組3public bool 戰(zhàn)斗 = false;

這種情況下,判斷就變得很復(fù)雜,因?yàn)榇嬖冢瑫r成立和非同時成立的狀態(tài),

例如,戰(zhàn)斗的同時可以走動,也可以跑動,或者技能施法

但是在打坐,下線,死亡等狀態(tài)的時候既不能走動,也不能戰(zhàn)斗也不能施法。

這樣一來一去,判斷的if else 會多的,讓你頭痛欲裂的吧。

或許你會想到,是要枚舉,因?yàn)槊杜e提供位運(yùn)算,提供Enum.HasFlag()方法來判斷是否存在值

public enum Stauts{    //分組1    空值,    登陸,    死亡,    復(fù)活,    下線,    正常,    打坐,    //分組2    站立,    走動,    跑動,    施法,    //分組3    戰(zhàn)斗,}

查看一下使用方式

Stauts sValue = Stauts.登陸;sValue = sValue | Stauts.站立;if (sValue.HasFlag(Stauts.站立)){    Console.WriteLine("存在站立狀態(tài)");}

輸出:

但是,繼續(xù)測試一下

這樣看出來了,我并沒有設(shè)置復(fù)活狀態(tài),但是卻存在復(fù)活狀態(tài)~!

探究得明原因,是因?yàn)槲换颍ǎ?運(yùn)算, 按位或(|)表示相對應(yīng)的每位至少有一個為1,則結(jié)果為1,只有兩個都為0,結(jié)果才為0.

所以,我們應(yīng)該設(shè)置枚舉值的不同值;

為了更直觀的查看運(yùn)算方式,我們輸出枚舉值的二進(jìn)制值,

public static void Show(Stauts value){    string log = ("結(jié)果:" + ((long)value).ToString().PadLeft(10, ' ') + " -> " + Convert.ToString(((long)value), 2).PadLeft(64, '0'));    Console.WriteLine(log);}

查看一下

我們看到

Stauts.登陸 | Stauts.死亡 位或計算方式,結(jié)果值。

這些明白了,那就是枚舉的值,定義不合法,

public enum Stauts{    //分組1    空值 = 0,    登陸 = 1,    死亡 = 2,    復(fù)活 = 4,    下線 = 8,    正常 = 10,    打坐 = 20,    //分組2    站立 = 40,    走動 = 80,    跑動 = 100,    施法 = 200,    //分組3    戰(zhàn)斗 = 400,}

輸出結(jié)果

這下,沒有了復(fù)活狀態(tài)。這樣判斷,會減少一半,

可還是出現(xiàn)一個問題。那就是分組問題,也就說,死亡狀態(tài)和復(fù)活狀態(tài)不能同時存在,

死亡狀態(tài)和跑動狀態(tài)也不可能同時存在

那么我們在想,枚舉值的能不能分組呢?

可惜C#下面枚舉值,只能使用整型的基礎(chǔ)類型。

沒辦法只能另辟蹊徑:

    public class EnumStatus    {        public long Value { get; PRivate set; }        public long GroupValue { private set; get; }        public EnumStatus(long value, long group)        {            this.Value = value;        }    }

接下來我們設(shè)置一組常量

        // 0x000000一旦竟然這組狀態(tài)忽略一切狀態(tài)        public static EnumStatus Status0_空值 = new EnumStatus(0, 0x000000);        public static EnumStatus Status0_登陸 = new EnumStatus(1 << 0, 0x000000);        public static EnumStatus Status0_死亡 = new EnumStatus(1 << 1, 0x000000);        public static EnumStatus Status0_復(fù)活 = new EnumStatus(1 << 2, 0x000000);        public static EnumStatus Status0_下線 = new EnumStatus(1 << 3, 0x000000);        public static EnumStatus Status0_正常 = new EnumStatus(1 << 4, 0x000000);        public static EnumStatus Status1_打坐 = new EnumStatus(1 << 5, 0x000000);        //移動組狀態(tài) 4個狀態(tài)值        public static EnumStatus Status1_站立 = new EnumStatus(1 << 6, 0x00000f);//4位一組        public static EnumStatus Status1_走動 = new EnumStatus(1 << 7, 0x00000f);//        public static EnumStatus Status1_跑動 = new EnumStatus(1 << 8, 0x00000f);//        public static EnumStatus Status1_施法 = new EnumStatus(1 << 9, 0x00000f);// 無法移動的施法        //戰(zhàn)斗狀態(tài) 這組只有一個狀態(tài)值        public static EnumStatus Status2_戰(zhàn)斗 = new EnumStatus(1 << 10, 0x000010);//

后面的分組值,的由來是

0x00000f 二進(jìn)制 0000,1111,

0x000010 二進(jìn)制 0001,0000,這樣就成功分組了

上面分組代碼代碼有錯誤:

        // 0x000000一旦竟然這組狀態(tài)忽略一切狀態(tài)        public static EnumStatus Status0_空值 = new EnumStatus(0, 0x000000);        public static EnumStatus Status0_登陸 = new EnumStatus(1 << 0, 0x000000);        public static EnumStatus Status0_死亡 = new EnumStatus(1 << 1, 0x000000);        public static EnumStatus Status0_復(fù)活 = new EnumStatus(1 << 2, 0x000000);        public static EnumStatus Status0_下線 = new EnumStatus(1 << 3, 0x000000);        public static EnumStatus Status0_正常 = new EnumStatus(1 << 4, 0x000000);        public static EnumStatus Status1_打坐 = new EnumStatus(1 << 5, 0x000000);        //移動組狀態(tài) 4個狀態(tài)值        public static EnumStatus Status1_站立 = new EnumStatus(1 << 6, 0x0003c0);//4位一組        public static EnumStatus Status1_走動 = new EnumStatus(1 << 7, 0x0003c0);//        public static EnumStatus Status1_跑動 = new EnumStatus(1 << 8, 0x0003c0);//        public static EnumStatus Status1_施法 = new EnumStatus(1 << 9, 0x0003c0);// 無法移動的施法        //戰(zhàn)斗狀態(tài) 這組只有一個狀態(tài)值        public static EnumStatus Status2_戰(zhàn)斗 = new EnumStatus(1 << 10, 0x000400);//

由于前面的分組0占用了6位,

所以分組應(yīng)該改為,

也許看到這里你需要一定的位運(yùn)算知識了;

接下來我在介紹一下

位運(yùn)算的操作符

//// 按位異或(^)比較特殊,它比較的是如果兩個不同則值為1(如:(1、0)(0、1)),相同則為0(如:(1、1)(0、0))。//// 按位與(&)表示相對應(yīng)的兩位必須都為1,結(jié)果才為1,否則為0//// 按位或(|)表示相對應(yīng)的每位至少有一個為1,則結(jié)果為1,只有兩個都為0,結(jié)果才為0.//// 按位取反~ 運(yùn)算符對操作數(shù)執(zhí)行按位求補(bǔ)運(yùn)算,其效果相當(dāng)于反轉(zhuǎn)每一位。

修改一下計算值

    public class EnumStatus    {        public long Value { get; private set; }        public long GroupValue { private set; get; }        public EnumStatus(long value, long group)        {            this.Value = value;        }        public bool HasFlag(EnumStatus status)        {            return (this.Value & status.Value) != 0;        }        public void Show()        {            string log = ("結(jié)果:" + this.Value.ToString().PadLeft(10, ' ') + " -> " + Convert.ToString(this.Value, 2).PadLeft(64, '0'));            Console.WriteLine(log);        }        public static EnumStatus Operator |(EnumStatus statusLeft, EnumStatus statusRight)        {            statusLeft.Value = statusLeft.Value & statusRight.GroupValue | statusRight.Value;            return statusLeft;        }        public static EnumStatus operator &(EnumStatus statusLeft, EnumStatus statusRight)        {            statusLeft.Value = statusLeft.Value & (~statusRight.Value);            return statusLeft;        }    }

上面重載的 位域算法也是有問題的。

public static EnumStatus operator |(EnumStatus statusLeft, EnumStatus statusRight)        {            if (statusRight.GroupValue==0)//當(dāng)分組為0的時候清除所有狀態(tài)            {                statusLeft.Value = statusLeft.Value & (statusRight.GroupValue) | statusRight.Value;            }            else            {//當(dāng)分組不為零                statusLeft.Value = statusLeft.Value & (~statusRight.GroupValue) | statusRight.Value;            }            return statusLeft;        }

這下才是正確的結(jié)果

這下是不是很輕松的解決了這一系列的狀態(tài)問題呢?包括各種同時存在和不同時的存在的狀態(tài)~!

但是這也有一個弊端,那就是值只有64個,也就是64個狀態(tài),,雖然存在分組。但是每一個分組的值都必須不同才行。

不知道,各位看官還有么沒有更好的辦法????

==============================================================================================

java版本的

java的枚舉是可以自定義的這方面比較方便

但是java沒有運(yùn)算符重載,

enum EnumStatus {    //0x000000一旦竟然這組狀態(tài)忽略一切狀態(tài)    Status0_空值(0, 0x000000),    Status0_登陸(1 << 0, 0x000000),    Status0_下線(1 << 1, 0x000000),    Status0_正常(1 << 2, 0x000000),    //移動組狀態(tài)    Status1_走動(1 << 3, 0x00000f),    Status1_跑動(1 << 4, 0x00000f);    Long value = 0L;    Long group = 0L;    private EnumStatus(long value, long group) {        this.value = value;        this.group = group;    }    public boolean hasFlag(EnumStatus status) {        return (value & (~status.value)) != 0;    }    public void addStatus(EnumStatus status) {        value = value & status.group | status.value;
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 图木舒克市| 东山县| 突泉县| 玛曲县| 炎陵县| 长宁区| 瑞丽市| 南康市| 通道| 临洮县| 柞水县| 廊坊市| 青岛市| 罗山县| 渭南市| 定兴县| 娱乐| 图木舒克市| 贺州市| 台江县| 张家界市| 武隆县| 舞钢市| 昭苏县| 郎溪县| 日土县| 洪泽县| 莱阳市| 辉县市| 当涂县| 襄城县| 铜山县| 图木舒克市| 沁阳市| 晋城| 新津县| 乐亭县| 万安县| 荆门市| 闻喜县| 郓城县|