Adding achievements mechanism - how do design - objective c
So I want to add achievements to my game. Basically there are around 40 achievements that can be awarded while using the app. (if while playing a game, and even while pressing some menu buttons).
I'm not sure how should I implement it, so I'll let you know what are the options I thought of so far :
Writing an AM (Achievements Manager) class which will have a addAchievment() function.
Inside every function in my app that can grant achievement I can allocate an Achievemnt object and call addAchievment() with that object. What I don't like about this approach is first, you have do add lot's of achievments code to many many parts of the app. (and also checking not add the same achievement more than once).
One way to improve it would be maybe to call addAchievment() with a certain enum, and then inside addAchievment() implementation t开发者_高级运维o check each enum and allocate the appropriate achievment object - however, a function with a switch of 40 cases doesn't sound good either.
2. For every class that can report achievements I can write a function per achievement which return if that achievement should be granted. for example is class A can report 2 achivments I can write 2 functions :
-(BOOL) shouldGrantA1
-(BOOL) shouldGrantA2
When I init class A, I call the achievements manger and add those 2 function to an array of function the AM will hold. Every time I want to check if I should grant achievments I just call the AM CheckAchievements() and what it will do is run through all the function and add achievements where the function return TRUE.
Problem with this approach - Let's say in class A I reach a place where I change a value that I know can grant achievemetn. I can call AM's CheckAchievements() but that will go through all the achivements functions, even though probably currently only class A's achivement would be granted. seems like a bit overhead. Any way to solve that ?
I would love to here other suggestion as well. Thanks!!
I would not add any achievement like code to your existing game classes. No booleans or whatsoever because this creates too tight a coupling between your game classes and your achievement system. Better to create a separate "AchievementManager" that manages several AchievementListeners, these listen to the state of objects and when a relevant state changes the unlock condition is checked. I think this idea is best illustrated in code.
For example if you have the achievement "Player walks 100 kilometers". the PlayerWalksAchievementListener would look like this.
private AchievementManager manager;
private Player player.
private Vector2 previousPlayerPosition;
private float distanceWalked;
Update()
{
float dist = Vector2.Distance(player.Position, previousPlayerPosition);
if(dist > 0)
{
distanceWalked += dist;
CheckUnlockCondition();
}
}
CheckUnlockCondition()
{
if(distanceWalked * conversionFactor > 100) { manager.UnlockAchivement(achievementID); }
}
精彩评论