多bit跨时钟域同步_如何跨多个设备同步游戏应用

多bit跨时钟域同步

by Shukant Pal

通过Shukant Pal

如何跨多个设备同步游戏应用 (How to synchronize your game app across multiple devices)

If you’re having problems with online game synchronization, you’re in the right place!

如果您在在线游戏同步方面遇到问题,那么您来对地方了!

At their lowest level, typical games can be broken down into simple steps taken by each player — they are called turns, and in each turn a move occurs. It isn’t necessary that players get one turn at a time, or make only one move at a time. To synchronize your game app across multiple online devices, you need to be able to break your game into these little steps.

在最低的水平上,典型的游戏可以分解为每个玩家采取的简单步骤-它们被称为回合,并且每回合都会发生移动。 玩家不必一次转一圈,也不必一次只举一动。 要在多个在线设备上同步您的游戏应用程序,您需要能够将游戏分解为这些小步骤。

我们的模型 (Our Model)

In this article, we take a simple generic two-player board game. Before doing anything, we need two players, right?

在本文中,我们采用一个简单的通用两人棋盘游戏。 在做任何事情之前,我们需要两个球员,对吗?

To set this up, you need to implement a feature called matchmaking, where you have a common node in your FirebaseDatabase where every player can post their challenge. The challenge posted contains the UID of the challenger and another reference to a moves-node where the moves will be published. If you haven’t done this or are having problems implementing it, read this article on matchmaking.

要进行此设置,您需要实现一个称为“比赛匹配”的功能,该功能在FirebaseDatabase中具有一个公共节点,每个玩家都可以在该节点上发布挑战。 发布的质询包含质询者的UID,以及对将发布动作的移动节点的另一个引用。 如果您尚未执行此操作,或者在实现该功能时遇到问题,请阅读这篇关于婚介的文章。

Once both players get hold of the moves node, one player must post their first move, then the second, then the first and so on. We will use Firebase’s ChildEventListener to receive moves posted by the opponent.

一旦两个玩家都掌握了moves节点,则一个玩家必须发布他们的第一个动作,然后发布第二个动作,然后发布第一个动作,依此类推。 我们将使用Firebase的ChildEventListener接收对手发布的动作。

深入研究代码 (Dive deeper into the code)

Basically, we have two things to do: send a move and receive a move. Our FirebaseGameSynchronizer component will do just that, but interpretation of the move will be done by the Modulator you implement.

基本上,我们有两件事要做:发送移动和接收移动。 我们的FirebaseGameSynchronizer组件将仅执行此操作,但是对动作的解释将由您实现的Modulator完成。

The mover sends their move using sendMoveMsg . You can encode your move in a variety of ways. For example, if a piece is moved from (a,b) to (c,d), then encode the move as the number abcd. I would definitely recommend this method if the size of your sample (or if it’s a board game, the board size) is less than 10.

移动器使用发送他们的行动sendMoveMsg 。 您可以采用多种方式对移动进行编码。 例如,如果将一块从(a,b)移到(c,d),则将移动编码为数字abcd 。 如果您的样本大小(如果是棋盘游戏,则是棋盘大小)小于10,我绝对会推荐这种方法。

sendMoveMsg basically uploads the move to the moves-node mMovesRecordList and expects the other player to be listening to it.

sendMoveMsg基本上将移动mMovesRecordList moves节点mMovesRecordList并期望其他玩家正在听。

Once the move is published, both players receive the move. Wait a minute… You don’t want the mover to receive the move — because you may have already done the move on their end, and don’t want to do it twice.

发布动作后,两个玩家都会收到动作。 等一下……您不希望动子收到动议-因为您可能已经在他们的末端完成了动议,并且不想重复两次。

So, I also added a cool feature (if you want both players to receive the move instead, just remove all references to mSelfMoveSoph ): the self-moves semaphore. Every time sendMoveMsg is called, it increments to mSelfMoveSoph. We know how many moves we’ve uploaded right now with this semaphore.

因此,我还添加了一个很酷的功能(如果您想让两个玩家都接受此举,则只需删除对mSelfMoveSoph所有引用):自我移动信号灯。 每次调用sendMoveMsg ,它将递增到mSelfMoveSoph 。 我们知道此信号量现在已上传了多少步。

onChildAdded is called whenever a move is added by Firebase. It ignores the move if the semaphore has a value; otherwise, the mMessageModulator is called to interpret the move and show it to your user. Modulator is a functional interface that is the complement to your move-to-string encoder. It takes that string uploaded to Firebase and converts it into the move.

每当Firebase添加移动时,就会调用onChildAdded 。 如果信号量具有值,它将忽略移动。 否则,将mMessageModulator来解释移动并将其显示给您的用户。 Modulator是一个功能性接口,是对字符串移动编码器的补充。 它会将上载到Firebase的字符串,并将其转换为移动。

等待,如果用户接到电话那将不起作用 (Wait, that won’t work if the user gets a call)

Yes, if the user gets a call and your application is killed… how will the user get back to playing?

是的,如果用户接到电话,并且您的应用程序被杀死……用户将如何恢复播放?

Again, let’s make a Modulator like this:

同样,让我们​​制作一个像这样的Modulator

public class GenericGameFragment implements FirebaseGameSynchronizer.Modulator {
public void onMoveReceived(boolean isSyncingPast, String encodedMsg) {       // ... do move, show it on UI .....
}
}

Now two bad things will happen:

现在将发生两件事:

  1. If the user leaves, FirebaseGameSynchronizer will be left attached to the node listening to it. That’s a memory + CPU-usage leak.

    如果用户离开, FirebaseGameSynchronizer将保留在侦听该节点的节点上。 那是内存+ CPU使用率泄漏。

  2. FirebaseGameSynchronizer will have a reference to your fragment — just see it, Modulator must update the UI and has a reference to GenericGameFragment .

    FirebaseGameSynchronizer将引用您的片段-看到它,调制器必须更新UI并引用GenericGameFragment

与移动节点同步和不同步 (Syncing and Unsyncing to the moves-node)

I used a relatively simple solution to the problem. It’s a combination of two things:

我使用了一个相对简单的解决方案。 这是两件事的结合:

  1. Sync flag: When you set the sync property, FirebaseGameSynchronizer will call the modulator, otherwise, it will store the move in a buffer. On setting the sync flag again, it first releases the moves in its buffer.

    同步标志:设置sync属性时, FirebaseGameSynchronizer将调用调制器,否则,它将移动存储在缓冲区中。 再次设置同步标志时,它首先释放其缓冲区中的移动。

  2. Attachment: The modulator is removed whenever the fragment’s onStop method and set again on the fragment’s onStart.

    附件:每当片段的onStop方法删除调制器,然后再次在片段的onStart上进行设置。

Before using this “new” synchronizer, remember to call startSync(). On onStop, call stopSync and in onResume call startSync again. Now, you should call detachModulator and flush in onDestroy.

在使用此“新”同步器之前,请记住调用startSync() 。 在onStop ,调用stopSync ,在onResume再次调用startSync 。 现在,您应该调用detachModulatorflush onDestroy

Check this link for the full implementation: FirebaseGameSynchronization Gist.

检查此链接以获取完整实现: FirebaseGameSynchronization Gist

Further Reading:

进一步阅读:

翻译自: https://www.freecodecamp.org/news/how-to-synchronize-your-game-app-across-multiple-devices-88794d4c95a9/

多bit跨时钟域同步

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值