【发布时间】:2017-04-15 07:30:20
【问题描述】:
我正在尝试使用 firebase(用于实时配对)在 android 中实现一个两人游戏。
在 firebase 上,我设置了一个代表活跃玩家的节点。在每个客户端上,我都有一个 childEventListener 来监听播放器节点上的任何更改。
假设
- 最初只有一名玩家(玩家 A)。
- 然后又添加了 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);
}
});
}
}
}
我的怀疑是
- 这是正确的配对方式吗?
- 当 PlayerA 尝试与 PlayerB 配对、PlayerB 尝试与 PlayerC 配对、PlayerC 尝试与 PlayerD 配对、最后 PlayerD 尝试与 PlayerA 配对时会发生什么(以循环方式)。如何确保不会发生这种情况?
请注意,在 Doubt2 中,我没有处理两名玩家尝试与同一名玩家配对的情况。 (因为事务块将确保它不会发生,我猜:/)。
【问题讨论】:
标签: android firebase firebase-realtime-database multiplayer