Feat: Implémenter la boîte de dialogue de fin de partie multijoueur stylisée
Remplace le comportement précédent à la fin d'une partie multijoueur par une boîte de dialogue claire et stylisée. - Ajout d'une AlertDialog dans MultiplayerActivity affichée via showEndGameDialog lorsque la partie se termine (déclenché par handleMultiplayerGameOver). - La boîte de dialogue indique si le joueur a gagné, perdu ou fait match nul. - Inclut un bouton unique ('Menu principal') pour revenir à MainActivity, fermer l'activité multijoueur et clore la connexion WebSocket. - Création d'un layout personnalisé (dialog_multiplayer_game_over.xml) pour cette boîte de dialogue afin qu'elle corresponde au style visuel des dialogues existants en mode solo (par exemple, dialog_game_over.xml). - Mise à jour de showEndGameDialog pour charger et utiliser ce layout personnalisé au lieu des méthodes standard d'AlertDialog.Builder pour le titre/message/bouton. - Ajout des ressources string nécessaires pour les titres, messages et textes des boutons de la nouvelle boîte de dialogue.
This commit is contained in:
parent
1842213cac
commit
2b5dc6b85f
@ -7,12 +7,15 @@ import android.animation.AnimatorSet;
|
|||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
@ -577,40 +580,13 @@ public class MultiplayerActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
// Met à jour l'UI sur le thread principal
|
// Met à jour l'UI sur le thread principal
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
showGameOverMessage(finalState); // Affiche le message de fin
|
showEndGameDialog(finalState);
|
||||||
disableSwipe(); // Désactive les swipes
|
disableSwipe(); // Désactive les swipes
|
||||||
closeWebSocket(); // Ferme la connexion
|
closeWebSocket(); // Ferme la connexion
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Affiche le message approprié dans le TextView de statut en fonction du résultat de la partie.
|
|
||||||
* Gère les cas de victoire, défaite, match nul, et victoire par forfait (heuristique).
|
|
||||||
*
|
|
||||||
* @param finalState L'état final du jeu {@link GameStateResponse}.
|
|
||||||
*/
|
|
||||||
private void showGameOverMessage(GameStateResponse finalState) {
|
|
||||||
String endMessage;
|
|
||||||
boolean wonByForfeit = false;
|
|
||||||
// Heuristique pour détecter une victoire par forfait (si on gagne sans atteindre l'objectif)
|
|
||||||
// Cela nécessite que le serveur attribue correctement le gagnant en cas de déconnexion adverse.
|
|
||||||
if (myPlayerId != null && myPlayerId.equals(finalState.getWinnerId()) && finalState.getMyScore(myPlayerId) < finalState.getTargetScore()) {
|
|
||||||
wonByForfeit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Choisit le message en fonction du résultat
|
|
||||||
if ("DRAW".equals(finalState.getWinnerId())) { endMessage = getString(R.string.game_over_draw); }
|
|
||||||
else if (wonByForfeit) { endMessage = "Opponent disconnected - You Win!"; }
|
|
||||||
else if (myPlayerId != null && myPlayerId.equals(finalState.getWinnerId())) { endMessage = getString(R.string.game_over_won); }
|
|
||||||
else if (opponentPlayerId != null && opponentPlayerId.equals(finalState.getWinnerId())) { endMessage = getString(R.string.game_over_lost); }
|
|
||||||
else { endMessage = getString(R.string.game_over_generic); } // Cas générique
|
|
||||||
|
|
||||||
// Affiche le message et efface l'indicateur de tour
|
|
||||||
statusTextMulti.setText(endMessage);
|
|
||||||
turnIndicatorMulti.setText("");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronise la vue du plateau de jeu ({@link #boardGridLayoutMulti}) avec l'état
|
* Synchronise la vue du plateau de jeu ({@link #boardGridLayoutMulti}) avec l'état
|
||||||
* du plateau fourni.
|
* du plateau fourni.
|
||||||
@ -968,6 +944,69 @@ public class MultiplayerActivity extends AppCompatActivity {
|
|||||||
statusTextMulti.setText(myTurn ? "" : getString(R.string.multiplayer_status_waiting_opponent));
|
statusTextMulti.setText(myTurn ? "" : getString(R.string.multiplayer_status_waiting_opponent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Affiche une boîte de dialogue indiquant la fin de la partie multijoueur (Victoire, Défaite, Égalité)
|
||||||
|
* en utilisant un layout personnalisé pour correspondre au style des dialogues solo.
|
||||||
|
* Propose un bouton pour revenir à l'écran principal (MainActivity).
|
||||||
|
*
|
||||||
|
* @param finalState L'état final du jeu reçu du serveur.
|
||||||
|
*/
|
||||||
|
private void showEndGameDialog(GameStateResponse finalState) {
|
||||||
|
if (isFinishing() || finalState == null || myPlayerId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Détermine le résultat
|
||||||
|
boolean isWin = myPlayerId.equals(finalState.getWinnerId());
|
||||||
|
boolean isDraw = "DRAW".equals(finalState.getWinnerId());
|
||||||
|
|
||||||
|
String titleText;
|
||||||
|
String messageText;
|
||||||
|
|
||||||
|
if (isWin) {
|
||||||
|
titleText = getString(R.string.game_over_won);
|
||||||
|
messageText = getString(R.string.multiplayer_win_message);
|
||||||
|
} else if (isDraw) {
|
||||||
|
titleText = getString(R.string.game_over_draw);
|
||||||
|
messageText = getString(R.string.multiplayer_draw_message);
|
||||||
|
} else {
|
||||||
|
titleText = getString(R.string.game_over_lost);
|
||||||
|
messageText = getString(R.string.multiplayer_loss_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Création du Builder et inflation du layout personnalisé
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
|
LayoutInflater inflater = getLayoutInflater();
|
||||||
|
View dialogView = inflater.inflate(R.layout.dialog_multiplayer_game_over, null); // Utilise le nouveau layout
|
||||||
|
builder.setView(dialogView);
|
||||||
|
builder.setCancelable(false);
|
||||||
|
|
||||||
|
// Récupération des vues DANS le layout personnalisé
|
||||||
|
TextView titleTextView = dialogView.findViewById(R.id.dialogTitleMultiGameOver);
|
||||||
|
TextView messageTextView = dialogView.findViewById(R.id.dialogMessageMultiGameOver);
|
||||||
|
Button mainMenuButton = dialogView.findViewById(R.id.dialogButtonMainMenu);
|
||||||
|
|
||||||
|
// Définition du contenu des vues
|
||||||
|
titleTextView.setText(titleText);
|
||||||
|
messageTextView.setText(messageText);
|
||||||
|
|
||||||
|
// Création de la boîte de dialogue AVANT de définir l'OnClickListener du bouton
|
||||||
|
final AlertDialog dialog = builder.create();
|
||||||
|
|
||||||
|
// Configuration du bouton DANS le layout personnalisé
|
||||||
|
mainMenuButton.setOnClickListener(v -> {
|
||||||
|
// Action lorsque l'utilisateur clique sur le bouton "Menu principal"
|
||||||
|
dialog.dismiss();
|
||||||
|
closeWebSocket();
|
||||||
|
Intent intent = new Intent(MultiplayerActivity.this, MainActivity.class);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||||
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog.show(); // Affiche la boîte de dialogue
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Énumération privée représentant les quatre directions de mouvement possibles.
|
* Énumération privée représentant les quatre directions de mouvement possibles.
|
||||||
*/
|
*/
|
||||||
|
@ -12,17 +12,20 @@
|
|||||||
android:id="@+id/multiplayerInfoPanel"
|
android:id="@+id/multiplayerInfoPanel"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="36dp"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:padding="@dimen/padding_general"
|
android:padding="@dimen/padding_general"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/myScoreLabelMulti"
|
android:id="@+id/myScoreLabelMulti"
|
||||||
style="@style/ScoreLabelStyle"
|
style="@style/ScoreLabelStyle"
|
||||||
android:layout_weight="1"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="@dimen/margin_between_elements"
|
android:layout_marginEnd="@dimen/margin_between_elements"
|
||||||
|
android:layout_weight="1"
|
||||||
android:text="Mon Score:\n0" />
|
android:text="Mon Score:\n0" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@ -30,17 +33,19 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:paddingStart="8dp" android:paddingEnd="8dp"
|
android:paddingStart="8dp"
|
||||||
|
android:paddingEnd="8dp"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
android:textColor="@color/text_tile_low"
|
android:textColor="@color/text_tile_low"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
tools:text="À votre tour" />
|
||||||
tools:text="À votre tour"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/opponentScoreLabelMulti"
|
android:id="@+id/opponentScoreLabelMulti"
|
||||||
style="@style/ScoreLabelStyle"
|
style="@style/ScoreLabelStyle"
|
||||||
android:layout_weight="1"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/margin_between_elements"
|
android:layout_marginStart="@dimen/margin_between_elements"
|
||||||
|
android:layout_weight="1"
|
||||||
android:text="Adversaire:\n0" />
|
android:text="Adversaire:\n0" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
35
app/src/main/res/layout/dialog_multiplayer_game_over.xml
Normal file
35
app/src/main/res/layout/dialog_multiplayer_game_over.xml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="24dp"
|
||||||
|
android:background="@drawable/dialog_background">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/dialogTitleMultiGameOver"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/game_over_title" android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/text_tile_low"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_marginBottom="8dp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/dialogMessageMultiGameOver"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/multiplayer_win_message" android:textSize="16sp"
|
||||||
|
android:textColor="@color/text_tile_low"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_marginBottom="16dp"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/dialogButtonMainMenu"
|
||||||
|
style="@style/ButtonStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1" android:layout_marginStart="0dp" android:layout_marginEnd="0dp" android:text="@string/return_to_main_menu" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -122,4 +122,9 @@
|
|||||||
<string name="game_over_won">You Won!</string>
|
<string name="game_over_won">You Won!</string>
|
||||||
<string name="game_over_lost">You Lost.</string>
|
<string name="game_over_lost">You Lost.</string>
|
||||||
<string name="game_over_generic">Game Over!</string>
|
<string name="game_over_generic">Game Over!</string>
|
||||||
|
|
||||||
|
<string name="return_to_main_menu">Main menu</string>
|
||||||
|
<string name="multiplayer_win_message">Congratulations! You won the game.</string>
|
||||||
|
<string name="multiplayer_loss_message">Too bad! Your opponent was better this time.</string>
|
||||||
|
<string name="multiplayer_draw_message">It\'s a draw! A hard-fought game.</string>
|
||||||
</resources>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user