我想在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工具)?” –
使用事务来确保序列化访问数据库中的特定位置。 –