2
4

1 回答 1

4

我做类似的事情。在我的游戏中,每个玩家都有多个棋子,当每个棋子移动时保存比赛,以便其他玩家——如果他们在游戏中——可以实时观看发生的事情。就像你描述的那样,Game Center 消息几乎完全没用。

正如您所提到的,在 8.3 中,“回合结束”消息完全被破坏了。从 8.4 开始,它们发生的时间最多,但不是全部。如您所见,“比赛已保存”通知也不稳定。以下是我用来提高成功率的一些技巧:

  1. 减慢保存速度。如果您保存得太快,则只有最后一个到达收件人。我设置了一个 NSArray 队列,每次我想保存比赛时,我都会将新的 matchData 添加到该队列中。我有一个计时器循环正在运行,它执行实际的操作saveCurrentTurnWithMatchData,如果保存成功,则将项目从堆栈中弹出,然后设置一个新的计时器稍后再次调用自身。我正在使用 2 秒的间隔,这似乎运作良好。

  2. 追加每条新数据,不要覆盖。在每条数据上放置一个序列号。因此,如果您保存 seq 编号 1、2、3 和 4,但收件人只收到 #4 的通知,则匹配对象中存在 1、2 和 3 的记录。接收者需要跟踪它读取的最后一条记录,然后在接收到更新的 matchData 时从该点开始遍历任何新记录。

  3. 我还使用队列的 NSArray writeToFile: 函数来维护挂起保存的列表。如果用户在刷新队列之前退出游戏,我会在下次启动时从磁盘重新加载队列 NSArray

  4. 请注意,即使使用此机制,发送给收件人的通知也是不稳定的。一般来说,它们以 4+ 的批次到达。然后什么都不会发生,直到发生 3 或 4 次以上的保存,这些保存再次一起出现。进行 1 次保存并让游戏等待 10 分钟可能永远不会在接收者的机器上生成通知。但是,如果您连续保存 4 或 6 次,则它们往往都会突然出现。

  5. 有时,通知只会停止几个小时。不确定这是沙盒缺陷还是游戏中心的一般缺陷。没有任何类型的故障,消息只是停止工作一段时间。有时,第二天早上,它们会突然出现。有时不是。最后,我不再依赖通知。我设置了另一个计时器循环来不断下载比赛。它检查是否轮到我了,它检查是否已将新更新添加到 matchData。然后调用player:receivedTurnEventForMatch:didBecomeActive. 据receivedTurnEventForMatch: 知道,它是因为一个事件而推出的,它愉快地继续着它的业务。

  6. 保存比赛似乎非常迅速。如果您没有收到错误消息,似乎可以肯定更新的比赛可以立即供其他玩家使用……他们只需要知道使用它。但是,消息传递框架必须被视​​为完全不可靠且没有保证。因此,定时器循环不断地轮询匹配。

编辑:可以说,一旦我实施了#2,#1 就不再重要了。接收者收到的任何通知都会触发读取数据中的所有新记录。但是,随着我与 Game Center 的缺点作斗争,这种“硬化”在过去几个月中已经演变。我只是还没来得及删除#1。

于 2015-08-13T05:36:00.090 回答