添加成就机制-如何设计-目标c

发布于 2024-10-14 00:02:19 字数 887 浏览 0 评论 0原文

所以我想在我的游戏中添加成就。 基本上,使用该应用程序时可以授予大约 40 项成就。 (如果在玩游戏时,甚至在按某些菜单按钮时)。

我不确定应该如何实现它,所以我会让您知道到目前为止我想到的选项:

  1. 编写一个具有 addAchievment() 函数的 AM(成就管理器)类。

    在我的应用程序中可以授予成就的每个函数中,我可以分配一个 Achievemnt 对象并使用该对象调用 addAchievment() 。 我不喜欢这种方法的首先是,您必须向应用程序的许多部分添加大量成就代码。 (并检查是否多次添加相同的成就)。

改进它的一种方法可能是使用某个枚举调用 addAchievment() ,然后在 addAchievment() 实现内部检查每个枚举并分配适当的成就对象 - 然而,具有 40 个情况切换的函数听起来并不好也不错。

2. 对于每个可以报告成就的课程,我可以为每个成就编写一个函数,如果应该授予该成就,则返回该函数。 例如,A 类可以报告 2 个成就,我可以编写 2 个函数:

-(BOOL) shouldGrantA1
-(BOOL) shouldGrantA2

当我初始化 A 类时,我调用成就管理器并将这 2 个函数添加到 AM 将保存的函数数组中。 每次我想检查是否应该授予成就时,我只需调用 AM CheckAchievements() ,它将执行的操作是运行所有函数并添加成就 其中函数返回 TRUE。

这种方法的问题——假设在人工智能课堂上,我改变了一个我知道可以实现成就的值。我可以调用 AM 的 CheckAchievements(),但这将遍历所有成就函数,尽管目前可能只有 A 类的成就会被授予。似乎有点开销。 有什么办法解决吗?

我也很想在这里提出其他建议。 谢谢!!

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 :

  1. 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 to 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!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

迷迭香的记忆 2024-10-21 00:02:19

我不会将任何成就(例如代码)添加到您现有的游戏类中。没有布尔值或任何其他值,因为这会在游戏类和成就系统之间造成过于紧密的耦合。最好创建一个单独的“AchievementManager”来管理多个 AchievementListener,这些侦听器侦听对象的状态,并在相关状态更改时检查解锁条件。我认为这个想法最好用代码来说明。

例如,如果您有成就“玩家行走 100 公里”。 PlayerWalksAchievementListener 看起来像这样。

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); } 
}

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); } 
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文