Fix: Amélioration gestion états Victoire et Game Over
- Ajout d'un enum GameFlowState (PLAYING, WON_DIALOG_SHOWN, GAME_OVER) dans MainActivity. - handleSwipe n'accepte les mouvements que si l'état est PLAYING. - Lors de la première victoire (>= 2048), affiche une nouvelle boîte de dialogue proposant 'Continuer' ou 'Nouvelle Partie'. - Si 'Continuer', l'état passe à WON_DIALOG_SHOWN, permettant au jeu de continuer sans réafficher la dialogue de victoire. - En cas de Game Over, l'état passe à GAME_OVER et le jeu est bloqué. - startNewGame réinitialise l'état à PLAYING. - loadGame détermine l'état initial basé sur le jeu chargé. - Mise à jour des strings pour les nouvelles dialogues.
This commit is contained in:
parent
9d8d2c5c62
commit
b32d1e0986
@ -26,6 +26,7 @@ package legion.muyue.best2048;
|
|||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
@ -61,14 +62,17 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
private GameStats gameStats; // Instance pour gérer les stats
|
private GameStats gameStats; // Instance pour gérer les stats
|
||||||
private static final int BOARD_SIZE = 4;
|
private static final int BOARD_SIZE = 4;
|
||||||
|
|
||||||
|
// --- State Management ---
|
||||||
|
private boolean statisticsVisible = false;
|
||||||
|
private enum GameFlowState { PLAYING, WON_DIALOG_SHOWN, GAME_OVER } // Nouvel état de jeu
|
||||||
|
private GameFlowState currentGameState = GameFlowState.PLAYING; // Initialisation
|
||||||
|
|
||||||
// --- Preferences ---
|
// --- Preferences ---
|
||||||
private SharedPreferences preferences;
|
private SharedPreferences preferences;
|
||||||
private static final String PREFS_NAME = "Best2048_Prefs";
|
private static final String PREFS_NAME = "Best2048_Prefs";
|
||||||
private static final String HIGH_SCORE_KEY = "high_score";
|
private static final String HIGH_SCORE_KEY = "high_score";
|
||||||
private static final String GAME_STATE_KEY = "game_state";
|
private static final String GAME_STATE_KEY = "game_state";
|
||||||
|
|
||||||
private boolean statisticsVisible = false;
|
|
||||||
|
|
||||||
// --- Activity Lifecycle ---
|
// --- Activity Lifecycle ---
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -139,16 +143,22 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
*/
|
*/
|
||||||
private void initializeGameAndStats() {
|
private void initializeGameAndStats() {
|
||||||
preferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
|
preferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
|
||||||
gameStats = new GameStats(this); // Crée et charge les stats (y.c. overallHighScore)
|
gameStats = new GameStats(this);
|
||||||
loadGame(); // Charge l'état du jeu, crée un nouveau si nécessaire, synchronise le HS
|
loadGame(); // Charge jeu et met à jour high score
|
||||||
updateUI(); // Affiche l'état chargé ou nouveau
|
updateUI();
|
||||||
|
if (game == null) {
|
||||||
// Si loadGame a résulté en une nouvelle partie (game==null avant ou deserialize a échoué),
|
startNewGame(); // Assure une partie valide si chargement échoue
|
||||||
// on s'assure que les stats de la partie en cours sont bien initialisées.
|
|
||||||
if (game == null || preferences.getString(GAME_STATE_KEY, null) == null) {
|
|
||||||
startNewGame(); // Assure un état cohérent si aucun jeu n'a été chargé
|
|
||||||
} else {
|
} else {
|
||||||
// Le timer de la partie chargée sera (re)démarré dans onResume
|
// Détermine l'état initial basé sur le jeu chargé
|
||||||
|
if (game.isGameOver()) {
|
||||||
|
currentGameState = GameFlowState.GAME_OVER;
|
||||||
|
} else if (game.isGameWon()) {
|
||||||
|
// Si on charge une partie déjà gagnée, on considère qu'on a déjà vu la dialog
|
||||||
|
currentGameState = GameFlowState.WON_DIALOG_SHOWN;
|
||||||
|
} else {
|
||||||
|
currentGameState = GameFlowState.PLAYING;
|
||||||
|
// Redémarre le timer dans onResume
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,72 +276,119 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Traite un geste de swipe : appelle la logique de jeu, met à jour les statistiques,
|
* Traite un geste de swipe de l'utilisateur sur le plateau de jeu.
|
||||||
* ajoute une nouvelle tuile, met à jour l'UI et vérifie les conditions de fin de partie.
|
* 1. Tente d'effectuer le mouvement dans l'objet Game.
|
||||||
* @param direction Direction du swipe.
|
* 2. Si le mouvement a modifié le plateau (boardChanged == true) :
|
||||||
|
* - Met à jour les statistiques (mouvements, fusions, score, etc.).
|
||||||
|
* - Ajoute une nouvelle tuile aléatoire.
|
||||||
|
* - Met à jour l'affichage (UI).
|
||||||
|
* 3. Vérifie l'état du jeu (gagné ou perdu) APRÈS la tentative de mouvement,
|
||||||
|
* que le plateau ait changé ou non. C'est la correction clé.
|
||||||
|
* 4. Affiche les boîtes de dialogue appropriées (victoire, défaite).
|
||||||
|
*
|
||||||
|
* @param direction La direction du swipe détecté (UP, DOWN, LEFT, RIGHT).
|
||||||
*/
|
*/
|
||||||
private void handleSwipe(Direction direction) {
|
private void handleSwipe(Direction direction) {
|
||||||
if (game == null || gameStats == null || game.isGameOver() || game.isGameWon()) return;
|
// Si le jeu n'est pas initialisé ou s'il est DÉJÀ terminé, ignorer le swipe.
|
||||||
|
if (game == null || gameStats == null || currentGameState == GameFlowState.GAME_OVER) {
|
||||||
int scoreBefore = game.getCurrentScore();
|
return;
|
||||||
boolean boardChanged;
|
|
||||||
switch (direction) { /* ... appelle game.pushX() ... */
|
|
||||||
case UP: boardChanged = game.pushUp(); break;
|
|
||||||
case DOWN: boardChanged = game.pushDown(); break;
|
|
||||||
case LEFT: boardChanged = game.pushLeft(); break;
|
|
||||||
case RIGHT: boardChanged = game.pushRight(); break;
|
|
||||||
default: boardChanged = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stocker le score avant le mouvement pour calculer le delta
|
||||||
|
int scoreBefore = game.getCurrentScore();
|
||||||
|
// Indique si le mouvement a effectivement changé l'état du plateau
|
||||||
|
boolean boardChanged = false;
|
||||||
|
|
||||||
|
// --- 1. Tenter d'effectuer le mouvement ---
|
||||||
|
// Les méthodes pushX() de l'objet Game contiennent la logique de déplacement/fusion
|
||||||
|
// et appellent en interne checkWinCondition() et checkGameOverCondition()
|
||||||
|
// pour mettre à jour les états isGameWon() et isGameOver().
|
||||||
|
switch (direction) {
|
||||||
|
case UP:
|
||||||
|
boardChanged = game.pushUp();
|
||||||
|
break;
|
||||||
|
case DOWN:
|
||||||
|
boardChanged = game.pushDown();
|
||||||
|
break;
|
||||||
|
case LEFT:
|
||||||
|
boardChanged = game.pushLeft();
|
||||||
|
break;
|
||||||
|
case RIGHT:
|
||||||
|
boardChanged = game.pushRight();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- 2. Traiter les conséquences SI le plateau a changé ---
|
||||||
if (boardChanged) {
|
if (boardChanged) {
|
||||||
gameStats.recordMove(); // Met à jour stats mouvement
|
// Mettre à jour les statistiques liées au mouvement réussi
|
||||||
|
gameStats.recordMove();
|
||||||
int scoreAfter = game.getCurrentScore();
|
int scoreAfter = game.getCurrentScore();
|
||||||
int scoreDelta = scoreAfter - scoreBefore;
|
int scoreDelta = scoreAfter - scoreBefore;
|
||||||
if (scoreDelta > 0) {
|
if (scoreDelta > 0) {
|
||||||
gameStats.recordMerge(1); // Met à jour stats fusion (simplifié)
|
// Supposition simpliste : une augmentation de score implique au moins une fusion
|
||||||
// Met à jour le highScore dans Game et GameStats si nécessaire
|
gameStats.recordMerge(1);
|
||||||
|
// Vérifier et mettre à jour le meilleur score si nécessaire
|
||||||
if (scoreAfter > game.getHighestScore()) {
|
if (scoreAfter > game.getHighestScore()) {
|
||||||
game.setHighestScore(scoreAfter);
|
game.setHighestScore(scoreAfter); // Met à jour dans l'objet Game
|
||||||
gameStats.setHighestScore(scoreAfter); // Synchronise avec GameStats
|
gameStats.setHighestScore(scoreAfter); // Met à jour et sauvegarde dans GameStats
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Mettre à jour la tuile la plus haute atteinte
|
||||||
|
gameStats.updateHighestTile(game.getHighestTileValue());
|
||||||
|
|
||||||
gameStats.updateHighestTile(game.getHighestTileValue()); // Met à jour stat tuile max
|
// Ajouter une nouvelle tuile aléatoire sur le plateau
|
||||||
|
game.addNewTile();
|
||||||
|
|
||||||
game.addNewTile(); // Ajoute tuile
|
// Mettre à jour l'affichage complet du plateau et des scores
|
||||||
updateUI(); // Met à jour affichage
|
updateUI();
|
||||||
|
|
||||||
// Vérifie victoire/défaite après MAJ UI
|
}
|
||||||
if (game.isGameWon()) {
|
|
||||||
|
// --- 3. Vérifier l'état final du jeu (Gagné / Perdu) ---
|
||||||
|
// Cette vérification est faite APRÈS la tentative de mouvement,
|
||||||
|
// On vérifie aussi qu'on n'a pas DÉJÀ traité la fin de partie dans ce même appel.
|
||||||
|
if (currentGameState != GameFlowState.GAME_OVER) {
|
||||||
|
|
||||||
|
// a) Condition de Victoire (atteindre 2048 ou plus)
|
||||||
|
// On vérifie aussi qu'on était en train de jouer normalement (pas déjà gagné et décidé de continuer)
|
||||||
|
if (game.isGameWon() && currentGameState == GameFlowState.PLAYING) {
|
||||||
|
currentGameState = GameFlowState.WON_DIALOG_SHOWN; // Mettre à jour l'état de flux
|
||||||
|
// Enregistrer les statistiques de victoire
|
||||||
long timeTaken = System.currentTimeMillis() - gameStats.getCurrentGameStartTimeMs();
|
long timeTaken = System.currentTimeMillis() - gameStats.getCurrentGameStartTimeMs();
|
||||||
gameStats.recordWin(timeTaken);
|
gameStats.recordWin(timeTaken);
|
||||||
showGameWonDialog();
|
// Afficher la boîte de dialogue de victoire
|
||||||
|
showGameWonKeepPlayingDialog();
|
||||||
|
|
||||||
|
// b) Condition de Défaite (Game Over - pas de case vide ET pas de fusion possible)
|
||||||
|
// Cette condition est vérifiée seulement si on n'a pas déjà gagné.
|
||||||
} else if (game.isGameOver()) {
|
} else if (game.isGameOver()) {
|
||||||
|
currentGameState = GameFlowState.GAME_OVER; // Mettre à jour l'état de flux
|
||||||
|
// Enregistrer les statistiques de défaite et finaliser la partie
|
||||||
long timeTaken = System.currentTimeMillis() - gameStats.getCurrentGameStartTimeMs();
|
long timeTaken = System.currentTimeMillis() - gameStats.getCurrentGameStartTimeMs();
|
||||||
gameStats.recordLoss(); // Appelle endGame implicitement
|
gameStats.recordLoss();
|
||||||
|
gameStats.endGame(timeTaken); // Finalise le temps, etc.
|
||||||
|
// Afficher la boîte de dialogue de Game Over
|
||||||
showGameOverDialog();
|
showGameOverDialog();
|
||||||
|
|
||||||
|
if (!boardChanged) {
|
||||||
|
updateUI(); // Assure que le score final affiché est correct.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// c) Ni gagné, ni perdu : Le jeu continue. L'état reste PLAYING ou WON_DIALOG_SHOWN.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enum Direction (inchangé)
|
|
||||||
enum Direction { UP, DOWN, LEFT, RIGHT }
|
enum Direction { UP, DOWN, LEFT, RIGHT }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Affiche la boîte de dialogue demandant confirmation avant de redémarrer.
|
* Affiche la boîte de dialogue demandant confirmation avant de redémarrer.
|
||||||
*/
|
*/
|
||||||
private void showRestartConfirmationDialog() {
|
private void showRestartConfirmationDialog() {
|
||||||
// ... (code de la dialog inchangé, appelle startNewGame) ...
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
LayoutInflater inflater = getLayoutInflater();
|
LayoutInflater inflater = getLayoutInflater(); View dialogView = inflater.inflate(R.layout.dialog_restart_confirm, null);
|
||||||
View dialogView = inflater.inflate(R.layout.dialog_restart_confirm, null);
|
builder.setView(dialogView); Button cancelButton = dialogView.findViewById(R.id.dialogCancelButton); Button confirmButton = dialogView.findViewById(R.id.dialogConfirmButton);
|
||||||
builder.setView(dialogView);
|
final AlertDialog dialog = builder.create(); cancelButton.setOnClickListener(v -> dialog.dismiss());
|
||||||
Button cancelButton = dialogView.findViewById(R.id.dialogCancelButton);
|
confirmButton.setOnClickListener(v -> { dialog.dismiss(); startNewGame(); }); dialog.show();
|
||||||
Button confirmButton = dialogView.findViewById(R.id.dialogConfirmButton);
|
|
||||||
final AlertDialog dialog = builder.create();
|
|
||||||
cancelButton.setOnClickListener(v -> dialog.dismiss());
|
|
||||||
confirmButton.setOnClickListener(v -> { dialog.dismiss(); startNewGame(); });
|
|
||||||
dialog.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -339,11 +396,75 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
* crée un nouvel objet Game, synchronise le meilleur score et met à jour l'UI.
|
* crée un nouvel objet Game, synchronise le meilleur score et met à jour l'UI.
|
||||||
*/
|
*/
|
||||||
private void startNewGame() {
|
private void startNewGame() {
|
||||||
gameStats.startGame(); // Réinitialise stats partie en cours (mouvements, temps, etc.)
|
gameStats.startGame(); // Réinitialise stats de partie
|
||||||
game = new Game(); // Crée un nouveau jeu logique
|
game = new Game(); // Crée un nouveau jeu
|
||||||
// Applique le meilleur score global connu (chargé par gameStats) au nouvel objet Game
|
game.setHighestScore(gameStats.getOverallHighScore()); // Applique HS global
|
||||||
game.setHighestScore(gameStats.getOverallHighScore());
|
currentGameState = GameFlowState.PLAYING; // Définit l'état à JOUER
|
||||||
updateUI(); // Rafraîchit l'affichage
|
updateUI(); // Met à jour affichage
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Affiche la boîte de dialogue quand 2048 est atteint, en utilisant un layout personnalisé.
|
||||||
|
* Propose de continuer à jouer ou de commencer une nouvelle partie.
|
||||||
|
*/
|
||||||
|
private void showGameWonKeepPlayingDialog() {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
|
LayoutInflater inflater = getLayoutInflater();
|
||||||
|
View dialogView = inflater.inflate(R.layout.dialog_game_won, null); // Gonfle le layout personnalisé
|
||||||
|
builder.setView(dialogView);
|
||||||
|
builder.setCancelable(false); // Empêche de fermer sans choisir
|
||||||
|
|
||||||
|
// Récupère les boutons DANS la vue gonflée
|
||||||
|
Button keepPlayingButton = dialogView.findViewById(R.id.dialogKeepPlayingButton);
|
||||||
|
Button newGameButton = dialogView.findViewById(R.id.dialogNewGameButtonWon);
|
||||||
|
|
||||||
|
final AlertDialog dialog = builder.create();
|
||||||
|
|
||||||
|
keepPlayingButton.setOnClickListener(v -> {
|
||||||
|
// L'état est déjà WON_DIALOG_SHOWN, on ne fait rien de spécial, le jeu continue.
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
|
||||||
|
newGameButton.setOnClickListener(v -> {
|
||||||
|
dialog.dismiss();
|
||||||
|
startNewGame(); // Démarre une nouvelle partie
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Affiche la boîte de dialogue de fin de partie (plus de mouvements), en utilisant un layout personnalisé.
|
||||||
|
* Propose Nouvelle Partie ou Quitter.
|
||||||
|
*/
|
||||||
|
private void showGameOverDialog() {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
|
LayoutInflater inflater = getLayoutInflater();
|
||||||
|
View dialogView = inflater.inflate(R.layout.dialog_game_over, null); // Gonfle le layout personnalisé
|
||||||
|
builder.setView(dialogView);
|
||||||
|
builder.setCancelable(false); // Empêche de fermer sans choisir
|
||||||
|
|
||||||
|
// Récupère les vues DANS la vue gonflée
|
||||||
|
TextView messageTextView = dialogView.findViewById(R.id.dialogMessageGameOver);
|
||||||
|
Button newGameButton = dialogView.findViewById(R.id.dialogNewGameButtonGameOver);
|
||||||
|
Button quitButton = dialogView.findViewById(R.id.dialogQuitButtonGameOver);
|
||||||
|
|
||||||
|
// Met à jour le message avec le score final
|
||||||
|
messageTextView.setText(getString(R.string.game_over_message, game.getCurrentScore()));
|
||||||
|
|
||||||
|
final AlertDialog dialog = builder.create();
|
||||||
|
|
||||||
|
newGameButton.setOnClickListener(v -> {
|
||||||
|
dialog.dismiss();
|
||||||
|
startNewGame(); // Démarre une nouvelle partie
|
||||||
|
});
|
||||||
|
|
||||||
|
quitButton.setOnClickListener(v -> {
|
||||||
|
dialog.dismiss();
|
||||||
|
finish(); // Ferme l'application
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -456,28 +577,6 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
builder.create().show();
|
builder.create().show();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Affiche le dialogue de victoire. */
|
|
||||||
private void showGameWonDialog() { /* ... (inchangé) ... */
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
||||||
builder.setTitle("Vous avez gagné !")
|
|
||||||
.setMessage("Félicitations ! Vous avez atteint 2048 !")
|
|
||||||
.setPositiveButton("Nouvelle partie", (dialog, which) -> startNewGame())
|
|
||||||
.setNegativeButton("Quitter", (dialog, which) -> finish())
|
|
||||||
.setCancelable(false)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Affiche le dialogue de défaite. */
|
|
||||||
private void showGameOverDialog() { /* ... (inchangé) ... */
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
||||||
builder.setTitle("Partie terminée !")
|
|
||||||
.setMessage("Aucun mouvement possible. Votre score final est : " + game.getCurrentScore())
|
|
||||||
.setPositiveButton("Nouvelle partie", (dialog, which) -> startNewGame())
|
|
||||||
.setNegativeButton("Quitter", (dialog, which) -> finish())
|
|
||||||
.setCancelable(false)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Sauvegarde / Chargement ---
|
// --- Sauvegarde / Chargement ---
|
||||||
|
|
||||||
/** Sauvegarde l'état du jeu et le meilleur score via SharedPreferences. */
|
/** Sauvegarde l'état du jeu et le meilleur score via SharedPreferences. */
|
||||||
@ -494,27 +593,29 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
/** Charge l'état du jeu depuis SharedPreferences et synchronise le meilleur score. */
|
/** Charge l'état du jeu depuis SharedPreferences et synchronise le meilleur score. */
|
||||||
private void loadGame() {
|
private void loadGame() {
|
||||||
String gameState = preferences.getString(GAME_STATE_KEY, null);
|
String gameStateString = preferences.getString(GAME_STATE_KEY, null);
|
||||||
int savedHighScore = preferences.getInt(HIGH_SCORE_KEY, gameStats.getOverallHighScore()); // Utilise HS de GameStats comme défaut
|
int savedHighScore = preferences.getInt(HIGH_SCORE_KEY, 0); // HS lu depuis prefs
|
||||||
|
|
||||||
// S'assure que GameStats a la dernière version connue du HS
|
if (gameStats != null) { // S'assure que GameStats a le HS correct
|
||||||
gameStats.setHighestScore(savedHighScore);
|
gameStats.setHighestScore(savedHighScore);
|
||||||
|
}
|
||||||
|
|
||||||
if (gameState != null) {
|
if (gameStateString != null) {
|
||||||
game = Game.deserialize(gameState); // Désérialise plateau + score
|
game = Game.deserialize(gameStateString);
|
||||||
if (game != null) {
|
if (game != null) {
|
||||||
game.setHighestScore(savedHighScore); // Applique le HS à l'objet Game
|
game.setHighestScore(savedHighScore); // Applique HS à Game
|
||||||
} else {
|
// Détermine l'état basé sur le jeu chargé
|
||||||
// Échec -> Nouvelle partie
|
if (game.isGameOver()) currentGameState = GameFlowState.GAME_OVER;
|
||||||
game = new Game();
|
else if (game.isGameWon()) currentGameState = GameFlowState.WON_DIALOG_SHOWN; // Si gagné avant, on continue
|
||||||
game.setHighestScore(savedHighScore);
|
else currentGameState = GameFlowState.PLAYING;
|
||||||
gameStats.startGame(); // Réinitialise stats de partie
|
} else { game = null; } // Échec désérialisation
|
||||||
}
|
} else { game = null; } // Pas de sauvegarde
|
||||||
} else {
|
|
||||||
// Pas de sauvegarde -> Nouvelle partie
|
if (game == null) { // Si pas de jeu chargé ou erreur
|
||||||
game = new Game();
|
game = new Game();
|
||||||
game.setHighestScore(savedHighScore);
|
game.setHighestScore(savedHighScore);
|
||||||
gameStats.startGame(); // Réinitialise stats de partie
|
currentGameState = GameFlowState.PLAYING;
|
||||||
|
// Pas besoin d'appeler gameStats.startGame() ici, sera fait dans initializeGame OU startNewGame si nécessaire
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
53
app/src/main/res/layout/dialog_game_over.xml
Normal file
53
app/src/main/res/layout/dialog_game_over.xml
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?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/dialogTitleGameOver"
|
||||||
|
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/dialogMessageGameOver" android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/game_over_message" android:textSize="16sp"
|
||||||
|
android:textColor="@color/text_tile_low"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_marginBottom="16dp"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/dialogQuitButtonGameOver"
|
||||||
|
style="@style/ButtonStyle"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:text="@string/quit" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/dialogNewGameButtonGameOver"
|
||||||
|
style="@style/ButtonStyle"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:text="@string/new_game" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
55
app/src/main/res/layout/dialog_game_won.xml
Normal file
55
app/src/main/res/layout/dialog_game_won.xml
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?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/dialogTitleWon"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/you_won_title"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/text_tile_low"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_marginBottom="8dp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/dialogMessageWon"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/you_won_message"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="@color/text_tile_low"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_marginBottom="16dp"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/dialogNewGameButtonWon"
|
||||||
|
style="@style/ButtonStyle"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:text="@string/new_game" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/dialogKeepPlayingButton"
|
||||||
|
style="@style/ButtonStyle"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:text="@string/keep_playing" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -44,4 +44,11 @@
|
|||||||
<string name="single_player_section">Single Player</string>
|
<string name="single_player_section">Single Player</string>
|
||||||
<string name="multiplayer_section">Multiplayer</string>
|
<string name="multiplayer_section">Multiplayer</string>
|
||||||
<string name="back_button_label">Back</string>
|
<string name="back_button_label">Back</string>
|
||||||
|
<string name="you_won_title">You won!</string>
|
||||||
|
<string name="you_won_message">Congratulations, you\'ve reached 2048!</string>
|
||||||
|
<string name="keep_playing">Continue</string>
|
||||||
|
<string name="new_game">New Part</string>
|
||||||
|
<string name="game_over_title">Game over!</string>
|
||||||
|
<string name="game_over_message">No move possible.\nFinal score: %d</string>
|
||||||
|
<string name="quit">To leave</string>
|
||||||
</resources>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user