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.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.util.TypedValue;
|
||||
@ -61,14 +62,17 @@ public class MainActivity extends AppCompatActivity {
|
||||
private GameStats gameStats; // Instance pour gérer les stats
|
||||
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 ---
|
||||
private SharedPreferences preferences;
|
||||
private static final String PREFS_NAME = "Best2048_Prefs";
|
||||
private static final String HIGH_SCORE_KEY = "high_score";
|
||||
private static final String GAME_STATE_KEY = "game_state";
|
||||
|
||||
private boolean statisticsVisible = false;
|
||||
|
||||
// --- Activity Lifecycle ---
|
||||
|
||||
@Override
|
||||
@ -139,16 +143,22 @@ public class MainActivity extends AppCompatActivity {
|
||||
*/
|
||||
private void initializeGameAndStats() {
|
||||
preferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
|
||||
gameStats = new GameStats(this); // Crée et charge les stats (y.c. overallHighScore)
|
||||
loadGame(); // Charge l'état du jeu, crée un nouveau si nécessaire, synchronise le HS
|
||||
updateUI(); // Affiche l'état chargé ou nouveau
|
||||
|
||||
// Si loadGame a résulté en une nouvelle partie (game==null avant ou deserialize a échoué),
|
||||
// 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é
|
||||
gameStats = new GameStats(this);
|
||||
loadGame(); // Charge jeu et met à jour high score
|
||||
updateUI();
|
||||
if (game == null) {
|
||||
startNewGame(); // Assure une partie valide si chargement échoue
|
||||
} 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,
|
||||
* ajoute une nouvelle tuile, met à jour l'UI et vérifie les conditions de fin de partie.
|
||||
* @param direction Direction du swipe.
|
||||
* Traite un geste de swipe de l'utilisateur sur le plateau de jeu.
|
||||
* 1. Tente d'effectuer le mouvement dans l'objet Game.
|
||||
* 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) {
|
||||
if (game == null || gameStats == null || game.isGameOver() || game.isGameWon()) return;
|
||||
|
||||
int scoreBefore = game.getCurrentScore();
|
||||
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;
|
||||
// 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) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
gameStats.recordMove(); // Met à jour stats mouvement
|
||||
// Mettre à jour les statistiques liées au mouvement réussi
|
||||
gameStats.recordMove();
|
||||
int scoreAfter = game.getCurrentScore();
|
||||
int scoreDelta = scoreAfter - scoreBefore;
|
||||
if (scoreDelta > 0) {
|
||||
gameStats.recordMerge(1); // Met à jour stats fusion (simplifié)
|
||||
// Met à jour le highScore dans Game et GameStats si nécessaire
|
||||
// Supposition simpliste : une augmentation de score implique au moins une fusion
|
||||
gameStats.recordMerge(1);
|
||||
// Vérifier et mettre à jour le meilleur score si nécessaire
|
||||
if (scoreAfter > game.getHighestScore()) {
|
||||
game.setHighestScore(scoreAfter);
|
||||
gameStats.setHighestScore(scoreAfter); // Synchronise avec GameStats
|
||||
game.setHighestScore(scoreAfter); // Met à jour dans l'objet Game
|
||||
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
|
||||
updateUI(); // Met à jour affichage
|
||||
// Mettre à jour l'affichage complet du plateau et des scores
|
||||
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();
|
||||
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()) {
|
||||
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();
|
||||
gameStats.recordLoss(); // Appelle endGame implicitement
|
||||
gameStats.recordLoss();
|
||||
gameStats.endGame(timeTaken); // Finalise le temps, etc.
|
||||
// Afficher la boîte de dialogue de Game Over
|
||||
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 }
|
||||
|
||||
/**
|
||||
* Affiche la boîte de dialogue demandant confirmation avant de redémarrer.
|
||||
*/
|
||||
private void showRestartConfirmationDialog() {
|
||||
// ... (code de la dialog inchangé, appelle startNewGame) ...
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
LayoutInflater inflater = getLayoutInflater();
|
||||
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);
|
||||
final AlertDialog dialog = builder.create();
|
||||
cancelButton.setOnClickListener(v -> dialog.dismiss());
|
||||
confirmButton.setOnClickListener(v -> { dialog.dismiss(); startNewGame(); });
|
||||
dialog.show();
|
||||
LayoutInflater inflater = getLayoutInflater(); 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);
|
||||
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.
|
||||
*/
|
||||
private void startNewGame() {
|
||||
gameStats.startGame(); // Réinitialise stats partie en cours (mouvements, temps, etc.)
|
||||
game = new Game(); // Crée un nouveau jeu logique
|
||||
// Applique le meilleur score global connu (chargé par gameStats) au nouvel objet Game
|
||||
game.setHighestScore(gameStats.getOverallHighScore());
|
||||
updateUI(); // Rafraîchit l'affichage
|
||||
gameStats.startGame(); // Réinitialise stats de partie
|
||||
game = new Game(); // Crée un nouveau jeu
|
||||
game.setHighestScore(gameStats.getOverallHighScore()); // Applique HS global
|
||||
currentGameState = GameFlowState.PLAYING; // Définit l'état à JOUER
|
||||
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();
|
||||
}
|
||||
|
||||
/** 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 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. */
|
||||
private void loadGame() {
|
||||
String gameState = preferences.getString(GAME_STATE_KEY, null);
|
||||
int savedHighScore = preferences.getInt(HIGH_SCORE_KEY, gameStats.getOverallHighScore()); // Utilise HS de GameStats comme défaut
|
||||
String gameStateString = preferences.getString(GAME_STATE_KEY, null);
|
||||
int savedHighScore = preferences.getInt(HIGH_SCORE_KEY, 0); // HS lu depuis prefs
|
||||
|
||||
// S'assure que GameStats a la dernière version connue du HS
|
||||
gameStats.setHighestScore(savedHighScore);
|
||||
if (gameStats != null) { // S'assure que GameStats a le HS correct
|
||||
gameStats.setHighestScore(savedHighScore);
|
||||
}
|
||||
|
||||
if (gameState != null) {
|
||||
game = Game.deserialize(gameState); // Désérialise plateau + score
|
||||
if (gameStateString != null) {
|
||||
game = Game.deserialize(gameStateString);
|
||||
if (game != null) {
|
||||
game.setHighestScore(savedHighScore); // Applique le HS à l'objet Game
|
||||
} else {
|
||||
// Échec -> Nouvelle partie
|
||||
game = new Game();
|
||||
game.setHighestScore(savedHighScore);
|
||||
gameStats.startGame(); // Réinitialise stats de partie
|
||||
}
|
||||
} else {
|
||||
// Pas de sauvegarde -> Nouvelle partie
|
||||
game.setHighestScore(savedHighScore); // Applique HS à Game
|
||||
// Détermine l'état basé sur le jeu chargé
|
||||
if (game.isGameOver()) currentGameState = GameFlowState.GAME_OVER;
|
||||
else if (game.isGameWon()) currentGameState = GameFlowState.WON_DIALOG_SHOWN; // Si gagné avant, on continue
|
||||
else currentGameState = GameFlowState.PLAYING;
|
||||
} else { game = null; } // Échec désérialisation
|
||||
} else { game = null; } // Pas de sauvegarde
|
||||
|
||||
if (game == null) { // Si pas de jeu chargé ou erreur
|
||||
game = new Game();
|
||||
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="multiplayer_section">Multiplayer</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>
|
Loading…
x
Reference in New Issue
Block a user