À vous de jouer !
Je vous propose de réaliser un Gravity Snake : un jeu de “Snake”, mais commandé par inclinaison du device Android.
L’illustration suivante montre un exemple de visuel possible pour cette application, dont les éléments notables sont : un bouton pour lancer et relancer le jeu, un affichage du nombre de pommes mangées, l’affichage d’une pomme (un carré rouge dans cet exemple) et l’affichage d’un serpent, dont on voit que les carrés qui constituent son corps peuvent se superposer partiellement.

Règles et fonctionnement
Le principe général de ce jeu est décrit sur Wikipédia. Vous allez implémenter une version simplifiée des règles, décrite ci-dessous :
Votre jeu n’aura qu’un seul niveau infini et devra attendre que l’utilisateur clique sur un bouton “Start” pour que le jeu commence.
Un serpent sera une liste de carrés, qui peuvent se superposer.
À tout moment, une pomme devra être visible sur le plateau.
Si le serpent mange la pomme, son corps grandit de 1 carré et une nouvelle pomme est placée dans une case vide du plateau.
Si le serpent rentre en collision avec son corps ou avec un bord, alors la partie se termine.
Consignes spécifiques au gravity snake
L’inclinaison du device permettra d’avancer plus ou moins vite. Il sera donc possible que les carrés constituants le corps soient plus ou moins superposés. Mais il ne doit pas y avoir de blanc au milieu du corps du serpent.
Tout arrêt est interdit. Si le device est à plat, alors le serpent doit quand même continuer dans la dernière direction choisie et avec une vitesse minimale arbitraire.
Le serpent ne peut se déplacer que dans 4 sens : haut, bas, gauche et droite. Si une inclinaison est une composition de 2 sens, alors elle sera réduite à sa composante la plus forte (on mettra l’autre à 0).
Votre application devra être un projet Android compilé avec l’API 25 (Android 7.1.1) et devra être rétro-compatible jusqu’à l’API 15 (Android 4.0.3). Vous devrez donc avoir installé les 2 API sur votre ordinateur. Cette contrainte aidera à normaliser vos installations à réduire vos problème d’import du code d’un autre.
Conseils de réalisation
Le corps du serpent est une liste de carrés. Avancer correspondra à supprimer le carré le plus à l’arrière et à faire apparaître un carré en tête.
Vous devez rafraîchir l’affichage, soit à chaque réception d’une nouvelle donnée de capteur (plus simple), soit via un processus externe (plus fluide). La fluidité de l’avancée du serpent ne sera pas un critère d’évaluation.
Utilisez un
View
, unSurfaceView
ou tout autre objet pertinent.N'oubliez pas de respecter les bonnes pratiques en termes de lisibilité, d'indentation et de documentation du code source
Vérifiez votre travail
Vérifiez que vous avez bien les éléments suivants :
L'animation est fonctionnelle
Les données capteurs sont récupérées, converties dans le référentiel de la structure de donnée utilisée et les déplacements sont gérés dans la bonne direction (une seule direction à la fois)
La collision avec la pomme est détectée, avec gestion de l’agrandissement de la taille du serpent
Les cas de fin de jeu sont gérés (collision avec les bords ou avec le serpent)
Le code source est lisible et bien indenté
L'application compile et démarre
Un écouteur valide est créé et enregistré auprès du système
Le capteur est pertinent
La dépendance matérielle est annoncées dans le Manifeste
L'énergie est bien gérée
Le layout utilisé est pertinent, c'est-à-dire
LinearLayout
,ConstraintLayout
,RelativeLayout
et nonTableLayout
ouGridLayout
L'interface est bien dotée d’un bouton et une action est appelée lorsque celui-ci est pressé
L'objet graphique personnalisé (OGP) est bien défini et est correctement inséré dans ce layout, via XML ou Java
L'OGP est correctement défini, soit en héritant de
View
ou deSurfaceView
, soit d’une autre classe pour une bonne raison. Si l'OGP hérite de Button sous prétexte de pouvoir cliquer dessus (par exemple), alors c'est un mauvais choix (toute View est cliquable).L'OGP permet l’affichage d’un serpent et d’une pomme
Les initialisations des différents Paints utilisés sont faites à la création de la vue, et non dans la méthode
onDraw
(oudraw
)