Ce sujet a été développé par François Suro.

Comme d’habitude il est recommandé de lire le sujet en entier avant de se jeter sur son clavier.

L’objectif de ce thème est de réaliser une application Android permettant de contrôler un véhicule dans un jeu multijoueur en réseau.

Ce projet couvrira les séances de TP restantes. Vous serez évalués en binômes sur le résultat produit.

Objectifs pédagogiques

  • Développer une application plus complète.

  • Intégrer des classes existantes dans une application.

  • Utiliser une vue personnalisée.

  • Manipuler des communications par socket Wifi.

  • Proposer des solutions originales pour développer une application attrayante.

Rendu

Pour le rendu, vous devez vous conformer aux Consignes Git

Le nom de votre dépôt devra être "Android_Nom1_Nom2"

L’historique de vos commits sera évalué. Vous créerez un dossier pour vos documents de conception (dessins, schémas, cahier des charges …​).

Vous devez créer un fichier readme contenant la liste des fonctionnalités que vous avez implémentées, leur description succincte et leur justification du point de vue pédagogique.

exemples:

  • Liste des profils utilisateurs: les classes x y et z implémentent le système de listes , etc .. . Nous avons utilisé un RecyclerView et son adapter présentés en cours.

  • Gestion des threads : les classes w u v implémentent la gestion de threads pour l’envoi de base de données. Nous avons utilisé le mécanisme de handler et les files de messages (voir ligne xxx de la classe uuu).

  • …​

Git

Procédure normale :

L'idéal est de créer un dépôt vide sur gitlab, de le cloner sur votre machine, puis de créer le projet Android dans le répertoire résultant du clonage.

Si vous ne savez pas lire les consignes et que vous avez créé votre projet avant de cloner votre dépôt:

Si toutefois vous avez déjà un projet existant il est possible d’ajouter le projet à un dépôt git local puis de lui ajouter une "remote": Vous pouvez réaliser cela dans Android Studio ou en ligne de commande :

git init

git remote add gitlab https://url_qui_va_bien

git push gitlab main

Vous pouvez obtenir l’url à utiliser sur la page d’accueil de votre projet sur GitLab.

Pour plus d’informations : l’aide Git à propos de GitLab.

Ce qui est fourni

  • Une classe permettant (Lien / Doc):

    • d’établir une connexion avec un autre appareil via un Socket (wifi/ethernet),

    • d’envoyer des données via cette connexion,

    • de recevoir des données via cette connexion.

  • Une classe implémentant une View personnalisée permettant de simuler un joystick (Lien).

  • Une application Java permettant de créer un serveur de jeu (Lien / Doc).

Utilisation du serveur de jeu

Vous pourrez vous connecter au serveur de jeu commun, avec l’adresse IP fournie par votre encadrant de TP.

Vous connecterez l’appareil Android au même réseau wifi que pour le débogage :

  • SSID : RTAB

  • PASS : wifirtab

Si vous souhaitez lancer le serveur de jeu sur une machine personnelle, utilisez la commande suivante :

$java -jar AndroidGameServer.jar

La fenêtre console du serveur devrait montrer l’adresse de votre serveur. Si ce n’est pas le cas, vous pouvez entrer la commande suivante :

$ hostname -I

Première étape

Dans un premier temps, vous devez réaliser une application qui permet à l’utilisateur de se connecter au serveur à l’aide de la classe fournie. Pour cela il faut fournir l’adresse du serveur.

Le layout de cette première version ressemblera à ceci :

simple

Pour intégrer la classe de communication, vous devez ajouter le contenu de cette archive dans les sources de votre projet. La documentation de cette classe se trouve ici. Notez que cette classe possède une méthode permettant d’afficher son activité dans les logs.

Il faudra modifier les déclarations de package dans les classes fournies et modifier les directives import en conséquence.

Une fois cette application réalisée, connectez-vous au serveur. Vous devriez voir votre avatar apparaître dans la zone de jeu.

Deuxième étape

Une fois la connexion établie, vous créerez une seconde activité contenant des boutons spécifiques au contrôle de votre véhicule. De nombreuses solutions sont possibles, vous pourrez plus tard proposer ce qui vous semble le plus pertinent, dans un premier temps quatre boutons ("avancer","tourner droite","tourner gauche","stop") suffiront.

Le principe de base de déplacement du véhicule est d’appliquer un niveau de puissance aux moteurs des roues droite et gauche. Par exemple si le moteur droit et gauche reçoivent une puissance égale, le véhicule se déplacera en ligne droite (avant ou arrière selon la commande). Si la puissance du moteur droit et gauche est différente, le véhicule effectuera un virage.

Vous validerez que les boutons envoient des données compatibles avec ce que le serveur attend. Une commande est décrite par son nom et la ou les valeurs associés. Le nom est séparé de la valeur par le symbole "=". Plusieurs commandes peuvent être enchaînées dans le même message en les séparant par le caractère "#". Quelques exemples de commandes :

  • MotL=0.5 → assigne la puissance de moteur gauche à la valeur 0.5 (neutre)

  • MotR=1.0#MotL=1.0 → assigne la puissance de moteur droit et gauche à la valeur 1.0 (pleine vitesse avant)

  • EXIT → demande la déconnexion du serveur (commande sans valeur associée)

La liste minimale des commandes à implémenter sont les suivantes :

  • "MotL" : puissance du moteur gauche. Argument: réel compris entre 0 et 1 (0 pleine vitesse arrière, 1 pleine vitesse avant, 0.5 stop)

  • "MotR" : puissance du moteur droit. Argument: idem MotL.

  • "EXIT" : Quitter la partie. Argument: aucun.

La documentation complète du serveur se trouve ici

Troisième étape : Joystick

Dans cette étape, vous intégrerez la View JoystickView fournie dans une nouvelle activité qui ressemblera à quelque chose comme ça:

joystick

Cette activité permettra à l’utilisateur d’envoyer des commandes en continu au robot. Les commandes à envoyer correspondent aux vitesses gauche et droite calculées par la classe JoystickView.

Pour accéder à ces valeurs calculées, vous définirez une classe héritée de l’interface ValueChangedHandler que vous assignerez à votre instance de JoystickView par la méthode setValueChangeHandler (ou par le constructeur de la classe).

Note
Format de données pour le joystick
  • Vg → Puissance calculée pour le moteur gauche. Comprise entre -sVMax et +sVMax

  • Vd → Puissance calculée pour le moteur droit. Comprise entre -sVMax et +sVMax

Souvenez-vous que les actionneurs de votre véhicule attendent des valeurs ente 0 et 1.

La classe JoystickView fournie n’est pas une activité

Pour ajouter une JoystickView à votre activité, vous devez le faire par programme, en Java, dans le code de votre activité. Pour cela:

  • ajoutez un conteneur, par exemple un FrameLayout dans le layout de la nouvelle activité

  • Récupérez ce conteneur dans le onCreate de la nouvelle activité

  • Ajoutez une nouvelle instance de JoystickView au conteneur avec la méthode addView

Pour les paramètres de création du JoystickView voyez sa documentation.

Quatrième étape : Jeu multijoueur

Pour pouvoir participer au jeu multijoueur vous aurez besoin d’implémenter les fonctionnalités suivantes:

--xXx D4rThR0XX0R_92 xXx--

Permettez au joueur de changer son pseudonyme. Pour ce faire, envoyez la commande "NAME" suivie du pseudonyme (n’oubliez pas le séparateur d’argument)

BOOM HEADSHOT !!!!!!

L’actionneur "GunTrig" fera feu en continu pour une valeur supérieur à 0.5.

AFK at spawn…​

Si le serveur ne reçoit aucun message dans un délai donné, le joueur est automatiquement déconnecté. Plusieurs solutions sont possibles pour éviter cela, notamment l’envoi du message "LIVE" (sans aucun effet) à intervalle régulière.

Denial of service

Afin de ne pas surcharger le serveur, il est recommandé, notamment pour le joystick, d’ajouter des délais entre les envois de données. Il n’y a pas de contraintes sur la longueur des messages, uniquement sur le nombre. Si vous surchargez le serveur, vous serez déconnectés et perdrez votre score :( .

Cinquième étape : Félicitations !

Vous avez réalisé l’app minimale permettant de jouer. Cependant, il existe sûrement des dizaines d’applications similaires sur le marché et il va falloir vous démarquer si vous voulez avoir un million de téléchargements ! (ou plus de 10 au contrôle continu …​)

Quelques remarques générales sur ce qui peut rendre une application attrayante :

  • L’application fonctionne sans défauts : perte de données/travail, bugs, lags, ou pire freeze, sont rapidement sanctionnés par une désinstallation de votre application, voire par un commentaire négatif !

  • Développer un maximum de fonctionnalités/exploiter les possibilités : votre application se connecte et agit sur un serveur, considérez toutes les commandes qui sont mises à votre disposition.

  • Offrez le plus de personnalisation possible à l’utilisateur : le joueur doit s’approprier le programme, créer son identité en jeu, avec son pseudonyme par exemple, ou encore des options esthétiques ou des messages personnels/emotes.

  • Facilitez l’utilisation de l’application : des menus clairs, facile d’accès évidement, mais aussi éviter de faire répéter les mêmes opérations sans arrêt (par exemple entrer son nom ou les adresses de serveurs à chaque partie).

  • Donnez un avantage aux utilisateurs de votre application par rapport aux autres utilisateurs du même service/rendez votre application attrayante pour d’autres raisons que sa fonction première : à vous de gérer vos dilemmes moraux…

EVALUATION

Du point de vue de l’évaluation, nous tiendrons compte du nombre et de la qualité des fonctionnalités ajoutés, de la présentation et de l’aspect professionnel de l’application, de l’intégration et du respect des concepts présentés en cours ainsi que de l’originalité des propositions.

Vous devez lister les fonctionnalités que vous avez implémentées dans le fichier readme de votre dépôt, ainsi que leur description succincte et leur justification du point de vue pédagogique.

exemples:

  • Liste des profils utilisateurs: les classes x y et z implémentent le système de listes , etc .. . Nous avons utilisé un RecyclerView et son adapter présentés en cours.

  • Gestion des threads : les classes w u v implémentent la gestion de threads pour l’envoi de base de données. Nous avons utilisé le mécanisme de handler et les files de messages (voir ligne xxx de la classe uuu).

  • …​

Ci-après quelque pistes pour développer votre projet:

Éviter de bloquer le thread UI

Pour le moment toutes les actions de communication se font dans votre thread UI. Or il est fortement déconseillé de faire ce type d’opération, potentiellement bloquantes, dans le thread principal puisque cela risque de bloquer l’interface utilisateur de votre application (notamment si vous tentez d’envoyer des requêtes au serveur…​).

Pour remédier à ce problème, il est souhaitable de réaliser ces opérations dans un thread d’arrière-plan. Pour réaliser cela vous placerez les opérations de connexion et d’envoi de données dans des threads dédiés. N’oubliez pas que vous ne pouvez pas modifier l’interface utilisateur à partir d’un thread d’arrière-plan.

Pour vous faciliter la tâche, il peut être utile de vous créer une console/menu de débug pour tester l’envoi et la réception des différents messages.

Le layout de ce menu pourra ressembler à ceci :

simple

Proposez un menu ou le joueur pourra personnaliser son apparence en jeu, et sauvegarder les paramètres de cette personnalisation.

Voici un exemple de ce genre de menus, tirés d’un jeu célèbre:

simple

Control map

Proposez d’autres façons de contrôler le véhicule en jeu, et développez les interfaces associées (boutons , joystick, slider, gyroscope de la tablette, gamepad connecté en bluetooth …​).

Créez un menu permettant aux joueurs de choisir (et sauvegarder) le type de contrôle qu’il souhaite utiliser.

Interaction joueurs

Proposez par exemple un système de message rapides ou d’émotes, pour féliciter (ou moquer) vos adversaires et vous cordonner avec vos équipiers. Concevez un menu permettant de les utiliser facilement durant la partie ou de les envoyer automatiquement sous certaines conditions.

Favorites / History

Développez le menu de connexion afin de conserver l’historique et d’enregistrer des serveurs favoris. Le joueur pourra ainsi se reconnecter aux serveurs enregistrés sans entrer à nouveau l’adresse. Offrez la possibilité d’assigner un nom personnalisé à chaque favori. Ajoutez une fonction de recherche par nom ?

I’m iN ur BaZe, KiLliN Ur D00Dz

Exploitez les possibilités offertes par les commandes du serveur pour gagner à tout prix…​ tant pis pour le fair-play.

Pas de pitié pour le consommateur

Jouez sur les mécanismes d’addiction pour "fidéliser" vos utilisateurs. Créez des buts artificiels et des récompenses sans valeurs basées sur le temps passé à utiliser l’application.

Vous pouvez par exemple comptabiliser le nombre de parties jouées et présenter une barre de progression sur le menu principal. Comptabiliser le score cumulé des parties jouées et donner des "titre" et "achievements" comme récompense.

Vous pourrez certainement trouver d’autres exemples des méthodes utilisés par les compagnies privées (ex: "surprise mechanics").