close

這次來比較兩個有趣的東西:StrategyDecorator
同樣是巢狀邏輯判斷式的寫法
改法不止限於上次提到的Composed

StrategyDecorator也是不錯的選擇

艾倫史密斯在互動元件那邊做了一個示範
詳細內容我不贅述了,有興趣可以去找找看
總之是在處理主角吸上互動元件後
怎麼對主角施予重力和建立Joint
讓主角不會掉下來
,並且可以做有限制的移動
第一個碰到的問題是
當主角踩在互動元件上面的那一瞬間
要怎麼去判斷他踩到的是什麼呢?

想當然爾,碰撞會有碰撞訊息
於是以下的Code就會出現:
switch (pMsg->m_uiType)
{
    case MST_TRIGGER_COLLISION:
    {
        ksMsgActor *pObj = pMsg->m_pTouchAI;
        if ( NiIsKindOf(ksObjA, pObj) ||
NiIsKindOf(ksObjB, pObj) )
            // 建立第一種Joint
        else if
( NiIsKindOf(ksObjC, pObj) || NiIsKindOf(ksObjD, pObj) )
            // 建立第二種Joint
        else if ( NiIsKindOf(ksObjE, pObj) )
            // 建立第三種Joint
        else if ( NiIsKindOf(ksObjF, pObj) )
            // 建立第四種Joint
        break;
    }
}


很好,決定了Joint的種類
接下來主角開始移動,但是磁力物件千百種
有的直有的彎,怎麼知道主角該不該轉彎呢?

主角吸在物件上面,所以會有Trigger的訊息
於是下列的程式碼出現:

switch (pMsg->m_uiType)
{
    case MST_TRIGGER_ON_STAY:
    {
        ksMsgActor *pObj = pMsg->m_pTouchAI;
        if ( NiIsKindOf(ksObjA, pObj) ||
NiIsKindOf(ksObjB, pObj) )
            // 走在直線型的物件上
        else if
( NiIsKindOf(ksObjC, pObj) || NiIsKindOf(ksObjD, pObj) )
            // 走在圓弧形的物件上
        break;
    }
}


如果你以為艾倫史密斯是這種寫法,那你就錯了
要知道,他可是史密斯
寫法當然要不一樣,所以他採取的是
Strategy
一種抽象到不行的寫法,害我每次Trace Code都很痛苦...
不過這真的是物件抽象的極致
搞到最後他也不知道是碰到哪一個種類的物件~XD

使用Strategy,可以大大減少主角這邊判斷的機制
我只需要呼叫統一的介面,就可以輕鬆吸上磁力物件
就像這樣:

ksTerrainDestKit* pKit = (ksTerrainDestKit*)pAI->GetKit(TERRAIN_DEST_KIT);
pKit->CreateJoint();
這裡的CreateJoint裡面包著就是Strategy function
同理,主角移動時也用類似的方式來取得資料

pKit->AddForce();
剩下的由物件自己去處,而ksTerrainDestKit就是Strategy委託者

那麼Decorator何時會使用呢?
對我來說,如果Strategy是橫向的封裝
那Decorator就是縱向的封裝

Strategy會依據種類來決定使用哪一種function
但是Decorator是一層一層的
封裝多少層,就會經過多少個function

兩個Pattern詳細比較在豬屎排程寫的比較多
但是真正要使用的時刻,怎麼判斷用哪一個
還真的是靠個人修行!


講了那麼多,其實兩種Pattern的比較只講了一點點...
好吧,我承認自己修行不夠,沒法寫出精闢的解析
所以就讓我繼續下一章節吧!XD

全站熱搜
創作者介紹
創作者 kgsprogrammer 的頭像
kgsprogrammer

太陽系後援會

seeulin 發表在 痞客邦 留言(1) 人氣()