我已经在这个多人游戏大厅工作了几天,现在我正在挣扎让我告诉你。
无论如何,我正在纸上解决问题,因此我可以逐步实现自己的目标。到达我的大厅的简单步骤如下:
所以这是我当前的过程,但是我不确定是否缺少任何步骤。当然,这些步骤后面有很多代码,但这只是事物的本质。
我的问题是如何制作游戏,以便当用户创建游戏时,如何将其正确添加到实时的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<>();
答案 0 :(得分:1)
我在Firebase中做过类似的游戏。我通常使用onDataChange()
方法来验证每个客户端都知道gameRoom
的列表已更改。
用户单击多人游戏
如果已经存在一个空房间,则客户可以进入。
如果其他房间都已满或没有空房间,则客户端会创建一个房间
配对过程完成后,让我们开始比赛
当比赛结束时,第一个客户端修改用户变量,第二个客户端删除整个房间子级。
如果要创建动态数组列表,则必须使用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