Hey Leute,
das könnte ein etwas längerer Beitrag werden, aber ich möchte gern alles beschreiben.
Also ich bin dabei, ein online Multiplayer Game zu entwickeln, welches über Firebase laufen soll. Hierzu wird Firestore und die Realtime Database verwendet.
Ebenfalls wird eine Modelklasse verwendet mit den Werten:
gameID = null;
gameState = 0;
myScore = 0;
friendScore = 0;
lastButtonPressed = null;
turn = false;
howBig = 0;
howBigFriend = 0;
listNumber = null;
listBuchstabe = null;
Und noch ein paar andere Werte, die aber hier nicht relevant sind.
Wenn der Multiplayermodus gestartet wird, werden die werte bspw. Wie folgt initialisiert:
localGame.setGameState(0);
Sorry, dass ich das alles so ausführlich mache, aber nicht das es zu Missverständnissen kommt
Ebenfalls ist eine HashMap und FirebaseFirestore vorhanden:
FirebaseFirestore gameSync = FirebaseFirestore.getInstance();
HashMap<String, Object> updateGame = new HashMap<>();
Nach der Initialisierung kommt folgendes statement:
updateGame.put("gameState", localGame.getGameState());
Natürlich wird das für jeden wichtigen Wert wiederholt, um so diese HashMap an eine Collection zu übergeben:
gameSync.collection("Active Game").document("G" + localGame.getGameID()).update(updateGame);
Anschließend kommt dieser Code:
gameSync.collection("Active Game").document("G" + localGame.getGameID()).addSnapshotListener((docume ntSnapshot, e) -> {
if (documentSnapshot != null && documentSnapshot.exists() && documentSnapshot.getData() != null) {
if ((long) documentSnapshot.getData().get("gameIsActive") == (long) 2) {
HashMap<String, Object> gameInstance = new HashMap<>(documentSnapshot.getData());
if (gameInstance.get("isWaiting") != null && (long) gameInstance.get("isWaiting") == 2) {
//reset game for next round
{
Hier wird dann alles zurückgesetzt und wieder an die collection übergeben.
}
}else if (gameInstance.get("gameState") != null && (long) gameInstance.get("gameState") > localGame.getGameState() && !isStopGame) {
localGame.setLastButtonPressed((long) gameInstance.get("lastButtonPressed"));
//localGame.setHowBigFriend((int) gameInstance.get("howBig"));
localGame.setGameState((long) gameInstance.get("gameState") - 1);
updateUI();
}
updateUi() sieht dann so aus:
private void updateUI() {
switch (localGame.getLastButtonPressed().intValue()) {
case 1:
clickedButton(binding.b11, localGame.getLastButtonPressed().intValue(), true, 0, localGame.getHowBigFriend());
break;
mit ein paar mehr cases
clickedButton():
void clickedButton(Button button, int id, boolean isUiUpdate, int zahl, int bigHow) {
if (localGame.isTurn()) {
if (localGame.getGameState() % 2 == 0) {
Hier wird dann abgefragt, was wann passiert. Das funktioniert soweit auch ganz okay und unten kommt dann:
buttonNumbers[zahl] = howBig;
arrayResult[zahl] = "O";
button.setText("O");
list.set(zahl, howBig);
listGesetzt.set(zahl, "O");
updateGame.put("howBig", howBig);
updateGame.put("howBigFriend", howBigFriend);
weiter = true;
}
Ich starte das Spiel also und starte eine neue Runde. In Firestore sieht es nun so aus:
gameID"22222"
gameIsActiveExtreme 2
gameState0
howBig 0
howBigFriend 0
isWaiting0
lastButtonPressed0
//die zwei Listen werden natürlich anders dargestellt, aber so sieht es übersichtlicher aus
listBuchstaben {“”,””,””,””,””,””,””,””}
listNumbers {0,0,0,0,0,0,0,0}
playerFriend"Friend"
playerHost"me"
timeStampNovember 18, 2021 at 11:37:09 AM UTC+1(timestamp)
turn"me"
“me” macht einen Zug und die Db ändert sich wie folgt:
gameID"22222"
gameIsActiveExtreme 2
gameState 2
howBig 3
howBigFriend 0
isWaiting0
lastButtonPressed1
listBuchstaben {“I”,””,””,””,””,””,””,””}
listNumbers {3,0,0,0,0,0,0,0} //die 3 gibt den Wert von “howBig” an. Ist für die Gewinnerabfrage notwendig
playerFriend"Friend"
playerHost"me"
timeStampNovember 18, 2021 at 11:37:09 AM UTC+1
turn"Friend"
Hier aber das erste Problem. Auf dem “me” smartphone wird der Wert in der richtigen Größe angezeigt. Um das zu erklären. Beide sollen das identische Spielfeld sehen. Beim Player “me” ist das erste Feld, welches er gedrückt hat, richtig dargestellt. Es gibt 6 Größen und im ersten Feld ist die Größe 3 dargestellt. Beim Freund wird allerdings die Größe 6 dargestellt.
Player “Friend” klickt nun mit der größe 5 auf das letzte Feld und die Db sieht nun so aus:
gameID"22222"
gameIsActiveExtreme 2
gameState 3
howBig 5
howBigFriend0
isWaiting0
lastButtonPressed 9
listBuchstaben {“”,””,””,””,””,””,””,”U”}
listNumbers {0,0,0,0,0,0,0,5}
playerFriend"Friend"
playerHost"me"
timeStampNovember 18, 2021 at 11:37:09 AM UTC+1
turn"me"
Wie ihr sehen könnt wurden die Werte von “me” gelöscht und jetzt sind nur noch die Werte von “friend” dargestellt. Wenn “me” wieder einen Zug macht ändert sich die Db wie folgt:
gameID"22222"
gameIsActiveExtreme 2
gameState 4
howBig 4
howBigFriend0
isWaiting0
lastButtonPressed 5
listBuchstaben {“I”,””,””,”I”,””,””,””,”U”}
listNumbers {3,0,0,4,0,0,0,3}
playerFriend"Friend"
playerHost"me"
timeStampNovember 18, 2021 at 11:49:37 AM UTC+1
turn"Friend"
Jetzt hat er wieder die Werte von beiden, nur hat er bei listNumbers den letzten Wert – warum auch immer – geändert.
Wenn “Friend” wieder einen Zug macht, sehen die zwei Listen wieder so aus:
listBuchstaben {“”,””,”U”,””,”I”,””,””,”U”}
listNumbers {0,0,6,0,5,0,0,5}
Es passt also im Endeffekt schon irgendwie, aber alles in allem macht es nicht das, was es soll. Mal abgesehen davon, dass die Darstellung nicht passt, wie arbeitet man denn richtig mit Listen und Firestore?
Ich mache da jetzt schon gefühlte Ewigkeiten herum und komme einfach nicht auf den Fehler. Hat jemand Erfahrung damit gemacht oder weiß was zu tun ist?
Falls ihr noch irgendwelche Informationen benötigt, gebt bitte bescheid.
Hoffentlich war das alles nicht zu viel und es ist ein bisschen einleuchtend, was hier das Problem ist
Danke schon einmal im Voraus
das könnte ein etwas längerer Beitrag werden, aber ich möchte gern alles beschreiben.
Also ich bin dabei, ein online Multiplayer Game zu entwickeln, welches über Firebase laufen soll. Hierzu wird Firestore und die Realtime Database verwendet.
Ebenfalls wird eine Modelklasse verwendet mit den Werten:
gameID = null;
gameState = 0;
myScore = 0;
friendScore = 0;
lastButtonPressed = null;
turn = false;
howBig = 0;
howBigFriend = 0;
listNumber = null;
listBuchstabe = null;
Und noch ein paar andere Werte, die aber hier nicht relevant sind.
Wenn der Multiplayermodus gestartet wird, werden die werte bspw. Wie folgt initialisiert:
localGame.setGameState(0);
Sorry, dass ich das alles so ausführlich mache, aber nicht das es zu Missverständnissen kommt
Ebenfalls ist eine HashMap und FirebaseFirestore vorhanden:
FirebaseFirestore gameSync = FirebaseFirestore.getInstance();
HashMap<String, Object> updateGame = new HashMap<>();
Nach der Initialisierung kommt folgendes statement:
updateGame.put("gameState", localGame.getGameState());
Natürlich wird das für jeden wichtigen Wert wiederholt, um so diese HashMap an eine Collection zu übergeben:
gameSync.collection("Active Game").document("G" + localGame.getGameID()).update(updateGame);
Anschließend kommt dieser Code:
gameSync.collection("Active Game").document("G" + localGame.getGameID()).addSnapshotListener((docume ntSnapshot, e) -> {
if (documentSnapshot != null && documentSnapshot.exists() && documentSnapshot.getData() != null) {
if ((long) documentSnapshot.getData().get("gameIsActive") == (long) 2) {
HashMap<String, Object> gameInstance = new HashMap<>(documentSnapshot.getData());
if (gameInstance.get("isWaiting") != null && (long) gameInstance.get("isWaiting") == 2) {
//reset game for next round
{
Hier wird dann alles zurückgesetzt und wieder an die collection übergeben.
}
}else if (gameInstance.get("gameState") != null && (long) gameInstance.get("gameState") > localGame.getGameState() && !isStopGame) {
localGame.setLastButtonPressed((long) gameInstance.get("lastButtonPressed"));
//localGame.setHowBigFriend((int) gameInstance.get("howBig"));
localGame.setGameState((long) gameInstance.get("gameState") - 1);
updateUI();
}
updateUi() sieht dann so aus:
private void updateUI() {
switch (localGame.getLastButtonPressed().intValue()) {
case 1:
clickedButton(binding.b11, localGame.getLastButtonPressed().intValue(), true, 0, localGame.getHowBigFriend());
break;
mit ein paar mehr cases
clickedButton():
void clickedButton(Button button, int id, boolean isUiUpdate, int zahl, int bigHow) {
if (localGame.isTurn()) {
if (localGame.getGameState() % 2 == 0) {
Hier wird dann abgefragt, was wann passiert. Das funktioniert soweit auch ganz okay und unten kommt dann:
buttonNumbers[zahl] = howBig;
arrayResult[zahl] = "O";
button.setText("O");
list.set(zahl, howBig);
listGesetzt.set(zahl, "O");
updateGame.put("howBig", howBig);
updateGame.put("howBigFriend", howBigFriend);
weiter = true;
}
Ich starte das Spiel also und starte eine neue Runde. In Firestore sieht es nun so aus:
gameID"22222"
gameIsActiveExtreme 2
gameState0
howBig 0
howBigFriend 0
isWaiting0
lastButtonPressed0
//die zwei Listen werden natürlich anders dargestellt, aber so sieht es übersichtlicher aus
listBuchstaben {“”,””,””,””,””,””,””,””}
listNumbers {0,0,0,0,0,0,0,0}
playerFriend"Friend"
playerHost"me"
timeStampNovember 18, 2021 at 11:37:09 AM UTC+1(timestamp)
turn"me"
“me” macht einen Zug und die Db ändert sich wie folgt:
gameID"22222"
gameIsActiveExtreme 2
gameState 2
howBig 3
howBigFriend 0
isWaiting0
lastButtonPressed1
listBuchstaben {“I”,””,””,””,””,””,””,””}
listNumbers {3,0,0,0,0,0,0,0} //die 3 gibt den Wert von “howBig” an. Ist für die Gewinnerabfrage notwendig
playerFriend"Friend"
playerHost"me"
timeStampNovember 18, 2021 at 11:37:09 AM UTC+1
turn"Friend"
Hier aber das erste Problem. Auf dem “me” smartphone wird der Wert in der richtigen Größe angezeigt. Um das zu erklären. Beide sollen das identische Spielfeld sehen. Beim Player “me” ist das erste Feld, welches er gedrückt hat, richtig dargestellt. Es gibt 6 Größen und im ersten Feld ist die Größe 3 dargestellt. Beim Freund wird allerdings die Größe 6 dargestellt.
Player “Friend” klickt nun mit der größe 5 auf das letzte Feld und die Db sieht nun so aus:
gameID"22222"
gameIsActiveExtreme 2
gameState 3
howBig 5
howBigFriend0
isWaiting0
lastButtonPressed 9
listBuchstaben {“”,””,””,””,””,””,””,”U”}
listNumbers {0,0,0,0,0,0,0,5}
playerFriend"Friend"
playerHost"me"
timeStampNovember 18, 2021 at 11:37:09 AM UTC+1
turn"me"
Wie ihr sehen könnt wurden die Werte von “me” gelöscht und jetzt sind nur noch die Werte von “friend” dargestellt. Wenn “me” wieder einen Zug macht ändert sich die Db wie folgt:
gameID"22222"
gameIsActiveExtreme 2
gameState 4
howBig 4
howBigFriend0
isWaiting0
lastButtonPressed 5
listBuchstaben {“I”,””,””,”I”,””,””,””,”U”}
listNumbers {3,0,0,4,0,0,0,3}
playerFriend"Friend"
playerHost"me"
timeStampNovember 18, 2021 at 11:49:37 AM UTC+1
turn"Friend"
Jetzt hat er wieder die Werte von beiden, nur hat er bei listNumbers den letzten Wert – warum auch immer – geändert.
Wenn “Friend” wieder einen Zug macht, sehen die zwei Listen wieder so aus:
listBuchstaben {“”,””,”U”,””,”I”,””,””,”U”}
listNumbers {0,0,6,0,5,0,0,5}
Es passt also im Endeffekt schon irgendwie, aber alles in allem macht es nicht das, was es soll. Mal abgesehen davon, dass die Darstellung nicht passt, wie arbeitet man denn richtig mit Listen und Firestore?
Ich mache da jetzt schon gefühlte Ewigkeiten herum und komme einfach nicht auf den Fehler. Hat jemand Erfahrung damit gemacht oder weiß was zu tun ist?
Falls ihr noch irgendwelche Informationen benötigt, gebt bitte bescheid.
Hoffentlich war das alles nicht zu viel und es ist ein bisschen einleuchtend, was hier das Problem ist
Danke schon einmal im Voraus
Comment