« Pygame/Chimp - Ligne par ligne » : différence entre les versions

Contenu supprimé Contenu ajouté
Seb.bernery (discussion | contributions)
Aucun résumé des modifications
NewBorn (discussion | contributions)
Traduction complète
Ligne 1 :
{{Pygame Tutorials- Menu}}
Line By Line Chimp
by Pete Shinners
 
Traduit de l'anglais, original par ''Pete Shinners'' :<br/>
http://www.pygame.org/docs/tut/chimp/ChimpLineByLine.html
Introduction
Dans les exemples de la pygame, il y a un simple exemple nommé "chimp". Cet exemple simule un singe a taper qui bouge dans un petit écran avec des richesses et des récompenses. Cet exemple est vraiment simple, et a été simplifié dans le code de recherche d'erreurs. Ce programme de démonstration montre les grandes possibilités de la pygame, la possibilité de créer des fenêtres graphiques, de charger des sons et des images, de lire le texte au format TTF, et gérer les évenements basiques et les mouvements de la souris.
 
Ce programme ainsi que les images sont disponibles dans les sources de pygame. Pour la version 1.3 de pygame, cet exemple a été completement réécrit pour ajouter des fonctions et avoir un gestionnaire d'erreur correct. Ceci fait que la taille de l'exemple a doublé par rapport à l'original, mais nous donne plusieurs avantages non négligeables, et je peux vous le recommander pour vos propres projets.
Ce tutorial est découpé bloc par bloc, avec leurs explications. Il y aura également des mentions concernant la façon dont le code pourrait être amélioré et ce que le gestionnaire d'erreur peut nous en dire.
 
== Introduction ==
Ceci est un exellent tutorial pour les personnes désireuses de voir pour la première fois du code pygame. Si vos avez la pygame completement installée, vous pouver y trouver et executer la demo de chimp dans le repertoire d'exemple.
Importation des modules
Ceci est un code qui importe tout ce dont nous avons besoin comme modules dans notre programme. Il verifie la disponibilité des modules optionnels de pygame.
import os, sys
import pygame
from pygame.locals import *
 
Dans les exemples de Pygame, il y a un petit exemple nommé ''chimp''. Cet exemple simule un singe à frapper qui bouge dans un petit écran avec des promesses de récompenses. Cet exemple est en lui-même vraiment simple, et réduit la recherche d'erreurs dans le code. Cet exemple de programme démontre les possibilités de Pygame, comme la création de fenêtres graphiques, le chargement de fichiers d'images et de sons, de rendu de texte TTF (police TrueType), et la gestion des évènements de bases et des mouvements de la souris.
if not pygame.font: print 'Warning, fonts disabled'
if not pygame.mixer: print 'Warning, sound disabled'
 
Ce programme ainsi que les images sont disponibles dans les sources de Pygame. Pour la version 1.3 de Pygame, cet exemple a été complètement réécrit pour ajouter quelques fonctions et corriger quelques erreurs. Ceci fait que la taille de l'exemple a doublé par rapport à l'original, mais nous donne plus de matière à analyse, aussi bon que soit le code, je ne peux que vous recommander de le réutiliser pour vos propres projets.
 
Ce tutoriel analyse le code bloc par bloc, expliquant comment le code fonctionne. Il sera également mentionné la façon dont le code pourrait être amélioré et quel contrôle d'erreur peut nous venir en aide.
Premièrement, nous importons les modules python standars "os" et "sys". Ceux-ci nous permettent de faire des choses comme utiliser les systemes de fichier propres au systeme d'exploitation.
 
Ceci est un excellent tutoriel pour les personnes qui étudient pour la première fois du code Pygame. Une fois Pygame complètement installé, vous pourrez trouver et exécuter vous-même la démo de ''chimp'' dans le répertoire des exemple.
Dans la ligne suivante, nous importons le pack des modules de pygame. Quand pygame est importé, tous les modules sont importés. Sauf les modules optionnels et les modules non trouvés. Leur valeur est donc "False".
 
== Importer des modules ==
Il existe un module pygame spécial nommé "locals". Ce module contient des sous ensembles de pygame. Les membres de ce module sont généralement
 
Voici le code qui importe tous les modules nécessaires dans notre programme. Il vérifie la disponibilité de certains des modules optionnels de Pygame.
There is a special pygame module named "locals". This module contains a subset of pygame. The members of this module are commonly used constants and functions that have proven useful to put into your program's global namespace. This locals module includes functions like "Rect" to create a rectangle object, and many constants like "QUIT, HWSURFACE" that are used to interact with the rest of pygame. Importing the locals module into the global namespace like this is entirely optional. If you choose not to import it, all the members of locals are always available in the pygame module.
 
<source lang="python">
Lastly, we decide to print a nice warning message if the font or sound modules in pygame are not available.
import os, sys
import pygame
from pygame.locals import *
Loading Resources
 
Here we have two functions we can use to load images and sounds. We will look at each function individually in this section.
if not pygame.font: print 'Attention, polices désactivées'
if not pygame.mixer: print 'Attention, son désactivé'
</source>
 
D'abord, nous importons les modules standards de Python <tt>os</tt> et <tt>sys</tt>. Ceux-ci nous permettent de faire certaines choses comme créer des chemins de fichiers indépendants du système d'exploitation.
 
Dans la ligne suivante, nous importons l'ensemble des modules de Pygame. Quand Pygame est importé, tous les modules appartenant à Pygame sont importés. Certains modules sont optionnels, s'ils ne sont pas trouvés, leur valeur est définie à <tt>None</tt>.
 
Il existe un module Pygame spécial nommé <tt>locals</tt>. Ce module contient un sous-ensembles de Pygame. Les membres de ce module utilisent couramment des constantes et des fonctions qui ont prouvés leur utilité à être incorporé dans l'espace de nom global de votre programme. Ce module de locales inclut des fonctions comme <tt>Rect()</tt> pour un objet rectangle, et plusieurs constantes comme <tt>QUIT, HWSURFACE</tt> qui sont utilisées pour interagir avec le reste de Pygame. L'importation de ce module de locales dans l'espace de nom global est complètement optionnel. Si vous choisissez de ne pas l'importer, tous les membres des locales sont toujours disponibles dans le module <tt>pygame</tt>.
 
Enfin, nous avons décidé d'imprimer un joli message si les modules <tt>font</tt> ou <tt>sound</tt> ne sont pas disponibles dans Pygame.
 
== Chargement des Ressources ==
 
Ici nous avons deux fonctions que nous pouvons utiliser pour charger des images et des sons. Nous examinerons chaque fonction individuellement dans cette section.
 
<source lang="python">
def load_image(name, colorkey=None):
fullname = os.path.join('data', name)
Ligne 44 ⟶ 46 :
image = pygame.image.load(fullname)
except pygame.error, message:
print 'Cannot"Impossible loadde charger l'image :'", name
raise SystemExit, message
image = image.convert()
Ligne 52 ⟶ 54 :
image.set_colorkey(colorkey, RLEACCEL)
return image, image.get_rect()
</source>
 
Cette fonction prend le nom de l'image à charger. Elle prend également un argument optionnel qui peut être utilisé pour définir une couleur clé à l'image. Une couleur clé est utilisée dans les graphismes pour représenter une couleur de l'image qui devra être transparente.
 
La première chose que cette fonction fait, est de créer un chemin de fichier complet vers le fichier. Dans cet exemple, toutes les ressources sont situées dans le sous-répertoire <tt>data</tt>. En utilisant la fonction <tt>os.path.join()</tt>, un chemin sera créé qui fonctionnera quelque soit la plateforme sur laquelle est lancé le jeu.
 
Ensuite, nous chargeons l'image en utilisant la fonction <tt>pygame.image.load()</tt>. Nous enveloppons cette fonction dans un bloc de <tt>try/except</tt>, ainsi s'il y a un problème lors du chargement de l'image, nous pouvons quitter élégamment. Après que l'image soit chargée, nous faisons un appel important à la fonction <tt>convert()</tt>. Ceci crée une nouvelle copie de la Surface et la convertit dans un format et une profondeur de couleurs qui correspondent à l'affichage en cours. Ceci signifie que le blitage de l'image sur l'écran sera aussi rapide que possible.
 
Enfin, nous définissons la couleur clé de l'image. Si l'utilisateur fournit un argument pour la couleur clé, nous utiliserons cette valeur de couleur clé pour l'image. Ceci devrait être habituellement une valeur RGB, comme (255, 255, 255) pour le blanc. Vous pouvez également passer la valeur <tt>-1</tt> comme couleur clé. Dans ce cas, la fonction examinera la couleur en haut à gauche de l'image, et utilisera cette couleur comme couleur clé.
 
<source lang="python">
This function takes the name of an image to load. It also optionally takes an argument it can use to set a colorkey for the image. A colorkey is used in graphics to represent a color of the image that is transparent.
The first thing this function does is create a full pathname to the file. In this example all the resources are in a "data" subdirectory. By using the os.path.join function, a pathname will be created that works for whatever platform the game is running on.
Next we load the image using the pygame.image.load function. We wrap this function in a try/except block, so if there is a problem loading the image, we can exit gracefully. After the image is loaded, we make an important call to the convert() function. This makes a new copy of a Surface and converts its color format and depth to match the display. This means blitting the image to the screen will happen as quickly as possible.
Last, we set the colorkey for the image. If the user supplied an argument for the colorkey argument we use that value as the colorkey for the image. This would usually just be a color RGB value, like (255, 255, 255) for white. You can also pass a value of -1 as the colorkey. In this case the function will lookup the color at the topleft pixel of the image, and use that color for the colorkey.
def load_sound(name):
class NoneSound:
Ligne 72 ⟶ 74 :
sound = pygame.mixer.Sound(fullname)
except pygame.error, message:
print 'CannotImpossibel loadde charger le son sound:', wav
raise SystemExit, message
return sound
</source>
 
Vient ensuite la fonction de chargement de fichier son. La première chose que cette fonction fait est de contrôler si le module <tt>pygame.mixer</tt> a été importé correctement. Si non, elle retourne une petite instance de classe qui possède une méthode de lecture factice. Ceci agira comme un objet Son normal pour ce jeu qui tournera sans contrôle d'erreur supplémentaire.
Next is the function to load a sound file. The first thing this function does is check to see if the pygame.mixer module was imported correctly. If not, it returns a small class instance that has a dummy play method. This will act enough like a normal Sound object for this game to run without any extra error checking.
 
Cette fonction est similaire à la fonction de chargement d'image, mais gère des problèmes différents. En premier lieu nous créons un chemin complet vers le fichier son, et chargeons ce fichier son à travers un bloc <tt>try/except</tt>, qui nous retourne alors l'objet Son chargé.
This function is similar to the image loading function, but handles some different problems. First we create a full path to the sound image, and load the sound file inside a try/except block. Then we simply return the loaded Sound object.
 
== Classes d'objet du Jeu ==
 
Game Object Classes
HereIci wenous createcréons twodeux classes toqui representreprésentent theles objectsobjets indans ournotre gamejeu. AlmostLa allplupart thede logicla forlogique thede gamejeu goesvient intode theseces twodeux classes. WeNous willles lookexaminerons overdans themcette one at a time heresection.
 
<source lang="python">
class Fist(pygame.sprite.Sprite):
"""movesDéplacer aun clenchedpoing fistfermé onsur thel'écran screen,qui followingsuit thela mousesouris"""
def __init__(self):
pygame.sprite.Sprite.__init__(self) #callAppel Spritedu initializerconstructeur de Sprite
self.image, self.rect = load_image('fist.bmp', -1)
self.punching = 0
 
def update(self):
"moveDéplace thele fistpoing basedsur onla theposition mousede positionla souris"
pos = pygame.mouse.get_pos()
self.rect.midtop = pos
Ligne 100 ⟶ 103 :
 
def punch(self, target):
"returnsRenvoi true ifsi thele fistpoing collidesentre withen thecollision targetavec la cible"
if not self.punching:
self.punching = 1
Ligne 107 ⟶ 110 :
 
def unpunch(self):
"calledAppelé topour pullfaire therevenir fistle backpoing"
self.punching = 0
</source>
 
Ici nous créons Hereune weclasse createpour areprésenter classle topoing representdu the players fistjoueur. ItElles isest deriveddérivée fromde thela classe Sprite classinclue includeddans inle themodule <tt>pygame.sprite module</tt>. TheLa méthode <tt>__init__()</tt> functionest isappelée calledlorsqu'une whennouvelle newinstance instancesde ofcette thisclasse classest are createdcréée. TheLa firstpremière thingchose weque donous isfaisons beest surede tos'assurer calld'appeler thela méthode <tt>__init__()</tt> functionde fornotre ourclasse de base class. ThisCeci allowsautorise thela Sprite'sméthode <tt>__init__()</tt> functionde toSprite prepareà ourpréparer objectnotre forobjet usepour l'utiliser ascomme aun sprite. ThisCe gamejeu usesutilise oneun ofdes thegroupes spritede drawingclasses Groupde classesdessin de sprite. TheseCes classes canpeuvent drawdessiner des sprites thatqui havepossèdent anun "attribut <tt>image"</tt> andet "<tt>rect" attribute</tt>. ByEn simplychangeant changingtout thesesimplement twoces attributesdeux attributs, thele renderermoteur willde drawrendu thedessinera currentles imageimages atactuelles theà currentleur position actuelle.
 
AllTous les sprites havepossède anune méthode <tt>update() method</tt>. ThisCette functionméthode isest typicallygénéralement calledappelée onceune perfois framepar image. ItC'est isle wherelieu you shouldvous putpouvez mettre le code thatqui movesdéplace andet updatesactualise theles variables forde thechaque sprite. TheLa méthode <tt>update()</tt> methodpour forle thepoing fistdéplace movesce thepoing fistvers tol'endroit the locationpointe ofla the mouse pointersouris. It alsoElle offsetscompense thelégèrement fistla position slightlydu ifpoing thesi fistcelui isest inen theétat "punching"de state''frappe''.
 
TheLes followingdeux twofonctions functionssuivantes <tt>punch()</tt> andet <tt>unpunch()</tt> changemodifie thel'état punchingdu statepoing. forLa the fist. Theméthode <tt>punch()</tt> methodretourne alsola returns avaleur <tt>true</tt> valuesi ifle thepoing fistentre isen collidingcollision withavec thele givensprite target spritecible.
 
<source lang="python">
class Chimp(pygame.sprite.Sprite):
"""movesDéplace aun monkeysinge critterà acrosstravers the screenl'écran. itElle canpeut spinfaire thetournoyer
le singe quand monkeyil whenest it is punchedfrappé."""
def __init__(self):
pygame.sprite.Sprite.__init__(self) #callAppel Spritedu intializerconstructeur de Sprite
self.image, self.rect = load_image('chimp.bmp', -1)
screen = pygame.display.get_surface()
Ligne 130 ⟶ 134 :
 
def update(self):
"walkDéplace orou spin,fait dependingtournoyer, onsuivant thel'état monkeysdu statesinge"
if self.dizzy:
self._spin()
Ligne 137 ⟶ 141 :
 
def _walk(self):
"moveDéplacer thele monkeysinge acrossà thetravers screenl'écran, andet turnle atfaire thepivoter endsà la fin"
newpos = self.rect.move((self.move, 0))
if not self.area.contains(newpos):
Ligne 148 ⟶ 152 :
 
def _spin(self):
"spinFaire the monkeytournoyer l'image du singe"
center = self.rect.center
self.dizzy += 12
Ligne 160 ⟶ 164 :
 
def punched(self):
"thisEntraine willle causetournoiement thedu monkey to start spinningsinge"
if not self.dizzy:
self.dizzy = 1
self.original = self.image
</source>
 
La classe Chimp fait un peu plus de travail que celle du poing, mais rien de complexe. Cette classe déplacera le chimpanzé de gauche à droite sur l'écran. Quand le singe sera frappé, il tournoiera sur lui-même dans un superbe effet. Cette classe est dérivée de la classe de base Sprite, et est initialisée de la même façon que celle du poing. Pendant l'initialisation, la classe définit l'attribut <tt>area</tt> comme dimension de l'affichage.
The chimp class is doing a little more work than the fist, but nothing more complex. This class will move the chimp back and forth across the screen. When the monkey is punched, he will spin around to exciting effect. This class is also derived from the base Sprite class, and is initialized the same as the fist. While initializing, the class also sets the attribute "area" to be the size of the display screen.
 
TheLa fonction <tt>update()</tt> functiondu forsinge thevérifie chimpsimplement simply looks at the current "dizzy"l'état stateactuel, whichlequel isest <tt>true</tt> whenquand thele monkeysinge istournoie spinningaprès fromun acoup punchde poing. ItElle callsappelle eitherla theméthode <tt>_spin</tt> orou <tt>_walk method</tt>. TheseCes functionsfonctions aresont prefixedpréfixées with and'un underscore. ThisC'est isun justidiome aPython standardqui pythonsuggère idiomque whichces suggestsméthodes thesedevraient methodsuniquement shouldêtre onlyutilisées beà usedl'intérieur byde thela Chimpclasse class<tt>Chimp</tt>. WeNous couldpourrions goaller soplus farloin asen toleur giveattribuant them aun double underscore, whichqui wouldindiquera tellà pythonPython tode reallyréellement tryessayer tod'en makefaire themdes privateméthodes methodsprivées, butmais wenous donn'tavons pas besoin de ce needtype suchde protection. :)
 
TheLa walkméthode method<tt>_walk</tt> createscrée aune newnouvelle position forpour thele monkey bysinge, movingen thedéplaçant currentle <tt>rect</tt> byactuel ad'un givendéplacement offsetélémentaire. IfSi thiscette newnouvelle position crossesse outsidesitue theà displayl'extérieur areade ofla thezone screend'affichage de l'écran, itelle reversesinverse thele movementdéplacement offsetélémentaire. ItElle alsoinverse mirrorségalement thele sens de l'image usingen theutilisant la fonction <tt>pygame.transform.flip function()</tt>. ThisC'est isun aeffet cruderudimentaire effectqui thatpermet makesau thesinge monkeyd'inverser lookle likesens he'sde turningson the directionimage hesuivant isson movingdéplacement.
 
La méthode <tt>_spin()</tt> est appelée quand le singe est ''étourdi'' (<tt>dizzy</tt>). L'attribut <tt>dizzy</tt> est utilisé pour enregistrer le nombre de rotation actuel. Quand le singe a entièrement tournoyé sur lui-même (360 degrés), il réinitialise l'image du singe à sa version droite originale. Avant d'appeler la fonction <tt>transform.rotate()</tt>, vous verrez que le code crée une référence locale à la fonction nommée <tt>rotate()</tt>. Il n'y a pas lieu de la faire pour cet exemple, nous l'avons uniquement fait ici pour conserver une longueur raisonnable à la ligne suivante. A noter qu'en appelant la fonction <tt>rotate()</tt>, nous faisons toujours tounoyer l'image originale du singe. Pendant la rotation, il y a une légère perte de qualité. Effectuer une rotation de façon répétitive sur la même image entraîne au fur et à mesure une dégradation de l'image. Quand une image tourne sur elle-même, la dimension de cette image sera modifiée. Ceci est dû au fait que les coins de l'image sortent de la dimension originale pendant la rotation, et augmente alors les dimensions de l'image. Nous nous assurons que le centre de la nouvelle image correspond au centre de l'ancienne image, de cette façon elle tournoie sans se déplacer.
The spin method is called when the monkey is currently "dizzy". The dizzy attribute is used to store the current amount of rotation. When the monkey has rotated all the way around (360 degrees) it resets the monkey image back to the original unrotated version. Before calling the transform.rotate function, you'll see the code makes a local reference to the function simply named "rotate". There is no need to do that for this example, it is just done here to keep the following line's length a little shorter. Note that when calling the rotate function, we are always rotating from the original monkey image. When rotating, there is a slight loss of quality. Repeatedly rotating the same image and the quality would get worse each time. Also, when rotating an image, the size of the image will actually change. This is because the corners of the image will be rotated out, making the image bigger. We make sure the center of the new image matches the center of the old image, so it rotates without moving.
 
TheLa lastdernière method isméthode <tt>punched()</tt> whichindique tellsque thele sprite toentre enterdans itsson état ''étourdi'' (<tt>dizzy state</tt>). ThisCeci willentrainera causele thetournoiement de l'image to start spinning. ItElle alsofera makeségaelement aune copycopie ofde the current imageactuelle namedappelée "<tt>original"</tt>.
 
== Tout initialiser ==
Initialize Everything
 
Before we can do much with pygame, we need to make sure its modules are initialized. In this case we will also open a simple graphics window. Now we are in the main() function of the program, which actually runs everything.
Avant d'aller plus loin avec Pygame, nous devons nous assurer que tous ces modules sont initialisés. Dans ce cas nous ouvrirons une simple fenêtre graphique. Maintenant nous sommes dans la fonction principale du programme, laquelle exécute tout.
 
<source lang="python">
pygame.init()
screen = pygame.display.set_mode((468, 60))
pygame.display.set_caption('Monkey Fever')
pygame.mouse.set_visible(0)
</source>
 
La première ligne d'initialisation de Pygame nous épargne un peu de travail. Elle contrôle les modules Pygame importés et tente d'initialiser chacun d'entre eux. Il est possible de vérifier si des modules n'ont pas échoué pendant l'initialisation, mais nous ne nous tracasserons pas avec ça. Il est ainsi possible d'effectuer un contrôle plus fin et d'initialiser chaque module spécifique à la main. Ce type de contrôle n'est généralement pas indispensable, mais il est disponible si besoin.
The first line to initialize pygame takes care of a bit of work for us. It checks through the imported pygame modules and attempts to initialize each one of them. It is possible to go back and check if modules failed to initialize, but we won't bother here. It is also possible to take a lot more control and initialize each specific module by hand. That type of control is generally not needed, but is available if you desire.
 
Ensuite, nous définissons le mode d'affichage. A noter que le module <tt>pygame.display</tt> est utilisé pour contrôler tous les paramètres d'affichage. Dans cet exemple, nous demandons une simple fenêtre. Il existe un tutoriel complet sur le paramétrage du mode graphique, mais nous n'en avons pas réellement besoin, Pygame effectue déjà un bon travail pour nous en obtenant quelque chose qui fonctionne. Pygame trouve la meilleure profondeur de couleur sans que nous lui en fournissons une.
Next we set up the display graphics mode. Note that the pygame.display module is used to control all the display settings. In this case we are asking for a simple skinny window. There is an entire separate tutorial on setting up the graphics mode, but if we really don't care, pygame will do a good job of getting us something that works. Pygame will pick the best color depth, since we haven't provided one.
 
Enfin nous définissons le titre de la fenêtre et désactivons le curseur de la souris de notre fenêtre. Très simple à faire, et maintenant nous avons une petite fenêre noire prête à recevoir nos requêtes. En fait le curseur est par défaut visible, ainsi il n'y a pas réellement besoin de définir son état tant que nous ne voulons pas le cacher.
Last we set the window title and turn off the mouse cursor for our window. Very basic to do, and now we have a small black window ready to do our bidding. Usually the cursor defaults to visible, so there is no need to really set the state unless we want to hide it.
 
== Créer l'arrière-plan ==
 
Notre programme affichera un message textuel en arrière-plan. Il serait bon pour nous de créer une simple surface pour représenter l'arrière-plan et l'utiliser à chaque fois. La première étape sera de créer cette surface.
Create The Background
 
Our program is going to have text message in the background. It would be nice for us to create a single surface to represent the background and repeatedly use that. The first step is to create the surface.
<source lang="python">
background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((250, 250, 250))
</source>
 
Ceci crée pour nous une nouvelle surface qui est de la même taille que la fenêtre d'affichage. A noter l'appel supplémentaire <tt>convert()</tt> après la création de la surface. La méthode <tt>convert()</tt> sans argument s'assure que notre arrière-plan est du même format que la fenêtre d'affichage, ce qui nous donnera des résultats plus rapide.
 
Nous remplissons alors entièrement l'arrière-plan avec une couleur blanchâtre. La méthode <tt>fill()</tt> prend un triplet RGB en argument de couleur.
 
== Appliquer le texte sur l'arrière-plan et le centrer ==
 
Maintenant que nous avons une surface d'arrière-plan, apppliquons-lui un rendu de texte. Nous le ferons uniquement si nous voyons que le module <tt>pygame.font</tt> a été importé correctement. Si non, nous passons cette section.
 
<source lang="python">
This creates a new surface for us that is the same size as the display window. Note the extra call to convert() after creating the Surface. The convert with no arguments will make sure our background is the same format as the display window, which will give us the fastest results.
We also fill the entire background with a solid white-ish color. Fill takes an RGB triplet as the color argument.
Put Text On The Background, Centered
Now that we have a background surface, lets get the text rendered to it. We only do this if we see the pygame.font module has imported properly. If not, we just skip this section.
if pygame.font:
font = pygame.font.Font(None, 36)
Ligne 215 ⟶ 221 :
textpos = text.get_rect(centerx=background.get_width()/2)
background.blit(text, textpos)
</source>
 
Comme vous le As you seevoyez, thereil arey a coupleune stepspaire tod'étapes gettingpour thisson doneobtention. FirstD'abord wenous mustcréons createun theobjet <tt>font</tt>, objectet anden renderfaisons itun intorendu asur la newnouvelle surface. WeNous thentrouvons findalors thele centercentre ofde thatcette newnouvelle surface and blit (paste)et itla onto''blitons'' thesur backgroundl'arrière-plan.
 
La police est créée avec le constructeur <tt>Font()</tt> du module <tt>font</tt>. En fait, nous passons le nom du fichier de police truetype à cette fonction, mais nous pouvons aussi passer <tt>None</tt> et utiliser la police par défaut. Le constructeur <tt>Font()</tt> nécessite de connaître la taille de la police que nous désirons créer.
The font is created with the font module's Font() constructor. Usually you will pass the name of a truetype font file to this function, but we can also pass None, which will use a default font. The Font constructor also needs to know the size of font we want to create.
 
Nous faisons alors un rendu de cette police dans la nouvelle surface. La fonction <tt>render()</tt> crée une nouvelle surface d'une taille appropriée à notre texte. Dans cet exemple, nous dirons aussi à la fonction <tt>render()</tt> de créer un texte anti-aliasé (pour obtenir un effet lissé) et d'utiliser une couleur gris sombre.
We then render that font into a new surface. The render function creates a new surface that is the appropriate size for our text. In this case we are also telling render to create antialiased text (for a nice smooth look) and to use a dark grey color.
 
Ensuite nous avons besoin de trouver le centre du texte sur l'affichage. Nous créons un objet <tt>Rect</tt> qui nous permet de l'assigner facilement au centre de l'écran.
Next we need to find the centered position of the text on our display. We create a "Rect" object from the text dimensions, which allows us to easily assign it to the screen center.
 
Enfin, nous ''blitons'' le texte sur l'image d'arrière-plan.
Finally we blit (blit is like a copy or paste) the text onto the background image.
 
== Afficher l'arrière-plan une fois les paramètres définis ==
 
Nous avons encore une fenêtre noire sur l'écran. Affichons notre arrière-plan pendant que nous attendons de charger les autres ressources.
Display The Background While Setup Finishes
 
We still have a black window on the screen. Lets show our background while we wait for the other resources to load.
<source lang="python">
screen.blit(background, (0, 0))
pygame.display.flip()
</source>
 
Ceci ''blitera'' notre arrière-plan complet sur la fenêtre d'affichage. Le ''blit'' est lui-même trivial, mais qu'en est-il de la routine <tt>flip()</tt> ?
This will blit our entire background onto the display window. The blit is self explanatory, but what about this flip routine?
 
Dans Pygame, les changements de la surface d'affichage ne sont pas immédiatement visible. Normalement, un affichage doit être mis à jour dans les zones qui ont changé pour les rendre visibles à l'utilisateur. Avec l'affichage par double-tampon (double buffer), l'affichage doit être interverti pour rendre les changements visibles. Dans cet exemple, la fonction <tt>flip()</tt> fonctionne parfaitement parce qu'elle manipule la zone entière de la fenêtre et gère les surfaces en simple et double tampon.
In pygame, changes to the display surface are not immediately visible. Normally, a display must be updated in areas that have changed for them to be visible to the user. With double buffered displays the display must be swapped (or flipped) for the changes to become visible. In this case the flip() function works nicely because it simply handles the entire window area and handles both singlebuffered and doublebufferes surfaces.
 
== Préparer les objets du jeu ==
 
Ici nous créons tous les objets dont le jeu aura besoin.
Prepare Game Object
 
Here we create all the objects that the game is going to need.
<source lang="python">
whiff_sound = load_sound('whiff.wav')
punch_sound = load_sound('punch.wav')
Ligne 251 ⟶ 257 :
allsprites = pygame.sprite.RenderPlain((fist, chimp))
clock = pygame.time.Clock()
</source>
 
D'abord nous chargeons Firstdeux weeffets loadsonores twoen soundutilisant effectsla using thefonction <tt>load_sound()</tt>. functionEnsuite wenous definedcréons above.une Theninstance wepour createchacune ande instancenos ofclasses each of ourde sprite classes. AndEt lastlyenfin, wenous createcréons aun spritegroupe Groupde whichsprites willqui containcontiendra alltous ournos sprites.
 
WeNous actuallyutilisons useen afait specialun spritegroupe groupspécial de sprites namednommé <tt>RenderPlain</tt>. ThisCe sprite grouppeut candessiner drawtous all theles sprites it containsqu'il tocontient theà screenl'écran. ItIl isest calledappelé <tt>RenderPlain</tt> becauseparce therequ'il arey actuallya moreen advancedfait Renderplusieurs groupsgroupes de rendu avancés. ButMais forpour ournotre gamejeu, wenous justavons needsimplement simplebesoin drawingde les dessiner. WeNous createcréons thele groupgroupe namednommé "<tt>allsprites"</tt> byen passingpassant aune listliste withavec alltous theles sprites thatqui shouldappartiennent belongau ingroupe. the group.Nous Wepourrons couldplus latertard onajouter addou orsupprimer removedes sprites fromde thisce groupgroupe, butmais indans thisce gamejeu, wenous wonn'ten aurons needpas tobesoin.
 
L'objet <tt>clock</tt> que nous créons, sera utilisé pour contrôler le taux d'images par seconde de notre jeu. Nous l'utiliserons dans la boucle principale de notre jeu pour s'assurer qu'il ne fonctionne pas trop vite.
The clock object we create will be used to help control our game's framerate. we will use it in the main loop of our game to make sure it doesn't run too fast.
 
== La boucle principale ==
 
Main Loop
Rien de spécial ici, simplement une boucle infinie.
Nothing much here, just an infinite loop.
 
<source lang="python">
while 1:
clock.tick(60)
</source>
 
Tous les jeux exécute ce type de boucle. L'ordre des choses est de vérifier l'état de l'ordinateur et des entrées utilisateur, déplacer et actualiser l'état de tous les objets, et ensuite de les dessiner sur l'écran. Vous verrez que cet exemple n'est pas différent.
 
Nous faisons ainsi appel à notre objet <tt>clock</tt> qui s'assurera que notre jeu ne dépasse pas les 60 images par seconde.
 
== Gérer tous les évènements d'entrée ==
 
C'est un exemple extrêmement simple sur le fonctionnement de la pile d'évènement.
 
<source lang="python">
All games run in some sort of loop. The usual order of things is to check on the state of the computer and user input, move and update the state of all the objects, and then draw them to the screen. You'll see that this example is no different.
We also make a call to our clock object, which will make sure our game doesn't run faster than 60 frames per second.
Handle All Input Events
This is an extremely simple case of working the event queue.
for event in pygame.event.get():
if event.type == QUIT:
Ligne 283 ⟶ 290 :
elif event.type == MOUSEBUTTONDOWN:
if fist.punch(chimp):
punch_sound.play() #punchfrappé
chimp.punched()
else:
whiff_sound.play() #missraté
elif event.type == MOUSEBUTTONUP:
fist.unpunch()
</source>
 
D'abord, nous prenons tous les évènements disponibles de Pygame et faisons une boucle pour chacun d'eux. Les deux premiers testent si l'utilisateur a quitté notre jeu ou a appuyé sur la touche <tt>Echap</tt>. Dans ces cas, nous retournons simplement dans la fonction principale et le programme se termine proprement.
First we get all the available Events from pygame and loop through each of them. The first two tests see if the user has quit our game, or pressed the escape key. In these cases we just return from the main() function and the program cleanly ends.
Next we just check to see if the mouse button was pressed or released. If the button was pressed, we ask the fist object if it has collided with the chimp. We play the appropriate sound effect, and if the monkey was hit, we tell him to start spinning (by calling his punched() method).
Update the Sprites
 
Ensuite, nous vérifions si le bouton de la souris a été enfoncé ou relaché. Si le bouton est enfoncé, nous demandons à l'objet poing si il est entré en collision avec le chimpanzé. Nous jouons l'effet sonore approprié, et si le singe est frappé, nous lui demandons de tournoyer (en appelant sa méthode <tt>punched()</tt>.
 
== Actualiser les Sprites ==
 
<source lang="python">
allsprites.update()
</source>
 
Les groupes de sprites possèdent une méthode <tt>update()</tt>, qui appelle la méthode <tt>update()</tt> de tous les sprites qu'ils contiennent. Chacun des objets se déplacera, en fonction de l'état dans lequel ils sont. C'est ici que le chimpanzé se déplacera d'un pas d'un côté à l'autre, ou tournoiera un peu plus loin s'il a récemment été frappé.
Sprite groups have an update() method, which simply calls the update method for all the sprites it contains. Each of the objects will move around, depending on which state they are in. This is where the chimp will move one step side to side, or spin a little farther if he was recently punched.
 
== Dessiner la scène entière ==
 
Maintenant que tous les objets sont à la bonne place, il est temps de les dessiner.
 
Draw The Entire Scene
<source lang="python">
Now that all the objects are in the right place, time to draw them.
screen.blit(background, (0, 0))
allsprites.draw(screen)
pygame.display.flip()
</source>
 
Le premier appel à <tt>blit()</tt> dessinera l'arrière-plan sur la totalité de la fenêtre. Ceci effacera tout ce que nous avons vu de la scène précédente (peu efficace, mais suffisant pour ce jeu). Ensuite nous appelons la méthode <tt>draw()</tt> du conteneur de sprites. Depuis que ce conteneur de sprites est réellement une instance de groupe de sprite ''DrawPlain'', il sait comment dessiner nos sprites. Enfin grâce à la méthode <tt>flip()</tt>, nous affichons le contenu du tampon de Pygame à l'écran. Tout ce que nous avons dessiné apparaît en une seule fois.
 
== Game Over ==
 
L'utilisateur a quitté, c'est l'heure du nettoyage.
 
Le nettoyage d'un jeu dans Pygame est extrêmement simple. En fait depuis que toutes les variables sont automatiquement détruites, nous n'avons pas réellement besoin de faire quoi que ce soit.
The first blit call will draw the background onto the entire screen. This erases everything we saw from the previous frame (slightly inefficient, but good enough for this game). Next we call the draw() method of the sprite container. Since this sprite container is really an instance of the "DrawPlain" sprite group, it knows how to draw our sprites. Lastly, we flip() the contents of pygame's software double buffer to the screen. This makes everything we've drawn visible all at once.
Game Over
User has quit, time to clean up
Cleaning up the running game in pygame is extremely simple. In fact since all variables are automatically destructed, we really don't have to do anything.