:: Enseignements :: ESIPE :: E4INFO :: 2015-2016 :: Interface Graphique avec Android ::
[LOGO]

Un peu de concentration


Le but du TD est d'implanter un jeu de mémoire avec des cartes.
Un paquet de cartes contenant que des paires est disposé formant une grille. Le joueur doit retrouver les paires en ne pouvant retourner que deux cartes à la fois. Si les deux cartes sont différentes, elles sont remises face cachée sinon, les cartes sont trouvées et ne peuvent plus être retournées. Le but du jeu est de trouver toutes les paires en un minimum de temps.

Exercice 1 - Des ressources insoupçonnées

Chaque paire de cartes utilise une image spécifique pour sa face visible. Toutes les cartes possèdent la même face cachée (sinon ce serait un peu trop facile). Nous souhaitons stocker les images des cartes (au format PNG ou JPEG) dans de ressources embarquées dans l'APK de l'application.

  1. On peut placer les ressources sous le répertoire res/drawable. Serait-il possible de proposer des images de résolutions différentes pour les différents types d'écran ? Est-ce vraiment indispensable ? Peut-on facilement lister les images disponibles dans ce répertoire ?
  2. Quelle est la différence entre une Resource et un Asset ?
  3. On choisit de placer les images dans le répertoire assets. Écrivez du code pour lister toutes les images présentes dans ce répertoire. On propose une méthode pour sélectionner aléatoirement N images de ce répertoire et les mélanger. On stockera par contre la face retournée commune à toutes les cartes dans res/drawable.
On pourra télécharger ici une archive contenant quelques images que l'on pourra utiliser.

Exercice 2 - Un GridView avec son Adapter

L'API graphique d'Android utilise un système Modèle-Adapteur-Vue pour gérer les ListView et GridView (ainsi que d'autres composants graphiques). Le modèle n'est donc pas directement relié à la vue mais communique par le biais d'un adaptateur.

  1. Créez un layout XML afin de représenter une image avec une étiquette en bas de celle-ci indiquant son nom. Comment charger dynamiquemet ce layout à l'exécution ?
  2. Créez maintenant un GridView qui occupera toute la taille de l'activité. Celui-ci affichera sur plusieurs colonnes les cartes du jeu.
  3. Installez un adaptateur sur le GridView pour afficher les cartes avec leur nom. Il pourra être utile, pour représenter le modèle, de créer une classe Card avec toutes les informations nécessaires sur l'identité et l'état d'une carte (image, nom, retournée ou non...). Au départ toutes les cartes sont retournées. L'adaptateur consulte le modèle pour proposer pour chaque item de la grille une vue adaptée pour l'affichage (méthode getView() à redéfinir).
  4. Rajoutez un listener sur le clic des items de la grille afin de retourner si nécessaire la carte. Pour chaque tour, on est censé retourner deux cartes. Au début d'un nouveau tour, lorsque l'on divulgue une carte, on masque les deux cartes affichées du tour précédent sauf si une paire avait été trouvée.
  5. Jouez un peu et constatez le problème qui survient lorsque l'on impose une rotation à l'écran. Pour résoudre cet écueil, deux méthodes sont possibles :
    1. Bloquer l'orientation de l'appareil dans un seul mode (portrait ou paysage) pour qu'il n'y ait pas de rotation possible (propriété ScreenOrientation dans le manifeste).
    2. Supporter la rotation (qui nécessite la destruction puis la réinstantiation de l'activité). Il faut alors sauvegarder l'état du jeu dans un Bundle puis le restaurer lors de l'appel à onCreate(). C'est cette solution que l'on implantera.

Exercice 3 - Performances de jeu

On souhaite mesurer nos performances au jeu en stockant quelques informations utiles.

  1. Rajoutez un TextView afin d'afficher le nombre de tours joués.
  2. Rajoutez un chronomètre indiquant le nombre de secondes écoulées depuis le début du jeu. On essaiera de ne pas instantier de thread si cela est possible (on privilégiera l'appel à postDelayed sur un Handler)

Exercice 4 - Fin de jeu

On matérialise la fin du jeu (découverte de toutes les paires) par l'affichage d'une activité félicitant le joueur et lui présentant le nombre de tentatives réalisées avec le temps écoulé.

  1. Créez l'activité de fin de jeu et liez-la à l'activité de jeu par l'utilisation d'un Intent (qui devra contenir toutes les informations nécessaires dont notamment le nombre de tentatves ou le temps écoulé).

Exercice 5 - (BONUS) Photos

Plutôt que d'utiliser des assets statiques à l'application, on désire utiliser les photos prises avec notre appareil.

  1. Créez une activité d'accueil pour notre application avec deux boutons : un bouton pour capturer une photo et un bouton pour lancer une partie. Nous n'allons pas utiliser directement l'API de manipulation de la caméra (on pourra toutefois consulter la Javadoc ici). On lancera l'application préinstallée de prise de photo de l'appareil à l'aide d'un Intent. Il faut demander à l'application d'enregistrer les images vers un chemin que l'on spécifie. Il est conseillé de lire attentivement ce tutorial.
  2. Le 2ème bouton de l'activité doit permettre de lancer une nouvelle partie en utilisant toutes les photos que nous venons de prendre. Comment pourrait-on faire si l'on souhaitait récupérer TOUTES les photos déjà prises par l'utilisateur (pas seulement les photos prises depuis l'application) ?
  3. Rajoutez un 3ème bouton qui permet de lancer une partie en utilisant classiquement les assets fournies avec l'application.

Exercice 6 - (BONUS) Dialogue

On souhaite proposer à l'utilisateur le choix du nombre de paires de cartes à jouer.

  1. Faites en sorte que lorsque l'on clique sur le bouton de lancement de jeu, un dialogue s'ouvre demandant au joueur le nombre de paires à utiliser. Ce dialogue doit comprend également un bouton Cancel qui permet de ne pas lancer de partie.