【问题标题】:Pairing in two player game with firebase in android?在android中与firebase配对两人游戏?
【发布时间】:2017-04-15 07:30:20
【问题描述】:

我正在尝试使用 firebase(用于实时配对)在 android 中实现一个两人游戏。

在 firebase 上,我设置了一个代表活跃玩家的节点。在每个客户端上,我都有一个 childEventListener 来监听播放器节点上的任何更改。

假设

  1. 最初只有一名玩家(玩家 A)。
  2. 然后又添加了 3 个玩家(B、C 和 D)(在相同的时间戳)。

然后,在客户端 1. 4名玩家每人都会通过childEventListener收到节点变化的通知。

现在,我想要实现的是“唯一配对”,即我应该能够从这 4 位玩家中生成 2 对。 (当然,一个玩家不能同时出现在两个对子中)

我已经编写了代码来将两个玩家配对在一个交易块中,这样两个玩家就不会与同一个玩家配对。

private void attachActivePlayersEventListener() {
        Log.i(TAG, "attachActivePlayersEventListener");
        if (activePlayersEventListener == null) {

            activePlayersEventListener = new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    searchPlayer(dataSnapshot);
                    Log.i("PLAYER_ADDED ", dataSnapshot.getValue(Player.class).getName());

                }

                @Override
                public void onChildChanged(DataSnapshot dataSnapshot, String s) {
                    searchPlayer(dataSnapshot);
                    Log.i("PLAYER_CHANGED ", dataSnapshot.getValue(Player.class).getName());
                }

                @Override
                public void onChildRemoved(DataSnapshot dataSnapshot) {
                }

                @Override
                public void onChildMoved(DataSnapshot dataSnapshot, String s) {
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {
                }

            };
            mActivePlayersDbRef.addChildEventListener(activePlayersEventListener);
        }
    }

private void searchPlayer(DataSnapshot dataSnapshot) {
        if(mPlayer.getState().equals(PlayerState.ACTIVE)) { // if the current user is active
            final String oppKey = dataSnapshot.getKey();
            Player oppPlayer = dataSnapshot.getValue(Player.class);

            if (oppPlayer.getState().equals(PlayerState.ACTIVE)
                    && !oppKey.equals(pushId)) { // if the opponent chosen is not the current user

                DatabaseReference oppRef = mActivePlayersDbRef.child(oppKey);
                oppRef.runTransaction(new Transaction.Handler() {

                    @Override
                    public Transaction.Result doTransaction(MutableData mutableData) {
                        Player player2 = mutableData.getValue(Player.class);
                        if (player2 == null) {
                            return Transaction.success(mutableData);
                        }
                        mActivePlayersDbRef.child(pushId).child("state").setValue(PlayerState.PLAYING);
                        mActivePlayersDbRef.child(oppKey).child("state").setValue(PlayerState.PLAYING);

                        return Transaction.success(mutableData);
                    }

                    @Override
                    public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
                        Log.d("PAIRING", "pairing:onComplete:" + databaseError);
                    }
                });
            }
        }
    }

我的怀疑是

  1. 这是正确的配对方式吗?
  2. 当 PlayerA 尝试与 PlayerB 配对、PlayerB 尝试与 PlayerC 配对、PlayerC 尝试与 PlayerD 配对、最后 PlayerD 尝试与 PlayerA 配对时会发生什么(以循环方式)。如何确保不会发生这种情况?

请注意,在 Doubt2 中,我没有处理两名玩家尝试与同一名玩家配对的情况。 (因为事务块将确保它不会发生,我猜:/)。

【问题讨论】:

    标签: android firebase firebase-realtime-database multiplayer


    【解决方案1】:

    您尝试做的事情很难正确和安全地完成。最好让后端服务进行这种匹配,这样客户端就不必都想办法以某种方式相互达成一致。

    您可以使用Cloud Functions for Firebase 编写一个database trigger 来响应数据库中的更改。一种策略是让客户端将数据推送到数据库中的某个位置,以表明他们的意图要匹配。然后,当一个函数在这些写入上触发时,它可以检查是否有其他合适的玩家可以匹配,并将更多数据写入数据库以设置游戏。客户端还需要一种方法来监听匹配后启动的游戏。这仍然非常重要,但比将逻辑放入客户端要容易得多。

    【讨论】:

    • 嘿@Doug,我探索了firebase的云功能,但仍然遇到同样的并发问题。因此,假设我编写了一个云函数“pairMe()”,每次将玩家添加到 firebase 中的“IWannaPlay”节点时都会触发该函数。现在,如果 50 个玩家在一个时间戳上出现,那么函数 pairMe() 的 50 个实例将在那个时刻被触发,并且我在问题中提到的所有问题都可能再次出现。我面临的基本问题是“给定大量玩家,我如何生成独特的配对(如果可能,使用 firebase 工具)?”
    • 使用事务确保对数据库中特定位置的序列化访问。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-21
    • 1970-01-01
    • 1970-01-01
    • 2021-03-13
    • 2011-09-09
    • 2013-09-14
    相关资源
    最近更新 更多