我想在android中使用firebase實現雙人遊戲(用於實時配對)。與android中的firebase在兩個玩家遊戲配對?
在firebase上,我建立了一個代表活躍球員的節點。並且在每個客戶端上我都有一個childEventListener來監聽播放器節點上的所有更改。
假設
- 最初只有一個玩家(玩家A)。
- 然後又增加了3個玩家(B,C和D)(在SAME TIMESTAMP)。
然後,在客戶端 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配對(以循環方式)。如何確保這種情況不會發生?
請注意,在懷疑2中,我沒有考慮到兩名球員試圖與同一名球員配對的情況。 (由於事務塊將確保它不會發生,我猜:/)。
嘿@Doug,我探索了firebase的一些雲功能,但仍然存在相同的併發問題。因此,假設我編寫了一個雲端函數「pairMe()」,每當玩家被添加到firebase中的「IWannaPlay」節點時就會觸發它。現在,如果有50個玩家出現在單個時間戳中,則會在該瞬間觸發50個函數pairMe()的實例,並再次提到我在問題中提到的所有這些問題。 我面臨的基本問題是「給定一個玩家流,我如何生成唯一對(如果可能,使用Firebase工具)?」 –
使用事務來確保序列化訪問數據庫中的特定位置。 –