Feat: Liaison UI-Logique et gestion des swipes
- 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). - Création de OnSwipeTouchListener.java pour la détection des gestes.
This commit is contained in:
parent
7eb597650c
commit
84ca7f9fc3
@ -37,6 +37,7 @@ dependencies {
|
|||||||
implementation(libs.material)
|
implementation(libs.material)
|
||||||
implementation(libs.activity)
|
implementation(libs.activity)
|
||||||
implementation(libs.constraintlayout)
|
implementation(libs.constraintlayout)
|
||||||
|
implementation(libs.gridlayout)
|
||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
androidTestImplementation(libs.ext.junit)
|
androidTestImplementation(libs.ext.junit)
|
||||||
androidTestImplementation(libs.espresso.core)
|
androidTestImplementation(libs.espresso.core)
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package legion.muyue.best2048;
|
package legion.muyue.best2048;
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
|
||||||
public class Game {
|
public class Game {
|
||||||
|
|
||||||
@ -15,6 +16,19 @@ public class Game {
|
|||||||
random = new Random();
|
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() {
|
public void printArray() {
|
||||||
for (int[] row : gameBoard) {
|
for (int[] row : gameBoard) {
|
||||||
String rowString = String.format("%6d%6d%6d%6d%n", row[0], row[1], row[2], row[3]);
|
String rowString = String.format("%6d%6d%6d%6d%n", row[0], row[1], row[2], row[3]);
|
||||||
@ -132,36 +146,35 @@ public class Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void pushLeft() {
|
public void pushLeft() {
|
||||||
Log.d("Game", "Pushing Left"); // Pour le débogage
|
Log.d("Game", "Pushing Left");
|
||||||
boolean[] alreadyCombined = new boolean[4]; // Tableau par ligne cette fois
|
boolean[] alreadyCombined = new boolean[4];
|
||||||
|
|
||||||
for (int x = 0; x < 4; x++) { // Itère sur les *lignes* d'abord
|
for (int x = 0; x < 4; x++) {
|
||||||
alreadyCombined = new boolean[4]; // Réinitialise pour chaque ligne
|
alreadyCombined = new boolean[4];
|
||||||
for (int y = 1; y < 4; y++) { // Itère sur les *colonnes*, en commençant par la deuxième
|
for (int y = 1; y < 4; y++) {
|
||||||
if (gameBoard[x][y] != 0) {
|
if (gameBoard[x][y] != 0) {
|
||||||
int value = gameBoard[x][y];
|
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) {
|
while (currentY > 0 && gameBoard[x][currentY - 1] == 0) {
|
||||||
currentY--;
|
currentY--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentY == 0) { // Arrivé tout à gauche
|
if (currentY == 0) {
|
||||||
gameBoard[x][0] = value;
|
gameBoard[x][0] = value;
|
||||||
if(currentY != y)
|
if(currentY != y)
|
||||||
gameBoard[x][y] = 0;
|
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;
|
gameBoard[x][currentY] = value;
|
||||||
if(currentY != y)
|
if(currentY != y)
|
||||||
gameBoard[x][y] = 0;
|
gameBoard[x][y] = 0;
|
||||||
} else if (!alreadyCombined[currentY - 1]) { // Case à gauche identique et non fusionnée
|
} else if (!alreadyCombined[currentY - 1]) {
|
||||||
gameBoard[x][currentY - 1] *= 2; // Fusionne
|
gameBoard[x][currentY - 1] *= 2;
|
||||||
score += gameBoard[x][currentY - 1];
|
score += gameBoard[x][currentY - 1];
|
||||||
gameBoard[x][y] = 0;
|
gameBoard[x][y] = 0;
|
||||||
alreadyCombined[currentY - 1] = true; // Marque comme fusionné
|
alreadyCombined[currentY - 1] = true;
|
||||||
} else { // Case à gauche identique mais déjà fusionnée
|
} else {
|
||||||
gameBoard[x][currentY] = value; // Place à côté
|
gameBoard[x][currentY] = value;
|
||||||
if(currentY != y)
|
if(currentY != y)
|
||||||
gameBoard[x][y] = 0;
|
gameBoard[x][y] = 0;
|
||||||
}
|
}
|
||||||
@ -171,36 +184,35 @@ public class Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void pushRight() {
|
public void pushRight() {
|
||||||
Log.d("Game", "Pushing Right"); // Pour le débogage
|
Log.d("Game", "Pushing Right");
|
||||||
boolean[] alreadyCombined = new boolean[4]; // Tableau par ligne
|
boolean[] alreadyCombined = new boolean[4];
|
||||||
|
|
||||||
for (int x = 0; x < 4; x++) { // Itère sur les *lignes*
|
for (int x = 0; x < 4; x++) {
|
||||||
alreadyCombined = new boolean[4]; // Réinitialise pour chaque ligne.
|
alreadyCombined = new boolean[4];
|
||||||
for (int y = 2; y >= 0; y--) { // Itère sur les *colonnes*, de droite à gauche (avant-dernière vers première)
|
for (int y = 2; y >= 0; y--) {
|
||||||
if (gameBoard[x][y] != 0) {
|
if (gameBoard[x][y] != 0) {
|
||||||
int value = gameBoard[x][y];
|
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) {
|
while (currentY < 3 && gameBoard[x][currentY + 1] == 0) {
|
||||||
currentY++;
|
currentY++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentY == 3) { // Arrivé tout à droite
|
if (currentY == 3) {
|
||||||
gameBoard[x][3] = value;
|
gameBoard[x][3] = value;
|
||||||
if (currentY != y)
|
if (currentY != y)
|
||||||
gameBoard[x][y] = 0;
|
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;
|
gameBoard[x][currentY] = value;
|
||||||
if(currentY != y)
|
if(currentY != y)
|
||||||
gameBoard[x][y] = 0;
|
gameBoard[x][y] = 0;
|
||||||
} else if (!alreadyCombined[currentY + 1]) { // Case à droite identique et non fusionnée
|
} else if (!alreadyCombined[currentY + 1]) {
|
||||||
gameBoard[x][currentY + 1] *= 2; // Fusionne
|
gameBoard[x][currentY + 1] *= 2;
|
||||||
score += gameBoard[x][currentY + 1];
|
score += gameBoard[x][currentY + 1];
|
||||||
gameBoard[x][y] = 0;
|
gameBoard[x][y] = 0;
|
||||||
alreadyCombined[currentY + 1] = true; // Marque comme fusionné
|
alreadyCombined[currentY + 1] = true;
|
||||||
} else { // Case à droite identique mais déjà fusionnée
|
} else {
|
||||||
gameBoard[x][currentY] = value; // Place à côté
|
gameBoard[x][currentY] = value;
|
||||||
if (currentY != y)
|
if (currentY != y)
|
||||||
gameBoard[x][y] = 0;
|
gameBoard[x][y] = 0;
|
||||||
}
|
}
|
||||||
|
@ -1,41 +1,154 @@
|
|||||||
package legion.muyue.best2048;
|
package legion.muyue.best2048;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.widget.TextView;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.gridlayout.widget.GridLayout;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private GridLayout gameBoardLayout;
|
||||||
|
private TextView scoreTextView;
|
||||||
|
private TextView highScoreTextView;
|
||||||
|
private Game game;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(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.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.pushUp();
|
||||||
game.printArray(); // Après pushUp
|
|
||||||
|
|
||||||
game.addNewNumbers();
|
game.addNewNumbers();
|
||||||
game.printArray(); // Avant pushDown
|
updateUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSwipeBottom() {
|
||||||
game.pushDown();
|
game.pushDown();
|
||||||
game.printArray(); // Après pushDown
|
|
||||||
|
|
||||||
game.addNewNumbers();
|
game.addNewNumbers();
|
||||||
game.printArray(); // Avant pushLeft
|
updateUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSwipeLeft() {
|
||||||
game.pushLeft();
|
game.pushLeft();
|
||||||
game.printArray(); // Après pushLeft
|
|
||||||
|
|
||||||
game.addNewNumbers();
|
game.addNewNumbers();
|
||||||
game.printArray(); // Avant pushRight
|
updateUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSwipeRight() {
|
||||||
game.pushRight();
|
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