I. Introduction à Pygame

Cet article est une introduction à la bibliothèque Pygame pour les programmeurs Python. La version originale est parue dans Pyzine, volume 1, issue 3. Cette version contient des révisions trop mineures pour créer un nouvel article. Pygame est une bibliothèque d'extension de Python enveloppant la bibliothèque SDL.

II. Histoire

Pygame a commencé durant l'été 2000. Connaissant le langage C depuis des années, j'ai découvert Python et SDL en même temps. Si vous êtes déjà familiarisé avec Python, (qui en était à la version 1.5.2), vous pourriez avoir besoin d'une introduction à SDL, acronyme signifiant : Simple Directmedia Library. Créée par Sam Lantinga, SDL est une bibliothèque multiplateforme écrite en C afin de gérer le multimédia pouvant être comparé à DirectX. Elle a été utilisée par des centaines de projets commerciaux et de jeux open source. J'ai été impressionné par la propreté et la simplicité des deux projets et j'ai vite réalisé qu'associer Python et SDL étaient une idée intéressante.

J'ai découvert un petit projet existant avec exactement la même idée : PySDL. Créée par Mark Baker, PySDL était une implémentation de SDL pour Python. L'interface était propre, mais je trouvais que ce code était trop proche du C. La mort de PySDL m'a encouragé à lancer un nouveau projet.

J'ai cherché à faire un projet tirant réellement profit de Python. Mon but était de permettre de réaliser facilement des choses simples aussi bien que des choses plus complexes. Pygame a commencé en octobre 2000. Six mois plus tard, la version 1.0 faisait son apparition.

III. Un avant-goût

Je trouve que le meilleur moyen pour saisir le fonctionnement d'une nouvelle bibliothèque est de plonger directement dans un code d'exemple. Dès les premiers jours avec Pygame, j'ai créé une animation de balle rebondissante en sept lignes de code. Jetons un coup d'œil à une version simplifiée de la même chose.

 
Sélectionnez
import sys, pygame
pygame.init()
 
size = width, height = 320, 240
speed = [2, 2]
black = 0, 0, 0
 
screen = pygame.display.set_mode(size)
 
ball = pygame.image.load("ball.bmp")
ballrect = ball.get_rect()
 
while 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()
 
    ballrect = ballrect.move(speed) 

    if ballrect.left < 0 or ballrect.right > width:
        speed[0] = -speed[0]

    if ballrect.top < 0 or ballrect.bottom > height:
        speed[1] = -speed[1]

    screen.fill(black)
    screen.blit(ball, ballrect)
    pygame.display.flip()

(Si vous voulez essayer cet exemple, placez une image nommée ball.bmp dans le même dossier que le script.)

  • C'est la façon la plus simple d'obtenir une animation de balle rebondissante. On voit au début du code l'importation et l'initialisation du module Pygame, ce qui n'est pas très intéressant. Le import pygame importe tous les modules disponibles de Pygame. L'appel de pygame.init() initialise chacun de ces modules.
  • À la ligne 8, une fenêtre graphique est créée par l'appel de pygame.display.set_mode(). Pygame et SDL nous simplifient la vie en sélectionnant par défaut les modes graphiques les plus adaptés au matériel graphique. Vous pouvez outrepasser ce mode et Pygame compensera tout ce que le matériel ne peut pas faire. Pygame représente les images comme des objets Surface. La fonction display.set_mode() crée un nouvel objet Surface représentant l'image affichée à l'écran. Tous les dessins que vous faites sur cette surface seront visibles à l'écran.
  • À la ligne 10, nous chargeons notre image de balle. Pygame supporte une grande variété de format d'image, comme la bibliothèque SDL_image, les formats pris en compte sont : JPG, PNG, TGA et GIF. La fonction pygame.image.load() nous retourne la surface contenant l'image de la balle. La surface gardera toutes les propriétés (couleur clé et/ou de transparence alpha) du fichier d'origine. Après le chargement de l'image de la balle, nous créons une variable ballrect. Pygame possède un objet très utile nommé Rect qui représente une zone rectangulaire. Dans la partie du code chargée de l'animation, nous verrons quel est le rôle des objets Rect.
  • À la ligne 13, notre programme est initialisé et prêt à être lancé. À l'intérieur d'une boucle infinie qui gère les évènements générés par l'utilisateur, le code dessine et déplace la balle. Si vous êtes habitué avec la programmation de GUI (Graphical User Interface, ou Interface Utilisateur Graphique), vous avez certainement une notion de ce que sont les évènements. Avec Pygame, il s'agit de la même chose. Lorsqu'un évènement se produit, le programme l'intercepte et agit en conséquence. Le premier évènement pris en compte est l'action de quitter le programme. Si cet évènement survient, le programme agit en conséquence en appelant la méthode sys.exit().
  • Ensuite vient le traitement de l'actualisation de la position de la balle. Les lignes 17 et 21 déplacent la variable ballrect par sa vitesse courante. Si la balle s'est déplacée à l'extérieur de l'écran, la vitesse de la balle est inversée pour qu'elle reparte dans l'autre sens. Ça ne correspond pas exactement aux lois de Newton, mais ce n'était, de toute façon pas l'objectif de ce premier programme.
  • À la ligne 23, nous effaçons l'écran en le remplissant de noir. Si vous n'avez jamais travaillé avec des animations, ceci peut vous paraître étrange. Vous pouvez vous demander : pourquoi avons-nous besoin de tout effacer ? Pourquoi n'avons-nous pas juste la balle à bouger sur l'écran ?, ceci n'est pas vraiment la manière de fonctionner des animations sur ordinateur. Une animation n'est rien de plus qu'une succession d'images, mais cette succession d'images est tellement rapide que le cerveau humain voit une animation. screen n'est qu'une image que l'utilisateur voit. Si vous n'avez pas pris le temps d'effacer la balle de l'écran, nous pourrions voir la trace de la balle tout en continuant de voir la balle dans ses nouvelles positions.
  • À la ligne 24, nous dessinons l'image de la balle sur l'écran. Le dessin de ces images est géré par la méthode Surface.blit(). Un blit signifie que l'on copie les couleurs de chaque pixel d'une image sur une autre. Avec la méthode blit(), on prend une surface dite source que l'on applique sur la surface destination, le tout à une position définie.
  • La dernière chose dont nous avons besoin est la mise à jour de l'affichage. Pygame gère l'affichage avec un double tampon (double buffer). Quand nous avons fini de dessiner, nous faisons appel à la fonction pygame.display.flip(). Ceci fait que tout ce que nous avons dessiné sur la Surface screen devient visible. Cette mise en tampon fait que nous sommes sûrs de voir des images complètes dessinées à l'écran. Sans cette manipulation par tampon, l'utilisateur verrait l'image se dessiner au fur et à mesure sur son écran.

Ceci conclut notre courte introduction à Pygame. Pygame possède plusieurs modules pour gérer les entrées de la souris, du clavier et du joystick. Il est aussi possible de mixer des fichiers audio et de décoder des flux musicaux. Avec les Surfaces, vous pouvez dessiner des formes simples, les faire pivoter et/ou les redimensionner. Vous pouvez même effectuer des transformations en temps réel plus complexes sur les pixels avec les tableaux NumPy. Pygame peut lire les vidéos MPEG et supporte les CDs audio. Pygame a également la capacité d'agir en tant que couche d'affichage multiplateforme pour PyOpenGL. La plupart des modules de Pygame sont écrits en C, peu sont en Python.

Le site Internet de Pygame possède une documentation de référence complète pour chaque fonction de Pygame et plusieurs tutoriels pour tout niveau d'utilisateur. Les sources de Pygame viennent avec de nombreux exemples comme un jeu de tir d'OVNI et un combat de singe.

IV. Python et les jeux

Python est-il approprié pour les jeux ?
La réponse est : cela dépend du jeu.

Python est en fait capable de faire tourner des jeux. Cela vous surprendra toujours de savoir tout ce qu'il est possible de faire en trente millisecondes. Toutefois, il n'est pas difficile d'atteindre la limite une fois que votre jeu commencera à devenir plus complexe. N'importe quel jeu fonctionnant en temps réel utilisera pleinement l'ordinateur.

Depuis plusieurs années, il y a une tendance intéressante dans le développement de jeux : l'utilisation de langage de plus haut niveau (plus proche de l'utilisateur que de la machine). Généralement, un jeu est divisé en deux parties majeures. Le moteur de jeu, qui doit être le plus rapide possible et la logique de jeu, qui commande le moteur de jeu. Il n'y a pas si longtemps, le moteur était écrit en assembleur avec quelques portions en C. De nos jours, le C est plus présent dans les moteurs de jeu, tandis que le jeu en lui-même est écrit en langage de script de haut niveau. Les jeux comme Quake3 et Unreal Tournament exécutent ces scripts en tant que bytecode portable.

Dans le courant 2001, les développeurs de Rebel Act Studios ont fini leur jeu, Severance: Blade of Darkness. Ce jeu utilise un moteur de jeu 3D modifié, le reste du jeu est écrit en Python. Le jeu est un jeu d'action à la 3e personne. Vous contrôlez un guerrier médiéval attaquant et explorant des donjons. Vous pouvez télécharger le 3e addon pour ce jeu et vous verrez qu'il n'y a rien d'autre que des fichiers sources en Python.

Beaucoup plus récemment, Python a été utilisé dans une grande variété de jeux comme Freedom Force et Humungous' Backyard Sports Series.

Pygame et SDL s'utilisent comme un excellent moteur de jeu en C pour des jeux en 2D. Les jeux trouvent en grande partie ce dont ils ont besoin dans la SDL pour le graphisme. SDL peut avantageusement utiliser l'accélération graphique matérielle. Vous pouvez optimiser le jeu pour lui faire afficher entre 40 et 200 FPS (images par seconde). Lorsque l'on voit qu'un jeu en Python peut afficher 200 FPS, on réalise que Python et les jeux peuvent se combiner.

Il est impressionnant de savoir que Python et SDL fonctionnent sur de multiples plateformes. Par exemple, en mai 2001, j'ai actualisé complètement mon projet avec Pygame : SolarWolf, un jeu d'action et d'arcade. Une chose qui m'a étonné est qu'après un an, il n'avait toujours pas eu besoin de patches, correction de bogues, ou de mises à jour. Le jeu était entièrement développé sous Windows, mais tournait aussi sous Linux, Mac OSX et plusieurs Unix sans aucun travail de ma part.

Toutefois, il y a clairement des limitations. La meilleure manière de gérer l'accélération matérielle n'est pas toujours la meilleure façon d'avoir des résultats plus rapides que l'accélération logicielle. L'accélération n'est pas disponible sur toutes les plateformes. Quand un jeu devient trop complexe, il doit souvent se réduire à une seule plateforme. La SDL a également quelques limitations de conception, des choses comme le scrolling en plein écran peuvent réduire fortement la vitesse du jeu, jusqu'à ce que ça devienne injouable. SDL n'est pas fait pour tous les types de jeux, mais souvenez-vous que des entreprises comme Loki ont utilisé la SDL pour faire fonctionner une grande variété de jeux de qualité.

Pygame est un langage bas niveau quand il est utilisé pour coder les jeux. Vous aurez rapidement besoin d'envelopper des fonctions communes pour votre environnement de jeu. C'est en grande partie dû au fait qu'il n'y a rien dans Pygame pour cela. Votre programme a le contrôle total sur tout. Vous constaterez que l'effet indésirable à cela est que vous devrez écrire beaucoup de code ennuyeux pour obtenir une structure plus avancée. Vous aurez besoin d'une meilleure compréhension de ce que vous faites.

V. En conclusion

Le développement de jeux vidéo est un travail qui en vaut la peine. Il y a quelque chose d'excitant dans le fait de pouvoir voir et interagir avec le code que vous avez écrit. Pygame est actuellement utilisée par plus de trente projets. Plusieurs sont jouables dès maintenant. Vous allez être surpris en visitant le site Internet de Pygame et voir ce que les autres utilisateurs sont capables de faire avec Python.

Une chose qui a retenu mon attention est que beaucoup de personnes se sont mises à utiliser Python pour leurs premiers essais en développement de jeux. Je peux voir pourquoi les jeux attirent de nouveaux programmeurs, mais il peut être difficile de créer un jeu qui requiert une compréhension plus solide du langage. J'ai essayé de soutenir ce type d'utilisateurs en écrivant plusieurs exemples et tutoriels sur Pygame pour les personnes nouvelles à ces concepts.

Pour finir, mon conseil est de faire au plus simple. Je ne peux assez insister sur ce point. Si vous prévoyez de créer votre premier jeu, sachez qu'il y a beaucoup à apprendre. Même un jeu simple est un défi et les jeux complexes ne sont pas nécessairement de bons jeux. Lorsque vous comprenez Python, vous pourrez utiliser Pygame pour créer un jeu simple en une ou deux semaines. Mais pour avoir un jeu complètement présentable, il vous faudra de nombreuses heures de travail.

VI. Vue d'ensemble des modules de Pygame

Voici un récapitulatif des modules disponibles dans la bibliothèque de Pygame, avec un lien sur la documentation de référence de chacun de ces modules.

Cdrom
Accéder et contrôler les lecteurs CD audio.
Cursors
Charger et compiler des images de curseur.
Display
Configurer la surface d'affichage.
Draw
Dessiner des formes simples comme des lignes et des ellipses sur des surfaces.
Event
Gérer les évènements à partir de différents matériels d'entrée (clavier, souris…), ainsi que du fenêtrage.
Font
Charger et faire un rendu des polices TrueType.
Image
Charger, sauver et transférer des images sur des surfaces.
Joystick
Gérer les joysticks.
Key
Gérer le clavier.
Mixer
Charger et jouer des sons.
Mouse
Gérer la souris et son affichage.
Movie
Lire des vidéos à partir de film en MPEG.
Music
Jouer des pistes musicales en streaming.
Overlay
Accéder à l'affichage vidéo avancé.
Pygame
Fonctions de haut niveau pour le contrôle de Pygame.
Rect
Conteneur flexible pour un rectangle.
Sndarray
Manipuler des échantillons de données audio.
Sprite
Objets de haut niveau pour la représentation des images de jeu.
Surface
Objets pour des images et l'écran.
Surfarray
Manipuler des images avec Numeric.
Time
Manipuler les temporisateurs et le taux de rafraîchissement.
Transform
Redimensionner et déplacer des images.
   

VII. Remerciements

Traduit de l'anglais, l'original par Pete Shinners : http://www.pygame.org/docs/tut/intro/intro.html

Cette traduction est aussi disponible sur Wikibooks. La liste des contributeurs est disponible ici.

Merci à zoom61 pour sa relecture orthographique.