[英]Adding a multi-node ArrayList to Firebase Realtime-Database
我已經在這個多人游戲大廳工作了幾天,我很掙扎,讓我告訴你。
無論如何,我正在紙上重新解決問題,以便我可以逐步實現我想要做的事情。 我的大廳的簡單步驟如下:
所以這是我目前的流程,但我不確定我是否遺漏了任何步驟。 當然,這些步驟背后有很多代碼,但這只是事情的要點。
我的問題是如何做到這一點,以便在用戶創建游戲時,如何將其正確添加到所有用戶都可以實時訪問的 ArrayList 中。 現在 ArrayList 對所有用戶都不同。 因此,如果一個人制作了一款游戲,該游戲會添加到實時數據庫中,但不會添加到每個用戶的列表中。
如何制作動態實時 ArrayList?
這是目前將游戲同時添加到數據庫和列表的方法。
gameMaker = new GameMaker(hp.uid, userName, wagerD, numGames);
cgRef.child(Integer.toString(numGames))
.setValue(gameMaker).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(FlipCoinLobby.this, "Game creation successful.", Toast.LENGTH_SHORT).show();
uName = gameRef.child("Username").toString();
openGames.add(numGames, uName);
adapter.notifyDataSetChanged();
} else {
Toast.makeText(FlipCoinLobby.this, task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
我的 ArrayList 在類的頂部被簡單地定義為:
ArrayList<String> openGames = new ArrayList<>();
我在 Firebase 中做了一個類似的游戲。 我通常使用onDataChange()
方法來驗證每個客戶端都知道gameRoom
列表已更改。
用戶點擊多人游戲
如果已經存在一個空房間,則客戶端進入。
如果其他房間已滿或沒有空房間,則客戶端創建一個房間
配對完成后,讓我們開始比賽
當比賽結束時,第一個客戶端修改用戶變量,第二個客戶端刪除整個房間的孩子。
如果你想創建一個動態onDataChange()
,你必須使用onDataChange()
方法並在每次數組列表更改時使用它。 如果 arraylist 已更改,則必須更新每個客戶端 arraylist。
有很多競爭問題。
Every_Flag 是多人游戲可用並由每個客戶端下載的標志列表。 在客戶端代碼中,每個標志都有特定的多人游戲 ID - 0,1,2 等 易於更新。
最后是比賽:
數據庫參考:
private DatabaseReference Matchmaking, Room,Accounts;
如果玩家登錄,多人游戲按鈕變得可用。 此方法對於在 db 中獲取每個匹配項是否可用非常有用:
//metodo per la gestione dei cambiamenti della tabella Matchmaking
Matchmaking.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
//nel caso ci siano delle modifiche alla tabella
//se il match non è stato trovato e Account è stato verificato
if(accountFound){
//azzero la Lista
List_party = new ArrayList<>();
Id_rooms = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
//sempre se matchfound non è stato trovato
if (!currentwithID.getMatch_found()) {
//prendo la quantità di figli presenti
size = Integer.parseInt(String.valueOf(dataSnapshot.getChildrenCount()));
//inserisco all'interno della variabile CT il valore di ogni figlio
ct = ds.getValue(Class_party.class);
// e se è il numero di giocatori == 1 e la partita non è iniziata e finita in modo anomalo
if (ct.getNumberOfPlayers() == 1 && !ct.getStart() && ct.getCorrect_end() && ct.getAccessible()) {
//aggiungo l'id della room alla lista
//Inserisco alla list_party l'intero oggetto
Id_rooms.add(ct.getId());
List_party.add(ct);
}
Toast.makeText(HomeActivity.this, "Lista ROOMs aggiornata", Toast.LENGTH_SHORT).show();
}
}
}
}
這就是我生成匹配的方式:
//MATCHMAKING
public void Create(View view)
{
boolean start = false;
boolean correct_end = true;
boolean accessible = true;
uSer = user.getDisplayName();
//se la lunghezza delle partite disponibili a cui accedere è ==0
if(size==0||Id_rooms.size()==0)
{
//creo la chiave univoca per il match
String id = Matchmaking.push().getKey();
//creo un utente corrente con nome e punteggio
current=new Class_user(uSer,0);
//un utente con ID utente, nome e se il match è stato trovato
//genero le domande che verranno utilizzato solo per quel determinato match
list_game= Generation();
//ora creo il match vero e proprio e lo inserisco nella tabella matchmaking
second = new Class_party(id, current, list_game,start,correct_end,accessible);
Matchmaking.child(id).setValue(second); }
else{
accessible = false;
// se invece ci sono delle partite disponibili, le randomizzo
Collections.shuffle(Id_rooms);
for(int i=0; i<List_party.size();i++)
{
//le passo tutte finché non trovo quella con l'ID corrispondente alla prima che ho randomizzato
if(List_party.get(i).getId()==Id_rooms.get(0))
{
// popolo la variabile class_party
second=new Class_party(List_party.get(i).getId(),List_party.get(i).getUser1(),List_party.get(i).getFlag(),start,correct_end,accessible);
}
}
matchFound = false;
//inserisco l'utente e il numero di giocatori = 2
currentwithID = new Class_user(uID,uSer,matchFound);
current=new Class_user(uSer,0);
second.setUser2(current);
second.setNumberOfPlayers(2);
//ora reinserisco tutto nel figlio che ha come ID, quello della stanza selezionata
Matchmaking.child(second.getId()).setValue(second);
Accounts.child(uID).setValue(currentwithID);
}
}
public ArrayList<Integer> Generation()
{
ArrayList<Integer> tmp = new ArrayList<>();
Collections.shuffle(mFlag);
for(int i=0; i<=10; i++) //3 momentaneamente
{
tmp.add(mFlag.get(i));
}
Toast.makeText(HomeActivity.this,"Domande generate",Toast.LENGTH_LONG).show();
return tmp;
}
首先,我設置了所有變量。 uSer 是我從 google auth 獲得的名稱。 如果房間可用為 0,我創建空房間,生成標志列表(隨機 10 個標志)並插入它是一個類的孩子:
public class Class_party {
public Class_user user1, user2;
public int numberOfPlayers;
public String id;
public ArrayList<Integer> value;
public boolean start,correct_end,accessible;
public Class_party(String id,Class_user user1, ArrayList<Integer> value, Boolean start,Boolean correct_end, Boolean accessible) {
this.value = value;
this.user1 = user1;
this.numberOfPlayers = 1;
this.id = id;
this.start = start;
this.accessible = accessible;
this.correct_end = correct_end;
user2 = null;
}
public Class_party() {
}
public Class_user getUser1() {
return user1;
}
public void setUser1(Class_user user1) {
this.user1 = user1;
}
public Class_user getUser2() {
return user2;
}
public void setUser2(Class_user user2) {
this.user2 = user2;
}
public int getNumberOfPlayers() {
return numberOfPlayers;
}
public void setNumberOfPlayers(int numberOfPlayers) {
this.numberOfPlayers = numberOfPlayers;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public ArrayList<Integer> getFlag() { return value; }
public void setValue(ArrayList<Integer> value) {
this.value=value;
如果我找到一個匹配項或匹配項列表,我會選擇一個隨機匹配項,我找到它,並使用這個特定字符串在 FirebaseDatabase 中設置第二個用戶: Matchmaking.child(second.getId()).setValue(second);
現在,我們得到了一個名為 MULTIPLAYER 的新活動:
在此活動中,我創建了多人游戲,但讓我們看看如何獲取所有信息並設置所有變量。 首先,我使用 onDataChange 來獲取比賽中的每一個變化。
Matchmaking.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
//prendo tutte le tabelle e le aggiungo a list_party
for (DataSnapshot ds : dataSnapshot.getChildren()) {
ct = ds.getValue(Class_party.class);
List_party.add(ct);
}
// mi prendo la partita che mi interessa
for (int i = 0; i < List_party.size(); i++) {
if (List_party.get(i).getId() == intent_id) {
ct = List_party.get(i);
}
}
//controllo che gli utenti collegati siano due e che la partita non sia cominciata ne finita in modo anomalo
if (ct.getNumberOfPlayers() == 2 && !ct.getAccessible() && ct.getCorrect_end() && !ct.getStart()) {
//mi scarico le bandiere che sono state scelte alla creazione della ROOM
FlagsFromDB = ct.getFlag();
//passo dal Layout di Waiting a quello iniziale
switchToScreen(R.id.screen_intro);
matchFound=true;
Toast.makeText(MpMultiplayer.this, "Match Found", Toast.LENGTH_SHORT).show();
//imposto il match trovato = true
currentwithID.setMatch_found(true);
//aggiorno la tabella
Accounts.child(uID).setValue(currentwithID);
}
//se la partita è cominciata e il numero di giocatori è uguale a due e match_found = true
if (ct.getStart() && ct.getNumberOfPlayers()==2 && matchFound) {
//dico che la room è stata creata
roomcreated = true;
//ora il gioco comincia e cambio di layout
switchToScreen(R.id.screen_game);
Popolate();
}
//se qualcuno esce prima del previsto e la partita è già cominciata
if(!ct.getCorrect_end() && roomcreated)
{
//assegno automaticamente all'utente 500 punti
points += 500;
timer1.cancel();
mName.setText(intent_user + " You Won!");
mName.setTextSize(25);
mPoints.setText(new Integer(points).toString());
switchToScreen(R.id.screen_score);
Toast.makeText(MpMultiplayer.this, "The player LEFT the game", Toast.LENGTH_SHORT).show();
}
//se l'utente si è scollegato e la partita non è ancora cominciata
if(!ct.getCorrect_end() && !roomcreated)
{ //assegno automaticamente 100 punti
points += 100;
mName.setText(intent_user + "You Won!");
mName.setTextSize(25);
mPoints.setText(new Integer(points).toString());
switchToScreen(R.id.screen_score);
Toast.makeText(MpMultiplayer.this, "The player LEFT the game", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
當兩個用戶之一按下按鈕啟動時,我使用此方法更改數據庫變量:
void ChangeStartValue(){
Room = FirebaseDatabase.getInstance().getReference("Matchmaking");
try {
ct.setStart(true);
Room.child(ct.getId()).setValue(ct);
} catch (Exception e) {
e.printStackTrace();
}
}
void switchToScreen(int screenId) {
// make the requested screen visible; hide all others.
for (int id : SCREENS) {
findViewById(id).setVisibility(screenId == id ? View.VISIBLE : View.GONE);
}
}
這是當用戶完成比賽並按下 backToMainMenu 按鈕時:
private View.OnClickListener backtomainmenu = new View.OnClickListener() {
@Override
public void onClick(final View view) {
try {
if(ct.getNumberOfPlayers()==2){
ct.setNumberOfPlayers(ct.getNumberOfPlayers()-1);
Room.child(ct.getId()).setValue(ct);
Accounts.child(uID).child("match_found").setValue(false);
}
else
if (ct.getNumberOfPlayers()==1 && ct.getStart()&& ct.getCorrect_end()){
Room.child(ct.getId()).removeValue();
Accounts.child(uID).child("match_found").setValue(false); }
else
if(ct.getNumberOfPlayers()==1 && ct.getStart() && !ct.getCorrect_end()){
Room.child(ct.getId()).removeValue();
Accounts.child(uID).child("match_found").setValue(false);}
else
if(ct.getNumberOfPlayers()==1 && !ct.getStart() && !ct.getCorrect_end()) {
Room.child(ct.getId()).removeValue();
Accounts.child(uID).child("match_found").setValue(false);}
} catch (Exception e) {
e.printStackTrace();
}
finish();
}
};
如果用戶想不完成比賽就出去:
@Override
//in caso l'utente voglia uscire
public void onBackPressed() {
backpress = (backpress + 1);
// se preme una volta compare il toast
if (backpress >= 1 && backpress < 2)
Toast.makeText(getApplicationContext(), " Press Back again to Exit ", Toast.LENGTH_SHORT).show();
//se preme per più di una volta esce
if (backpress > 1) {
try {
//se i giocatori sono più di due, setto i giocatori ad 1 e Correct End a false
if(ct.getNumberOfPlayers()>=2){
ct.setNumberOfPlayers(ct.getNumberOfPlayers()-1);
ct.setCorrect_end(false);
//aggiorno poi le tabelle
Room.child(ct.getId()).setValue(ct);
Accounts.child(uID).child("match_found").setValue(false);
}
else
//se il giocatore è da solo
if(ct.getNumberOfPlayers()<2)
{
//cancello il figlio dalla tabella matchmaking
Room.child(ct.getId()).removeValue();
Accounts.child(uID).child("match_found").setValue(false);
}
} catch (Exception e) {
e.printStackTrace();
}
//se poi la partita era già cominciata, cancello il timer per evitare errori
if(roomcreated)
timer1.cancel();
//chiudo l'activity
this.finish();
}
}
我希望這會幫助你:D 如果你有任何問題,我會回答你:D
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.