Feat: Liaison UI-Logique et gestion des swipes (Étape 8)
- Modification de MainActivity: - Récupération des vues (GridLayout, TextViews). - Implémentation de initGameBoardLayout et updateUI pour dessiner la grille en fonction de l'état de Game. - Création et attachement de OnSwipeTouchListener pour gérer les swipes. - Modification de Game: - Ajout des getters: getGameBoard, getScore, getHighScore (placeholder). # La méthode printArray reste présente dans Game.java selon l'extrait. - Création de OnSwipeTouchListener.java pour la détection des gestes.
This commit is contained in:
parent
7eb597650c
commit
b6213f077a
@ -37,6 +37,7 @@ dependencies {
|
||||
implementation(libs.material)
|
||||
implementation(libs.activity)
|
||||
implementation(libs.constraintlayout)
|
||||
implementation(libs.gridlayout)
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.ext.junit)
|
||||
androidTestImplementation(libs.espresso.core)
|
||||
|
@ -1,8 +1,10 @@
|
||||
package legion.muyue.best2048;
|
||||
|
||||
import android.util.Log;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
// L'import Log reste car printArray est toujours défini dans cet extrait
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
public class Game {
|
||||
|
||||
@ -15,6 +17,19 @@ public class Game {
|
||||
random = new Random();
|
||||
}
|
||||
|
||||
public int getGameBoard(int x, int y) {
|
||||
return gameBoard[x][y];
|
||||
}
|
||||
|
||||
public int getScore() {
|
||||
return score;
|
||||
}
|
||||
|
||||
public int getHighScore() {
|
||||
return 0; // TODO: Implémentez la logique du meilleur score plus tard
|
||||
}
|
||||
|
||||
// La méthode printArray est toujours présente dans l'extrait de Game.java pour l'étape 8
|
||||
public void printArray() {
|
||||
for (int[] row : gameBoard) {
|
||||
String rowString = String.format("%6d%6d%6d%6d%n", row[0], row[1], row[2], row[3]);
|
||||
@ -132,36 +147,35 @@ public class Game {
|
||||
}
|
||||
|
||||
public void pushLeft() {
|
||||
Log.d("Game", "Pushing Left"); // Pour le débogage
|
||||
boolean[] alreadyCombined = new boolean[4]; // Tableau par ligne cette fois
|
||||
Log.d("Game", "Pushing Left");
|
||||
boolean[] alreadyCombined = new boolean[4];
|
||||
|
||||
for (int x = 0; x < 4; x++) { // Itère sur les *lignes* d'abord
|
||||
alreadyCombined = new boolean[4]; // Réinitialise pour chaque ligne
|
||||
for (int y = 1; y < 4; y++) { // Itère sur les *colonnes*, en commençant par la deuxième
|
||||
for (int x = 0; x < 4; x++) {
|
||||
alreadyCombined = new boolean[4];
|
||||
for (int y = 1; y < 4; y++) {
|
||||
if (gameBoard[x][y] != 0) {
|
||||
int value = gameBoard[x][y];
|
||||
int currentY = y; // Suit la colonne
|
||||
int currentY = y;
|
||||
|
||||
// Déplace vers la gauche
|
||||
while (currentY > 0 && gameBoard[x][currentY - 1] == 0) {
|
||||
currentY--;
|
||||
}
|
||||
|
||||
if (currentY == 0) { // Arrivé tout à gauche
|
||||
if (currentY == 0) {
|
||||
gameBoard[x][0] = value;
|
||||
if(currentY != y)
|
||||
gameBoard[x][y] = 0;
|
||||
} else if (gameBoard[x][currentY - 1] != value) { // Case à gauche différente
|
||||
} else if (gameBoard[x][currentY - 1] != value) {
|
||||
gameBoard[x][currentY] = value;
|
||||
if(currentY != y)
|
||||
gameBoard[x][y] = 0;
|
||||
} else if (!alreadyCombined[currentY - 1]) { // Case à gauche identique et non fusionnée
|
||||
gameBoard[x][currentY - 1] *= 2; // Fusionne
|
||||
} else if (!alreadyCombined[currentY - 1]) {
|
||||
gameBoard[x][currentY - 1] *= 2;
|
||||
score += gameBoard[x][currentY - 1];
|
||||
gameBoard[x][y] = 0;
|
||||
alreadyCombined[currentY - 1] = true; // Marque comme fusionné
|
||||
} else { // Case à gauche identique mais déjà fusionnée
|
||||
gameBoard[x][currentY] = value; // Place à côté
|
||||
alreadyCombined[currentY - 1] = true;
|
||||
} else {
|
||||
gameBoard[x][currentY] = value;
|
||||
if(currentY != y)
|
||||
gameBoard[x][y] = 0;
|
||||
}
|
||||
@ -171,36 +185,35 @@ public class Game {
|
||||
}
|
||||
|
||||
public void pushRight() {
|
||||
Log.d("Game", "Pushing Right"); // Pour le débogage
|
||||
boolean[] alreadyCombined = new boolean[4]; // Tableau par ligne
|
||||
Log.d("Game", "Pushing Right");
|
||||
boolean[] alreadyCombined = new boolean[4];
|
||||
|
||||
for (int x = 0; x < 4; x++) { // Itère sur les *lignes*
|
||||
alreadyCombined = new boolean[4]; // Réinitialise pour chaque ligne.
|
||||
for (int y = 2; y >= 0; y--) { // Itère sur les *colonnes*, de droite à gauche (avant-dernière vers première)
|
||||
for (int x = 0; x < 4; x++) {
|
||||
alreadyCombined = new boolean[4];
|
||||
for (int y = 2; y >= 0; y--) {
|
||||
if (gameBoard[x][y] != 0) {
|
||||
int value = gameBoard[x][y];
|
||||
int currentY = y; // Suit la colonne
|
||||
int currentY = y;
|
||||
|
||||
// Déplace vers la droite
|
||||
while (currentY < 3 && gameBoard[x][currentY + 1] == 0) {
|
||||
currentY++;
|
||||
}
|
||||
|
||||
if (currentY == 3) { // Arrivé tout à droite
|
||||
if (currentY == 3) {
|
||||
gameBoard[x][3] = value;
|
||||
if (currentY != y)
|
||||
gameBoard[x][y] = 0;
|
||||
} else if (gameBoard[x][currentY + 1] != value) { // Case à droite différente
|
||||
} else if (gameBoard[x][currentY + 1] != value) {
|
||||
gameBoard[x][currentY] = value;
|
||||
if(currentY != y)
|
||||
gameBoard[x][y] = 0;
|
||||
} else if (!alreadyCombined[currentY + 1]) { // Case à droite identique et non fusionnée
|
||||
gameBoard[x][currentY + 1] *= 2; // Fusionne
|
||||
} else if (!alreadyCombined[currentY + 1]) {
|
||||
gameBoard[x][currentY + 1] *= 2;
|
||||
score += gameBoard[x][currentY + 1];
|
||||
gameBoard[x][y] = 0;
|
||||
alreadyCombined[currentY + 1] = true; // Marque comme fusionné
|
||||
} else { // Case à droite identique mais déjà fusionnée
|
||||
gameBoard[x][currentY] = value; // Place à côté
|
||||
alreadyCombined[currentY + 1] = true;
|
||||
} else {
|
||||
gameBoard[x][currentY] = value;
|
||||
if (currentY != y)
|
||||
gameBoard[x][y] = 0;
|
||||
}
|
||||
|
@ -1,41 +1,154 @@
|
||||
package legion.muyue.best2048;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.gridlayout.widget.GridLayout;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
private GridLayout gameBoardLayout;
|
||||
private TextView scoreTextView;
|
||||
private TextView highScoreTextView;
|
||||
private Game game;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
Game game = new Game();
|
||||
gameBoardLayout = findViewById(R.id.gameBoard);
|
||||
scoreTextView = findViewById(R.id.scoreLabel);
|
||||
highScoreTextView = findViewById(R.id.highScoreLabel);
|
||||
|
||||
game = new Game();
|
||||
|
||||
initGameBoardLayout();
|
||||
|
||||
// Initialisation et tests des quatre directions
|
||||
game.addNewNumbers();
|
||||
game.addNewNumbers();
|
||||
game.addNewNumbers();
|
||||
game.printArray(); // Grille initiale
|
||||
updateUI();
|
||||
|
||||
// Ajout des listeners de swipe
|
||||
setupSwipeListener();
|
||||
}
|
||||
private void initGameBoardLayout() {
|
||||
gameBoardLayout.removeAllViews();
|
||||
gameBoardLayout.setColumnCount(4);
|
||||
gameBoardLayout.setRowCount(4);
|
||||
}
|
||||
|
||||
private void updateUI() {
|
||||
gameBoardLayout.removeAllViews(); // Efface les tuiles précédentes
|
||||
|
||||
for (int x = 0; x < 4; x++) {
|
||||
for (int y = 0; y < 4; y++) {
|
||||
TextView tileTextView = new TextView(this);
|
||||
int value = game.getGameBoard(x, y);
|
||||
|
||||
// Choisir le bon drawable en fonction de la valeur
|
||||
int drawableId;
|
||||
|
||||
switch (value) {
|
||||
case 2:
|
||||
drawableId = R.drawable.tile2;
|
||||
break;
|
||||
case 4:
|
||||
drawableId = R.drawable.tile4;
|
||||
break;
|
||||
case 8:
|
||||
drawableId = R.drawable.tile8;
|
||||
break;
|
||||
case 16:
|
||||
drawableId = R.drawable.tile16;
|
||||
break;
|
||||
case 32:
|
||||
drawableId = R.drawable.tile32;
|
||||
break;
|
||||
case 64:
|
||||
drawableId = R.drawable.tile64;
|
||||
break;
|
||||
case 128:
|
||||
drawableId = R.drawable.tile128;
|
||||
break;
|
||||
case 256:
|
||||
drawableId = R.drawable.tile256;
|
||||
break;
|
||||
case 512:
|
||||
drawableId = R.drawable.tile512;
|
||||
break;
|
||||
case 1024:
|
||||
drawableId = R.drawable.tile1024;
|
||||
break;
|
||||
case 2048:
|
||||
drawableId = R.drawable.tile2048;
|
||||
break;
|
||||
default:
|
||||
drawableId = R.drawable.tile_empty;
|
||||
break;
|
||||
}
|
||||
|
||||
tileTextView.setBackground(ContextCompat.getDrawable(this, drawableId));
|
||||
|
||||
// Afficher le texte uniquement si la valeur est > 0
|
||||
if (value > 0) {
|
||||
tileTextView.setText(String.valueOf(value));
|
||||
// Adapte la taille du texte en fonction de la valeur.
|
||||
tileTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, value < 128 ? 24 : (value < 1024 ? 20 : 16));
|
||||
|
||||
tileTextView.setTextColor(ContextCompat.getColor(this, R.color.text_tile_low));
|
||||
}
|
||||
tileTextView.setGravity(Gravity.CENTER);
|
||||
|
||||
GridLayout.LayoutParams params = new GridLayout.LayoutParams();
|
||||
params.width = 0;
|
||||
params.height = 0;
|
||||
params.rowSpec = GridLayout.spec(x, 1f);
|
||||
params.columnSpec = GridLayout.spec(y, 1f);
|
||||
params.setMargins(10, 10, 10, 10); // Marges codées en dur selon l'extrait
|
||||
tileTextView.setLayoutParams(params);
|
||||
|
||||
gameBoardLayout.addView(tileTextView);
|
||||
}
|
||||
}
|
||||
|
||||
scoreTextView.setText("Score:\n" + game.getScore()); // Concaténation simple selon l'extrait
|
||||
highScoreTextView.setText("High Score:\n" + game.getHighScore()); // Concaténation simple selon l'extrait
|
||||
}
|
||||
|
||||
private void setupSwipeListener() {
|
||||
gameBoardLayout.setOnTouchListener(new OnSwipeTouchListener(MainActivity.this) {
|
||||
@Override
|
||||
public void onSwipeTop() {
|
||||
game.pushUp();
|
||||
game.printArray(); // Après pushUp
|
||||
|
||||
game.addNewNumbers();
|
||||
game.printArray(); // Avant pushDown
|
||||
updateUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwipeBottom() {
|
||||
game.pushDown();
|
||||
game.printArray(); // Après pushDown
|
||||
|
||||
game.addNewNumbers();
|
||||
game.printArray(); // Avant pushLeft
|
||||
updateUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwipeLeft() {
|
||||
game.pushLeft();
|
||||
game.printArray(); // Après pushLeft
|
||||
|
||||
game.addNewNumbers();
|
||||
game.printArray(); // Avant pushRight
|
||||
updateUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwipeRight() {
|
||||
game.pushRight();
|
||||
game.printArray(); // Après pushRight
|
||||
game.addNewNumbers();
|
||||
updateUI();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package legion.muyue.best2048;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
public class OnSwipeTouchListener implements View.OnTouchListener {
|
||||
|
||||
private final GestureDetector gestureDetector;
|
||||
|
||||
public OnSwipeTouchListener(Context ctx) {
|
||||
gestureDetector = new GestureDetector(ctx, new GestureListener());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
return gestureDetector.onTouchEvent(event);
|
||||
}
|
||||
|
||||
private final class GestureListener extends GestureDetector.SimpleOnGestureListener {
|
||||
|
||||
private static final int SWIPE_THRESHOLD = 100;
|
||||
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
|
||||
|
||||
@Override
|
||||
public boolean onDown(MotionEvent e) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||
boolean result = false;
|
||||
try {
|
||||
float diffY = e2.getY() - e1.getY();
|
||||
float diffX = e2.getX() - e1.getX();
|
||||
if (Math.abs(diffX) > Math.abs(diffY)) {
|
||||
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
|
||||
if (diffX > 0) {
|
||||
onSwipeRight();
|
||||
} else {
|
||||
onSwipeLeft();
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
} else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
|
||||
if (diffY > 0) {
|
||||
onSwipeBottom();
|
||||
} else {
|
||||
onSwipeTop();
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public void onSwipeRight() {
|
||||
}
|
||||
|
||||
public void onSwipeLeft() {
|
||||
}
|
||||
|
||||
public void onSwipeTop() {
|
||||
}
|
||||
|
||||
public void onSwipeBottom() {
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user