Tôi nghĩ rằng một loại giải pháp mạnh mẽ sẽ là đi theo hướng đối tượng.
Tùy thuộc vào loại thành tích bạn muốn hỗ trợ, bạn cần một cách để truy vấn trạng thái hiện tại của trò chơi của bạn và / hoặc lịch sử hành động / sự kiện mà các đối tượng trò chơi (như người chơi) đã thực hiện.
Giả sử bạn có một lớp Thành tích cơ bản như:
class AbstractAchievement
{
GameState& gameState;
virtual bool IsEarned() = 0;
virtual string GetName() = 0;
};
AbstractAchievement
giữ một tham chiếu đến trạng thái của trò chơi. Nó được sử dụng để truy vấn những điều đang xảy ra.
Sau đó, bạn thực hiện cụ thể. Hãy sử dụng các ví dụ của bạn:
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;
}
};
Sau đó, tùy bạn quyết định khi nào nên kiểm tra bằng IsEarned()
phương pháp. Bạn có thể kiểm tra tại mỗi bản cập nhật trò chơi.
Ví dụ, một cách hiệu quả hơn sẽ có một loại quản lý sự kiện. Và sau đó đăng ký các sự kiện (chẳng hạn như PlayerHasSlicedSomethingEvent
hoặc PlayerGotInvicibleEvent
đơn giản PlayerStateChanged
) vào một phương thức sẽ lấy thành tích trong tham số. Thí dụ:
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;
giống nhưreturn (...)