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