結束了創建(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;
改完之後竟然消除掉所有的巢狀結構!
由此可見簡化的重要性
如何?修改完後是不是看起來清爽很多呢?
補充一句:"彼得哥萬歲!!!"
 
         留言列表
 留言列表 
             
 
 程式研究 (8)
 程式研究 (8)


