close

結束了創建(Creation)的部分,接下來則是簡化(Simplification)

 

我想又臭又長的程式碼是沒有人可以接受的

 

因此如何簡化程式碼的內容,也成為一大課題

 

 

 

第一個上場的就是Composed Method

 

簡單來說,就是把太大的function拆解成為小function

 

除了簡化原本的程式碼外,也可以讓function功能更加明確

 

拿我們AI在處理子彈的碰撞訊息為例子:

 

bool isHurt = false;
ksMsgActor *pObj = pMsg->m_pTouchAI;
if (NiIsKindOf(ksAmmo, pObj))
{
    if (isHurt == false && m_bDisableHurt == false)
    {
         if (((ksMainRoleAI*)pAI)->GetUnbeatable() == false)
         {
            NxActor *act = pMsg->m_pTouchActor;
            if (
act != NULL)
            {
                NiPoint3 vHitDir, vDir;
                NxVec3ToNiPoint3(act->getLinearVelocity(), vHitDir);
                vHitDir.z = 0.0f;
                NiPoint3::UnitizeVector(vHitDir);
                pAI->GetRotate().GetCol(Y_AXIS, vDir);
                float angle = vHitDir.Dot(-vDir);
                if (angle < 0.0f)
                   m_iCondition |= ksBaseCondition::COND_DAMAGE_B;
                else
                   m_iCondition |= ksBaseCondition::COND_DAMAGE_F;

                int hit =
((ksAmmo*)pObj)->GetHurt();
                int impulse = ((ksAmmo*)pObj)->GetShockWave();
                if (impulse >= 200)
                    m_iCondition |= ksBaseCondition::COND_DAMAGE_FLY;
                else if (impulse >= 100)
                    m_iCondition |= ksBaseCondition::COND_DAMAGE_BIG;
                float hp = pAI->GetHp();
                pAI->SetHp(hp - hit);
                isHurt = true;
            }
        }
    }
}
這個部分有兩大缺點,一個是巢狀式的判斷寫太多

 

以致於閱讀起來會不太方便

 

另一個是判斷式裡面內容太長,同樣也會造成閱讀困難

 

 

 

先把程式碼簡化吧!

 

該包裝的function就應該要包裝起來,然後取個易懂的名稱:

 

bool isHurt = false;
ksMsgActor *pObj = pMsg->m_pTouchAI;
if (NiIsKindOf(ksAmmo, pObj))
{
    if (isHurt == false && m_bDisableHurt == false)
    {
         if (((ksMainRoleAI*)pAI)->GetUnbeatable() == false)
         {
            NxActor *act = pMsg->m_pTouchActor;
            if (
act != NULL)
            {
               
m_iCondition |= GetHurtDirCondition( pAI, act );
                m_iCondition |= GetHurtLevelCondition(
                                                        ((ksAmmo*)pObj)->GetShockWave() );
                pAI->SetHp(
pAI->GetHp() - ((ksAmmo*)pObj)->GetHurt() );
                isHurt = true;
            }
        }
    }
}

 

 

 

雖然內容大幅縮短,但是討人厭的巢狀式架構還是存在
最後再簡化一次:

 

bool isHurt = false;
ksMsgActor *pObj = pMsg->m_pTouchAI;
if (NiIsKindOf(ksAmmo, pObj) == false)
    return;
if (isHurt || m_bDisableHurt)
    return;
if (((ksMainRoleAI*)pAI)->GetUnbeatable())
    return;
NxActor *act = pMsg->m_pTouchActor;
if (
act == NULL)
    return;

m_iCondition |= GetHurtDirCondition( pAI, act );
m_iCondition |= GetHurtLevelCondition( ((ksAmmo*)pObj)->GetShockWave() );
pAI->SetHp(
pAI->GetHp() - ((ksAmmo*)pObj)->GetHurt() );
isHurt = true;

改完之後竟然消除掉所有的巢狀結構!

 

由此可見簡化的重要性

 

如何?修改完後是不是看起來清爽很多呢?

 

補充一句:"彼得哥萬歲!!!"

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

太陽系後援會

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