Julien Jorge's Personal Website

Version 2 de Bim!, avec des menus

Mon Sep 23, 2024

Ce post a été publié sur LinuxFr.org. Vous pouvez le lire là bas, ainsi que les commentaires associés

Bonjour ’nal,

Ah je suis content de te voir :) Je viens de sortir un nouvel APK de mon jeu Bim!, le deuxième depuis la dernière fois que je t’en avais parlé. Entre temps j’ai surtout travaillé sur l’interface des menus, plus quelques corrections et ajustements ici et là.

Bim! est un jeu de type last-man-standing, très arcade, et fortement inspiré de Bomberman/Dyna Blaster, même s’il doit à terme s’en éloigner. Il se joue uniquement en ligne, de deux à quatre joueurs. Il n’y a pas d’IA ici ; les parties se font toujours entre humains.

Des menus

Le jeu utilise le moteur Axmol, qui est très bien pour afficher des trucs mais a peu de facilités pour gérer des écrans de jeu. Il y a bien quelques trucs mais de souvenir de Cocos2d-x, dont Axmol est un fork, ce n’était pas top. Du coup je bricole un truc par dessus pour faire mes interfaces.

Pour commencer, fini l’écran noir en entrant dans le jeu, on a maintenant un peu de couleur et d’animation :

C’est quand même plus sympa. Là on ne le voit pas mais le fond de l’écran et le fond du bouton sont animés. Il manquerait plus qu’un logo. De là on ne peut que lancer une partie et tomber sur l’écran de recherche d’adversaire :

Après que tous les joueurs aient validé cet écran on passe au match en lui-même :

Bon, là aucun travail n’a été fait, donc ça reste moche. Mais ça n’empêche pas de s’amuser !

Lorsque le match est terminé on passe sur l’écran de fin de partie d’où on peut relancer un match ou revenir à l’écran principal :

Et voilà. Ça va, c’est pas moche ! Et si on n’a pas de chance on peut aussi apercevoir la belle interface des popups :

Pfiou, trois mois pour ça… Bon ça va, il y a aussi du travail sous le capot dont je parle dans la section suivante :)

On ne le voit pas sur les captures mais il faut aussi savoir que tout cela appelle une gestion de transition d’un écran à l’autre qui demande un peu de rigueur. Il y a aussi pas mal de travail fait pour que l’interface s’adapte joliment aux diverses résolutions de téléphone (e.g. réduction globale de la taille des polices sur les écrans plus petits que le modèle de référence).

Tiens, un petit exemple du besoin de faire quelque chose au dessus d’Axmol et autres subtilités pour s’adapter aux différents appareils.

Le fonctionnement d’Axmol est de placer les nœuds d’affichage dans un canevas d’une taille fixe puis de redimensionner l’ensemble à la résolution de l’écran de l’appareil. Par exemple si je fais la conception sur un canevas de 768×1280 et que l’appareil a une résolution de 1536×2560 alors tout sera étiré ×2 sur les deux dimensions. En particulier, les textes seront un peu flous. Il vaut donc mieux avoir un système qui augmente la taille des polices globalement pour garder un rendu net.

Autre subtilité, pour les boutons j’utilise un 9-slices, ce qui est assez classique :

Illustration de la différence d’un redimensionnement d’un carré, à gauche, vers un rectangle, à droite, en étirement classique en haut, et 9-slices en bas — Alwik, Wikipedia.

Selon ce principe les coins des composants sont toujours à l’échelle 1 tandis que les zones centrales sont étirées pour remplir l’espace. Et bien si je prenais juste le 9-slices d’Axmol alors mon coin de 50×50 pixels sur mon 768×1280 ferait toujours 50×50 pixels sur l’appareil en 1536×2560. Il aurait l’air deux fois trop petit ! Pour compenser cela il faut adapter l’échelle du 9-slices en fonction de la résolution de l’appareil.

Grace à ces changements le jeu s’affiche maintenant correctement sur un Nexus 4 tout comme sur un Pixel 3.

Nouveautés de gameplay ou internes

J’avais précédemment tenté de compenser un peu la latence du réseau en forçant un petit délai entre le moment où le joueur presse le bouton et le moment ou l’action est effectuée. Ça évitait quelques surprises où on voyait un joueur faire une action pour ensuite la voir annulée parce qu’elle avait été mal prédite. Malheureusement cela causait aussi des difficultés de jeu puisqu’on déposait par exemple les bombes quelques cycles plus tard, donc pas là où on était quand on a appuyé sur le bouton. C’était très frustrant. Maintenant les bombes sont toujours posées là où le joueur était quand il a appuyé sur le bouton.

De plus, les bombes sont affichées dès que le bouton est pressé, bien qu’elles ne seront prises en compte par la boucle de gameplay que quelques cycles plus tard. Cela réduit fortement l’inconfort lié au lag.

Toujours sur le sujet de la synchro réseau, j’ai augmenté la fréquence d’envoi des actions de jeu, réduisant ainsi l’écart de la simulation avec le serveur. De plus, si un joueur va trop vite (il a trop d’avance sur le serveur) alors la simulation sera légèrement ralentie de son côté pour tenter de réduire l’écart.

Une liste de serveurs de jeu est maintenant récupérée du serveur web lors du lancement de l’application. Celle-ci se connecte alors au premier serveur disponible qui utilise la même version du protocole de communication. Cela devrait permettre des montées de version plus douces en laissant des serveur anciens tourner le temps que les joueurs fassent la mise à jour.

J’ai revu le système de matchmaking au niveau du serveur. Il faut savoir qu’il y a un mode permettant de trouver des adversaires dans une salle nommée, afin de jouer avec des amis. Ce n’est pas encore disponible dans le client mais le serveur le supporte et des tests valident la fonctionnalité. Auparavant ce mode et le mode adversaire aléatoire partageaient la même collection de parties. Ce n’était vraiment pas pratique dans des scénarios où les joueurs lancent des parties en boucles. Maintenant chaque service gère ses propres parties et il est plus simple pour le serveur de savoir si un joueur est toujours dans une partie.

En parlant de parties sur le serveur, celui-ci fait maintenant tourner la simulation du jeu. Auparavant il se contentait de faire le passe-plat entre les joueurs, transmettant les actions des uns aux autres. Maintenant il sait où en est la partie et peut donc savoir si elle est terminée ou non. C’est aussi lui qui dit aux clients que la partie est terminée, avec tel résultat.

Il faut voir qu’avec la communication en UDP entre les clients et le serveur les infos arrivent vraiment n’importe comment. Elles arrivent vite, mais en vrac. Cela fait qu’on peut sans difficulté se retrouver avec un message de recherche d’adversaire de la part d’un joueur suivi d’une action en jeu de ce même joueur ! Il suffit que le joueur ait rapidement enchaîné une partie puis une recherche pour qu’un message de la première, un peu perdu sur Internet, se fasse doubler par un message de la seconde. Dès lors, c’est l’enfer à gérer côté serveur. Maintenant que le serveur sait si la partie est en cours, il peut ignorer les messages qui ne concernent pas la partie, et inversement, il va ignorer les messages d’une partie une fois que celle-ci est terminée.

Le matchmaking est un gros sujet, ça mériterait un article à part.

En dehors de tout cela il y a eu pas mal de « petites » choses telles que les adaptations pour développer directement sur le téléphone (cf. mon dernier journal), quelques mises à jour, de bibliothèques et d’outils sur la CI, pas mal de tests automatiques supplémentaires, et enfin l’ajout d’un readme !

Un coup de main

Je t’épargne l’habituel « on cherche des contributeurs », parce qu’en fait je n’aurai pas le temps de gérer des contribs :) Par contre j’aimerais bien ton avis sur un truc.

Au départ j’avais un client en mode texte, pour valider les premières étapes du développement (gameplay, communication client-serveur). Je l’ai ensuite supprimé car c’était difficile de le maintenir mais finalement je me dis que ça serait bien pratique, en plus d’être hyper cool. Par exemple, si j’avais un client texte, je pourrais m’en servir pour faire tourner des robots pour les tests. Malheureusement je bloque sur un truc.

Le problème étant que le joueur se déplace en jeu progressivement d’une case à la voisine. Même s’il est toujours dans une seule case du point de vue du jeu, il y a quand même une progression visuellement. Cette progression, je ne vois pas du tout comment la faire dans un affichage en mode texte. J’ai le sentiment que dans une telle interface ce sera très frustrant de voir le joueur « bloqué » sur une case pendant 8 cycles avant de passer à la suivante.

Je sais bien que je n’ai pas besoin de l’affichage pour avoir des robots mais quitte à avoir un client sans GUI, autant qu’il soit cool (et l’affichage c’est quand même bien pour debuguer).

Toi qui a connu les jeux en mode texte, as-tu connaissance d’une astuce, d’une technique, pour rendre progressive la transition d’une case à sa voisine ? Si tu as des références de jeux qui faisaient ça bien, ça m’intéresse.

On joue ?

Jusque là le serveur a plutôt tourné en mode facile, genre trois clients max en simultané en dehors des tests. Est-ce que ça te dirait de le faire chauffer un peu ? On dit rendez-vous à 13 h (France métropolitaine) tous les jours de cette semaine pour une petite partie en attendant le dessert, et puis tu me diras dans les commentaires si tu as rencontré des problèmes.

Pour l’installation, c’est par ici.