我应该如何检查玩家是否完成了一项成就?


13

我正在制作MMO游戏,而我刚到需要实现成就的地步...我该怎么做?最直接的方法是每100ms运行一次:

for a in achievements
    for p in players
        if a.meetsRequirements(p) then p.completeAchievement(a)

但这只会带来更多的复杂性。例如,如何检查成就是否已经完成?玩家是否仅针对特定成就拥有自定义属性?我对任务进行了此类操作,因为它们主要是“收集100块木头”,因此玩家进行的主动任务会对此进行检查。另外,我认为必须有更好的时间来检查它,这会定期降低我的服务器的速度。


7
为什么不只在操作完成后运行相关检查?即,如果用户收集木材,请查看他们是否符合“收集100木材”规范。
Mike Cluck

1
那有点太乱了……到处都会有数不清的支票。我想我会坚持上面的算法,因为它很简单...
jcora 2011年

10
有一些方法可以使它不那么混乱:例如具有“ OnChange”事件处理程序,然后将成就“对象”附加到这些对象并处理其中的逻辑。还应了解,在当前设置下,您的复杂度为O(n ^ 2),这意味着您的游戏会随着角色的增加而变得越来越慢。对于MMO来说有点问题
Mike Cluck

Answers:


23

您所做的工作取决于成就的性质。除非您的成就全部符合一个简单的模式(收集X个Y数),否则您将不得不在某种程度上对它们进行特殊区分。

使用基于消息的通信系统,您可以提供挂钩,以使特殊情况的代码本地化。您可以采取某些措施向注册自己的听众发送消息。然后,您的成就代码/脚本可以将自己注册到适当的侦听器中,并进行必要的测试以激发成就。

您将收到有关可能希望成就听的典型事件的消息。诸如“玩家已获得物品X”或“实体Y杀死实体Z”之类的东西。这样,您可以跟踪玩家杀死了多少个Z。

对于成就系统,这可能是您可以做的最好的事情。它尽可能地集中了代码,并把侦听器的责任放在实际成就检测上。

另外,应该注意的是,对于集中式成就系统(X-Box Live,Steam成就),成就的进度通常存储在服务器上。因此,对于累积成就(“执行任务XY次数”),成就脚本仅检测何时执行X并增加服务器的计数。对于其他类型的成就(“执行任务X”),服务器成就是二进制的:您已经完成了,或者没有完成。


+1这是很棒的信息。甚至在我现在不需要实现成就的情况下也很有用。
Joshua Hedges

谢谢!等不及要实现它了,我希望我以前有这个想法...
jcora 2011年

3

根据成就的性质,您还可以引入某种“标记成就”。

例如,如果您连续获得3个成就:
木材1-收集100木材
木材2-收集500木材
木材3-收集1k木材

然后有意义的是,只需为第一个成就注册一个OnChange事件,直到玩家完成它为止。完成后,您可以注册下一个成就对象。

当然,这需要设计(或计算)成就依赖树。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.