在每次更新呼叫中以有效的方式检查游戏目标状态

我正在创建一个有三个级别的2D手机游戏。 每个级别有20个目标。 这可以在未来增加。

例子:

Level 1 Current Objective: 2/20 Objective : Collect 1000 coins Rewards: 100 coins. Level 1 Current Objective: 20/20 Objective : Kill 100 aliens Rewards: Shotgun 

问题是,当一个用户在玩游戏时,你如何检查他是否已经有效地完成了他目前的目标? 这不涉及像GameCenter,Scoreloop等任何第三方的听众

我不希望在每次更新调用中都有一个方法需要检查开关/ if-else /或任何其他条件块,因为这会影响FPS。 有些框架不是线程安全的。 所以有一个单独的线程是不是一个选项,因为我要将其移植到其他一些平台使用其他框架。

我如何去做呢?

过早优化和devise麻痹是邪恶的。 不要陷入担心简单检查的陷阱。 如果你担心,实施和configuration文件。

我认为你低估了硬件的性能 – 甚至是低端硬件。 比较简单的布尔值的if语句相当便宜,应该是游戏中最less的关注点。 我同意,检查每一帧的条件是不理想的 – 但有很多不同的方式,你可以绕过这个,如果你是有关的。 这张支票非常便宜,其他许多人已经完成了这个工作 – 但是我会试着再给出一个详细的解释。 你已经在Java和C ++下标记了这个,并且在评论中提到了Android 1.5,所以推测这是你的目标。

只在必要时检查。 如果您的目标是获得10,000分的分数; 在你的二传手上添加一个检查分数或者给成就经理添加一个callback,最好是validation这一点。 目标管理者只是一个简单的枚举和布尔值散列图; (我select了快速查找时间的哈希映射)callback可以快速查找此表,并将其设置为在需要时解锁。

针对游戏目标进行优化。 如果你的游戏目标是“杀死5艘船”,留下活着的船只的柜台; 不要直接查询游戏状态。 在完成状态变化时评估状态variables,所以你不必一次性完成昂贵的计算。 如果你的目标需要大量的空间探索,这可能是昂贵的,这是很方便的。 每个黄色的盒子都需要接触一个绿色的盒子吗? 在碰撞时,设置一个标志来确定这个,然后在对象脱落时取消设置。 保持状态易于访问和查询。

推迟支票。 如果您的支票比单个查找和几个比较(昂贵的属性获得者,function或许多支票)要贵,而且您确实认为不能优化支票,那么您总是可以推迟支票。 你的游戏可能有闲置状态,或玩家没有做很多事情。 不知道你的游戏很难说 – 但让我给一个总的要点。

我们将以“ 愤怒的小鸟”为例来说明目的。 愤怒的小鸟在状态机中可能有很多状态 – 但是为了简化起见,我们假设只有两个状态。

第一种状态是鸟在弹弓上rest; 他们闲着,没有做任何事,只是等待用户input。 没有太多的东西正在进行,小的FPS下降将不会被注意到这个状态过渡到。

第二种状态当然是鸟在空中飞行。 在这个状态结束后(鸟儿已经完成了飞行),游戏转回到弹弓(状态1)并且检查所有的猪是否已经失败。

推迟客观检查的想法和愤怒的小鸟完全一样 – 你可以排队在该状态期间可能发生的合理的客观检查,然后在负载可以接受的时候validation,并且最终用户不会注意到任何明显的帧丢失。

你应该建立一个观察规则和进行必要的检查的成就系统

如何建立一个灵活的处理成果框架?

保留每个级别的成就列表。 迭代每个周期的列表。 如果一个成就完成,就从列表中删除它(换句话说,检查就完成了)。

不要害怕“如果”每个选项。 你的gameboy将能够以60 fps迭代1000个成员列表(假设)。 你不会感觉到FPS的下降。

有没有方法可以去使用一些简单的math公式,但它是2013年。我们不需要这样的黑客。 这会让你的代码更加模糊。

只需检查每一个事件,而不是每一个帧的调用。 例如,如果你有一个收集200个硬币的目标,只有当你拿到一个硬币时才检查这个硬币。 如果你有成绩,只有在成绩改变时才检查。
只有在相关时才检查这些东西会保持你的最小开销。

为了避免大的if / switch结构,你可以创建一个专门的类来管理这些成就/目标,并且对于每个单独的成就都有一个独占的function。