Ich denke, eine Art robuste Lösung wäre, den objektorientierten Weg zu gehen.
Abhängig davon, welche Art von Leistung Sie unterstützen möchten, benötigen Sie eine Möglichkeit, den aktuellen Status Ihres Spiels und / oder den Verlauf von Aktionen / Ereignissen abzufragen, die die Spielobjekte (wie der Spieler) ausgeführt haben.
Angenommen, Sie haben eine Basis-Leistungsklasse wie:
class AbstractAchievement
{
GameState& gameState;
virtual bool IsEarned() = 0;
virtual string GetName() = 0;
};
AbstractAchievement
enthält einen Verweis auf den Stand des Spiels. Es wird verwendet, um die Ereignisse abzufragen.
Dann machen Sie konkrete Umsetzungen. Lassen Sie uns Ihre Beispiele verwenden:
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;
}
};
Dann liegt es an Ihnen, zu entscheiden, wann die IsEarned()
Methode angewendet werden soll . Sie können bei jedem Spiel Update überprüfen.
Ein effizienterer Weg wäre zum Beispiel, eine Art Event-Manager zu haben. Registrieren Sie dann Ereignisse (wie PlayerHasSlicedSomethingEvent
oder PlayerGotInvicibleEvent
oder einfach PlayerStateChanged
) für eine Methode, die die Leistung als Parameter annehmen würde. Beispiel:
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;
ist das gleiche wiereturn (...)