Manette Android pour jeu multijoueur
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
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 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 :
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.
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:
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
|
Souvenez-vous que les actionneurs de votre véhicule attendent des valeurs ente 0 et 1.
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éthodeaddView
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:
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)
L’actionneur "GunTrig" fera feu en continu pour une valeur supérieur à 0.5.
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.
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 :
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.
Menu de débug
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 :
Menu de personnalisation
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:
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").