Créer un jeu en Python

Ce qu’il y a de bien avec les vacances d’été, c’est que cela donne un peu de temps pour sortir de sa routine. Et justement, cela faisait quelque temps que je voulais explorer les possibilités qu’offre Python pour le jeu vidéo.

Créer un jeu vidéo, ce n’est pas simplement programmer des règles de jeu et créer de belles illustrations en pixel-art. C’est des concepts à connaitre pour afficher son jeu et gérer les actions du joueur. Il existe des bibliothèques qui vont nous aider pour cela. L’outil de référence dans ce domaine dans le monde Python, c’est Pygame.

Mais ce qui m’a le plus motivé à m’intéresser à Pygame, c’est la lecture des revues The MagPi et Wireframe. Ces publications issues de la fondation Raspberry Pi sont évidemment orientées éducation. Du coup, leurs exemples ne sont pas à base de Pygame mais de Pygame Zero. Pygame Zero repose sur Pygame (ce dernier reste donc indispensable) et se propose de simplifier la création de jeux par rapport à Pygame. Pour ma part, je n’ai pas l’ambition de devenir développeur de jeux vidéos en Python, juste de m’amuser un peu, alors sur quelle lib partir ?

Pygame et Pygame Zero

Pygame pour commencer est une bibliothèque qui permet de faciliter le développement de jeux. Pygame est construit sur SDL (Simple DirectMedia Layer) qui est une bibliothèque écrite en C. Il nous apporte les bénéfices de SDL en Python. Pygame s’occupe de tout le coté technique pour faire un jeu. Dans les grandes lignes, cela consiste à proposer une boucle qui à chaque itération génère l’image à afficher et réagit aux différentes conditions comme les contacts entre composants ou pression de touches.

Mais par bien des aspects, Pygame reste compliqué. C’est donc pour faciliter l’apprentissage de la programmation pour faire des jeux que Pygame Zero a été créé. Pygame Zero est ce que l’on appelle un Wrapper. Il s’agit donc d’une bibliothèque qui vient envelopper Pygame afin de traduire des instructions simples que vous écrirez en instructions plus complexes de Pygame.

Pygame Zero simplifie les tâches répétitives

À commencer simplement par la préparation d’un fichier de jeu. Avec Pygame Zero, un fichier vide est déjà un fichier valide. Pour afficher une fenêtre de 300 pixels sur 300, il suffit de créer un module avec le code suivant :

WIDTH = 300
HEIGHT = 300

def draw():
    screen.fill((0, 0, 0))

Vous voyez que Pygame Zero repose sur des conventions, il suffit de déclarer certaines variables selon un nom conventionnel comme pour les tailles (ok, ce sont des constantes…). La fonction draw() doit être déclarée et sera appelée par Pygame zero pour créer l’affichage.

Lorsqu’on utilise une bibliothèque, il est nécessaire de l’importer et là, vous voyez qu’il n’y a pas d’import dans le code. Avec Pygame Zero, il n’est pas nécessaire si on lance le programme par la commande :

pgzrun intro.py

Vous vous doutez que pgzrun appelle l’interpréteur Python et opère la magie. C’est pratique et ça simplifie le code, cependant, ce module ne peut pas s’exécuter comme un module standard. Si vous voulez l’exécuter comme un module Python standard, il faudra bien ajouter l’import de pgzrun ainsi que la dernière ligne du code suivant :

import pgzrun

WIDTH = 300
HEIGHT = 300

def draw():
    screen.fill((0, 0, 0))

pgzrun.go()

Cela reste un code assez simple qui va à l’essentiel. Le programme équivalent avec Pygame est le suivant :

import pygame
 
pygame.init()

screen = pygame.display.set_mode((300, 300))
screen.fill((0, 0, 0))
     
running = True
     
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

La différence fondamentale est que vous devez initialiser Pygame (ligne 3) qui vous fournira ainsi les composants nécessaire pour votre jeu (lignes 5 et 11). Vous voyez qu’avec Pygame Zero, l’objet screen est créé automatiquement.

Il vous faut ensuite gérer vous-même la boucle (lignes 10 et suivantes). Ce code est indispensable. En premier lieu pour la boucle en elle même qui fait que le programme ne s’arrête pas net après l’affichage de l’image. Ensuite, pour l’écoute des évènements afin d’offrir la possibilité d’interagir avec la fenêtre.

Autant vous le dire tout de suite, avec Pygame, ça se corse rapidement. Je ne vais pas ajouter d’exemple de code ici, mais sachez par exemple que le rajout d’un sprite (composant de l’image) ne se limite pas à l’affichage. Il est nécessaire d’indiquer à Pygame comment représenter le tout en 2D.

Pygame Zero de son coté permet de gérer les sprites avec une classe dédiée. Dessiner le sprite suffit, Pygame Zero s’occupe du reste.

Pygame Zero est plus simple mais…

Pygame Zero est plus simple, le constat est sans appel. Vous avez de nombreux tutos dans les magazines MagPi et Wireframe qui le démontrent.

Mais j’ai un gros problème avec toute la magie mise en œuvre.

Oui magie. On plaisante dans le monde Python lorsque certains outils facilitent tellement la tâche que l’on se demande comment ils font. Là, le soucis est autre. Cette volonté de simplification fait que vous utilisez des instructions sans savoir d’où elles sortent. Par exemple, dans le premier code, screen n’est défini nul part. Pire, il n’est initialisé nul part. En conséquence, pour n’importe quel environnement de développement, il y aura une erreur de type référence non résolue. Et du coup, il va être compliqué d’utiliser l’aide contextuelle (tel que la complétion) ainsi que la navigabilité dans les sources.

Si j’estime que ce type de code est de mauvaise qualité, Pygame Zero est indéniablement plus abordable. En fait, avec de la pratique, il est même plus productif que Pygame.

Le premier concept : accepter la boucle infinie

En passant, vous avez pu avec cet article découvrir le premier concept pour la création de jeux vidéos. Il s’agit d’un concept présent dans toutes les interfaces Homme/Machine : une boucle infinie.

La plupart des cours d’informatique vous mettent en garde contre les boucles infinies car le programme tourne alors… indéfiniment. Et bien ici, c’est exactement ce que l’on veut. En fait, pas tout à fait indéfiniment : nous allons avoir une condition de sortie (dans notre code Pygame, la fermeture de la fenêtre qui est implicite dans le code Pygame Zero). Nous allons en profiter lors de chaque itération pour faire plein de choses. Le code Pygame montre comment on écoute les actions possible de l’utilisateur, mais on y analyse aussi le comportement des composants, l’application des règles et la génération de l’image suivante.

Vous trouverez plus d’infos dans mon article sur l’automatisation avec la boucle while.

Si vous avez aimé ce post, n’hésitez pas à laisser un commentaire ci-dessous ou sur la page Facebook 😉

À propos de... Darko Stankovski

iT guy, photographe et papa 3.0, je vous fais partager mon expérience et découvertes dans ces domaines. Vous pouvez me suivre sur les liens ci-dessous.

Vous aimerez aussi...

2 réponses

  1. 8 août 2020

    […] La fondation RaspberryPi publie quelques magazines avec l’intention de rendre l’informatique accessible à tous. Wireframe Magazine est une publication lancée en 2018 dédiée à la création de jeux vidéo. Chaque numéro a un petit chapitre dédié à la bibliothèque PyGame Zero qui permet de développer des jeux en Python. […]

  2. 29 avril 2022

    […] Oui mais un jeu vidéo à la Zelda, Mario, Fortnite, il n’y a pas de tours de jeu. Non, en effet, il y a des images. Pour ces jeux, l’objectif sera de déterminer quoi afficher pour chaque image. C’est exactement ce que vous automatise une bibliothèque tel que PyGame. […]

Laisser un commentaire