ฉันคิดว่าวิธีการแก้ปัญหาที่มีประสิทธิภาพน่าจะเป็นวิธีที่มุ่งเน้นวัตถุ
คุณต้องการวิธีสอบถามสถานะปัจจุบันของเกมและ / หรือประวัติของการกระทำ / เหตุการณ์ที่วัตถุเกม (เช่นผู้เล่น) ทำขึ้นอยู่กับประเภทของความสำเร็จที่คุณต้องการสนับสนุน
สมมติว่าคุณมีระดับความสำเร็จพื้นฐานเช่น:
class AbstractAchievement
{
GameState& gameState;
virtual bool IsEarned() = 0;
virtual string GetName() = 0;
};
AbstractAchievement
ถือการอ้างอิงถึงสถานะของเกม มันใช้เพื่อค้นหาสิ่งที่เกิดขึ้น
จากนั้นคุณทำการใช้งานที่เป็นรูปธรรม ลองใช้ตัวอย่างของคุณ:
class MasterSlicerAchievement : public AbstractAchievement
{
string GetName() { return "Master Slicer"; }
bool IsEarned()
{
Action lastAction = gameState.GetPlayerActionHistory().GetAction(0);
Action previousAction = gameState.GetPlayerActionHistory().GetAction(1);
if (lastAction.GetType() == ActionType::Slice &&
previousAction.GetType() == ActionType::Slice &&
lastAction.GetObjectType() == ObjectType::Watermelon &&
previousAction.GetObjectType() == ObjectType::Strawberry)
return true;
return false;
}
};
class InvinciblePipeRiderAchievement : public AbstractAchievement
{
string GetName() { return "Invincible Pipe Rider"; }
bool IsEarned()
{
if (gameState.GetLocationType(gameState.GetPlayerPosition()) == LocationType::OVER_PIPE &&
gameState.GetPlayerState() == EntityState::INVINCIBLE)
return true;
return false;
}
};
จากนั้นขึ้นอยู่กับคุณในการตัดสินใจว่าจะตรวจสอบIsEarned()
วิธีการใช้งานเมื่อใด คุณสามารถตรวจสอบการอัพเดทแต่ละเกมได้
ตัวอย่างเช่นวิธีที่มีประสิทธิภาพมากขึ้นคือการมีตัวจัดการเหตุการณ์บางประเภท และการลงทะเบียนเหตุการณ์ (เช่นPlayerHasSlicedSomethingEvent
หรือPlayerGotInvicibleEvent
หรือเพียงแค่PlayerStateChanged
) เพื่อวิธีการที่จะนำความสำเร็จในพารามิเตอร์ ตัวอย่าง:
class Game
{
void Initialize()
{
eventManager.RegisterAchievementCheckByActionType(ActionType::Slice, masterSlicerAchievement);
// Each time an action of type Slice happens,
// the CheckAchievement() method is invoked with masterSlicerAchievement as parameter.
eventManager.RegisterAchievementCheckByPlayerState(EntityState::INVINCIBLE, invinciblePiperAchievement);
// Each time the player gets the INVINCIBLE state,
// the CheckAchievement() method is invoked with invinciblePipeRiderAchievement as parameter.
}
void CheckAchievement(const AbstractAchievement& achievement)
{
if (!HasAchievement(player, achievement) && achievement.IsEarned())
{
AddAchievement(player, achievement);
}
}
};
if(...) return true; else return false;
เหมือนกับreturn (...)