遊戲中的雙緩衝模式試驗

咱們假設一個遊戲,舞臺上有三個演員(A,B,C),每一個演員有一個本身面對的演員且成一個環(A面對B,B面對C,C面對A)。咱們能夠扇一個演員的耳光,這個演員無論誰扇的他,他都會去扇他面對的演員(因此咱們只要任意扇一我的,他們就會一直成環的扇下去)。數組

首先寫好演員的類:app

public class Actor
    {
        private string m_sName;      //名字
        private bool m_bIsSlapped;   //是否被扇
        private Actor m_facedActor;  //面對的演員

        public string Name
        {
            set { m_sName = value; }
            get { return m_sName; }
        }

        public Actor(string name)
        {
            m_sName = name;
            Reset();  //構造時設爲未被扇
        }

        public void Face(Actor actor)  //設置面對演員
        {
            m_facedActor = actor;
        }

        public void Reset()  //重置狀態
        {
            m_bIsSlapped = false;
        }

        public void Slap()  //被扇
        {
            m_bIsSlapped = true;
        }

        public bool WasSlapped()  //是否被扇
        {
            return m_bIsSlapped;
        }

        public void CheckStatus()  //檢查狀態,並做出輸出
        {
            if (WasSlapped())
            {
                Reset();
                Debug.Log(Name + " was slapped, so " + Name + " slapped " + m_facedActor.Name);
                m_facedActor.Slap();
            }
            else
            {
                Debug.Log(Name + " was not slapped, so nothing happens");
            }
        }
    }

而後是主類:code

public class DoubleBufferMain : MonoBehaviour
    {

        private Actor[] actors = new Actor[3];
        
        void Start()
        {
            Actor april = new Actor("April");
            Actor bella = new Actor("Bella");
            Actor charlie = new Actor("Charlie");
            april.Face(bella);
            bella.Face(charlie);
            charlie.Face(april);
            actors[0] = april;
            actors[1] = bella;
            actors[2] = charlie;

            april.Slap();  //扇A
            CheckStatus();
        }

        private void CheckStatus()
        {
            for(int i = 0; i < actors.Length; i ++)
            {
                actors[i].CheckStatus();
            }
            Invoke("CheckStatus", 1);  //每一秒檢測一下狀態
        }
    }

在這種狀況下每一個演員都會在本身被扇的同一幀扇下一個演員,他們會無限的互相傷害下去。blog

可是,若是咱們換一下他們在主類裏actors裏的順序,會發現輸出的結果會發生錯誤,有的演員會再被扇的同一幀作出反應,有的演員會再被扇的下一幀作出反饋。遊戲

只由於咱們改變了順序,兩次輸出的結果就不同了(第一次每幀都是3人扇人,第二次每幀有1個或者2我的扇人),顯然咱們的結果我應該由於僅僅由於咱們改變了數組中演員的順序就發生了改變,因此須要引入雙緩衝的模式。修改後的Actor類和主類:get

public class Actor
    {
        private string m_sName;      //名字
        private bool m_bIsCurrentSlapped;   //當前是否被扇
        private bool m_bIsNextSlapped;   //next是否被扇
        private Actor m_facedActor;  //面對的演員

        public string Name
        {
            set { m_sName = value; }
            get { return m_sName; }
        }

        public Actor(string name)
        {
            m_sName = name;
            m_bIsCurrentSlapped = false;
            m_bIsNextSlapped = false;
        }

        public void Face(Actor actor)  //設置面對演員
        {
            m_facedActor = actor;
        }

        public void Slap()  //被扇
        {
            m_bIsNextSlapped = true;
        }

        public void Swap()  //交換狀態
        {
            m_bIsCurrentSlapped = m_bIsNextSlapped;
            m_bIsNextSlapped = false;
        }

        public bool WasSlapped()  //是否被扇
        {
            return m_bIsCurrentSlapped;
        }

        public void CheckStatus()  //檢查狀態,並做出輸出
        {
            if (WasSlapped())
            {
                Debug.Log(Name + " was slapped, so " + Name + " slapped " + m_facedActor.Name);
                m_facedActor.Slap();
            }
            else
            {
                Debug.Log(Name + " was not slapped, so nothing happens");
            }
        }
    }
    
    public class DoubleBufferMain : MonoBehaviour
    {

        private Actor[] actors = new Actor[3];
        // Start is called before the first frame update
        void Start()
        {
            Actor april = new Actor("April");
            Actor bella = new Actor("Bella");
            Actor charlie = new Actor("Charlie");
            april.Face(bella);
            bella.Face(charlie);
            charlie.Face(april);
            actors[0] = april;
            actors[1] = bella;
            actors[2] = charlie;

            april.Slap();  //扇A
            CheckStatus();
        }

        private void CheckStatus()
        {
            for (int i = 0; i < actors.Length; i ++)
            {
                actors[i].CheckStatus();
            }
            for (int i = 0; i < actors.Length; i++)
            {
                actors[i].Swap();
            }
            Invoke("CheckStatus", 1);  //每一秒檢測一下狀態
        }
    }

此時無論咱們怎麼改變演員的順序,每幀得到的結果都是同樣的,而且每一個演員都會在本身被扇到的下一幀去扇下一我的。兩次結果都是:string

 

相關文章
相關標籤/搜索