140 lines
4.1 KiB
Java
140 lines
4.1 KiB
Java
|
|
package sae.chuzzle;
|
||
|
|
|
||
|
|
import android.view.MotionEvent;
|
||
|
|
import android.view.View;
|
||
|
|
|
||
|
|
public class GestionnaireTactile implements View.OnTouchListener {
|
||
|
|
|
||
|
|
private static final int NB_LIGNES = EtatJeu.NB_LIGNES;
|
||
|
|
private static final int NB_COLONNES = EtatJeu.NB_COLONNES;
|
||
|
|
private static final float SEUIL_DIRECTION_PX = 10f;
|
||
|
|
|
||
|
|
private final VueGrille vueGrille;
|
||
|
|
private final EtatJeu etatJeu;
|
||
|
|
private final Controleur controleur;
|
||
|
|
|
||
|
|
private float touchDebutX, touchDebutY;
|
||
|
|
private int ligneTouchee, colonneTouchee;
|
||
|
|
private Boolean estLigne;
|
||
|
|
private int indexGlissement;
|
||
|
|
private float decalagePx;
|
||
|
|
private float tailleCase;
|
||
|
|
|
||
|
|
public GestionnaireTactile(VueGrille vueGrille,
|
||
|
|
EtatJeu etatJeu,
|
||
|
|
Controleur controleur) {
|
||
|
|
this.vueGrille = vueGrille;
|
||
|
|
this.etatJeu = etatJeu;
|
||
|
|
this.controleur = controleur;
|
||
|
|
}
|
||
|
|
|
||
|
|
@Override
|
||
|
|
public boolean onTouch(View v, MotionEvent event) {
|
||
|
|
|
||
|
|
if (etatJeu.estTerminee()) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
switch (event.getAction()) {
|
||
|
|
|
||
|
|
case MotionEvent.ACTION_DOWN:
|
||
|
|
tailleCase = calculerTailleCase();
|
||
|
|
gererDebut(event);
|
||
|
|
return true;
|
||
|
|
|
||
|
|
case MotionEvent.ACTION_MOVE:
|
||
|
|
gererMouvement(event);
|
||
|
|
return true;
|
||
|
|
|
||
|
|
case MotionEvent.ACTION_UP:
|
||
|
|
case MotionEvent.ACTION_CANCEL:
|
||
|
|
gererFin(event.getAction() == MotionEvent.ACTION_UP);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void gererDebut(MotionEvent event) {
|
||
|
|
touchDebutX = event.getX();
|
||
|
|
touchDebutY = event.getY();
|
||
|
|
estLigne = null;
|
||
|
|
decalagePx = 0f;
|
||
|
|
|
||
|
|
float margeGauche = (vueGrille.getWidth() - tailleCase * NB_COLONNES) / 2f;
|
||
|
|
float margeHaut = (vueGrille.getHeight() - tailleCase * NB_LIGNES) / 2f;
|
||
|
|
|
||
|
|
ligneTouchee = (int) ((touchDebutY - margeHaut) / tailleCase);
|
||
|
|
colonneTouchee = (int) ((touchDebutX - margeGauche) / tailleCase);
|
||
|
|
|
||
|
|
ligneTouchee = Math.max(0, Math.min(NB_LIGNES - 1, ligneTouchee));
|
||
|
|
colonneTouchee = Math.max(0, Math.min(NB_COLONNES - 1, colonneTouchee));
|
||
|
|
}
|
||
|
|
|
||
|
|
private void gererMouvement(MotionEvent event) {
|
||
|
|
float dx = event.getX() - touchDebutX;
|
||
|
|
float dy = event.getY() - touchDebutY;
|
||
|
|
|
||
|
|
if (estLigne == null) {
|
||
|
|
if (Math.abs(dx) > SEUIL_DIRECTION_PX || Math.abs(dy) > SEUIL_DIRECTION_PX) {
|
||
|
|
estLigne = Math.abs(dx) >= Math.abs(dy);
|
||
|
|
|
||
|
|
if (estLigne) {
|
||
|
|
indexGlissement = ligneTouchee;
|
||
|
|
} else {
|
||
|
|
indexGlissement = colonneTouchee;
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (estLigne) {
|
||
|
|
decalagePx = dx;
|
||
|
|
} else {
|
||
|
|
decalagePx = dy;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Affiche le glissement réel du doigt (permet la rotation multi-cases)
|
||
|
|
vueGrille.definirGlissement(estLigne, indexGlissement, decalagePx);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void gererFin(boolean estRelachement) {
|
||
|
|
|
||
|
|
if (estLigne == null) {
|
||
|
|
vueGrille.annulerGlissement();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (tailleCase <= 1f) {
|
||
|
|
vueGrille.annulerGlissement();
|
||
|
|
estLigne = null;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Arrondi au nombre de cases le plus proche (permet ±1, ±2, ±3…)
|
||
|
|
int nbCases = (int) Math.round(decalagePx / tailleCase);
|
||
|
|
|
||
|
|
if (nbCases != 0 && estRelachement) {
|
||
|
|
boolean accepte = etatJeu.appliquerCoup(estLigne, indexGlissement, nbCases);
|
||
|
|
if (accepte) {
|
||
|
|
controleur.rafraichirAffichage();
|
||
|
|
controleur.verifierFinDePartie();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
vueGrille.annulerGlissement();
|
||
|
|
estLigne = null;
|
||
|
|
}
|
||
|
|
|
||
|
|
private float calculerTailleCase() {
|
||
|
|
float l = vueGrille.getWidth();
|
||
|
|
float h = vueGrille.getHeight();
|
||
|
|
|
||
|
|
if (l == 0 || h == 0) {
|
||
|
|
return 1f;
|
||
|
|
}
|
||
|
|
|
||
|
|
return Math.min(l / NB_COLONNES, h / NB_LIGNES);
|
||
|
|
}
|
||
|
|
}
|