Dot.Blog

C#, XAML, WinUI, WPF, Android, MAUI, IoT, IA, ChatGPT, Prompt Engineering

Création de jeux et détection de touches clavier multiples sous xaml

Xaml est conçu pour s'intégrer dans des chaînes de développement "sérieuses". Son but est principalement la création d'Apps LOB ou utilitaires le plus souvent associées à des applications métier desktop. Avec MAUI il s'agit en fait de porter WPF sur les devices mobiles et de faire ainsi converger applications "desktop" et applications mobiles de façon transparente. Mais Xaml est aussi un merveilleux outil pour écrire des jeux ou autres Apps ayant le même type d'interaction. Plus loin, et j'en parle souvent, les techniques visuelles du jeu ne sont pas à négliger pour créer des applications professionnelles disposant d'interfaces innovantes.

Raison de plus pour se pencher sur la question. Aujourd'hui je vais aborder la gestion du clavier. Pour ce qui est de la boucle de jeu elle dépend du contexte.

Tout le problème pour des interactions directes en desktop est de détecter plusieurs touches appuyées en même temps. 

Pour une gestion de déplacement rudimentaire (les 4 directions par les 4 flèches) cela pourrait parfaitement convenir. Mais comment gérer les déplacements en diagonal (KeyUp+KeyLeft par exemple) ou pire des choses du genre Shift-Ctrl-KeyUp/Barre d'espace ? Il faudrait se rappeler dans l'événement KeyDown si l'une ou l'autre des touches a été enfoncée et si elle est toujours Down... De plus aucune assurance de l'ordre dans lequel les touches vont arriver (la simultanéité n'existe pas du point de vue du pilote clavier, une touche est forcément avant l'autre).

Bref cela semble d'un seul coup se compliquer énormément !

Oui et non. Oui puisque la solution n'est pas directe, non parce que celle-ci n'est pas si compliquée à trouver.

La classe KeyLogger

Ne cherchez pas dans l'aide du Framework, cette classe n'existe pas :-) Il s'agit justement de la classe que je vous propose aujourd'hui de créer pour gérer le petit problème des touches simultanées.

Problématique

On doit pouvoir à tout moment dans la boucle principale du jeu tester si certaines combinaisons de touches sont actives ou non. On doit aussi pouvoir tester l'appui sur une seule touche.

Solution

Il n'y a pas de miracle, pour savoir si une ou dix touches sont appuyées il faut se souvenir de toutes les touches ayant reçu un KeyDown et pas encore de KeyUp. Se souvenir, en informatique, cela signifie stocker des données. C'est bien ce que nous allons faire en créant un tableau dont les éléments seront des booléens et dont l'index sera la valeur de l'énumération Key (classe du Framework listant les touches accessibles du clavier). Ne reste plus qu'à gérer nous-mêmes les KeyUp et KeyDown pour mettre à vrai/faux les cases correspondantes dans le tableau. Pour tester une combinaison de touches (ou une touche) il suffit alors d'interroger le tableau pour savoir si les touches que nous voulons tester sont toutes à true.

Le code

Une fois le problème et la solution posés, il ne reste plus qu'à coder. Plutôt que d'alourdir ce post, je vous renvoie au code source du projet téléchargeable en fin de billet. Ouvrez-le sous Blend ou Visual Studio, vous comprendrez rapidement comment il fonctionne.

Le UserControl principal de l'application exemple commence par créer une instance du KeyLogger et l'attache à lui-même. On pourrait fort bien attacher un KeyLogger différent à différentes zones écran, ici nous optons pour un seul gestionnaire centralisé.

La détection du clavier ne marche que si le contrôle a le focus. Donner par défaut celui-ci au UserControl n'est pas forcément évident, je n'ai pas trouvé de solution qui marche systématiquement. D'où la petite astuce du bouton de démarrage : en cliquant dessus je lance l'animation qui le fait disparaître et qui diminue l'opacité des instructions mais surtout j'en profite de réclamer le focus. Cette technique a l'avantage de fonctionner à tous les coups.

Conclusion

Remplacer le rectangle rouge par une petite fusée, ajoutez des blocs rocheux, détectez la barre d'espace pour tirer, utilisez la gestion de sprites pour animer les tirs de laser, agrémentez d'une gestion de collision, complétez par une gestion de l'inertie des mouvements... et vous aurez une réplique de Asteroid ! Yaka. :-)

Déplacer des objets ou contrôler des animations via le clavier est l'une des bases de la création de jeux. Avec l'exemple de la neige qui tombe nous avions déjà vu la gestion des sprites, vous disposez maintenant des briques pour commencer à réfléchir à des petits jeux sympas (éviter la cent-millième version de Asteroid ou de Space Invader bien entendu :-) )!

Amusez-vous bien, et .... Stay Tuned !

Code source du projet de la classe KeyLogger : KeyTrapper.zip (78,30 kb)

Faites des heureux, partagez l'article !
blog comments powered by Disqus