« Pygame/Introduction au module Sprite » : différence entre les versions

Contenu supprimé Contenu ajouté
Argon.7600 (discussion | contributions)
NewBorn (discussion | contributions)
Traduction complète
Ligne 1 :
{{Pygame - Menu}}
La version 1.3 de Pygame inclus un nouveau module, pygame.sprite. Ce module est écrit en python et inclus quelques classes de haut niveau d'abstraction
pour gérer les objets de votre jeu. En utilisant ce module avec toute l'ampleur de ses possibilités, vous pouvez facilement gérer et dessiner les
objets dans votre jeu. Les classes du module sprite sont très optimisées, donc il est probable que votre jeu fonctionne plus rapidement avec ce module que sans.
 
Traduit de l'anglais, l'original par ''Pete Shinners'' :<br/>
Le module sprite a aussi une utilisation très générique. Il est possible de l'utiliser pour pratiquement n'importe quel type de gameplay. Cette grande flexibilité a toutefois un léger défaut, elle nécessite un peu de réflexion/compréhsension pour pouvoir l'utiliser correctement. La documentation de référence pour le module sprite peut vous aider à faire ce que vous voulez, mais vous aurez probablement besoin d'un peu d'explications supplémentaires pour utiliser pygame.sprite dans votre jeu.
http://www.pygame.org/docs/tut/SpriteIntro.html
 
__TOC__
Plusieurs des examples d'utilisation de pygame (comme "chimp" et "aliens") ont été mis à jour pour utiliser le module sprite. Vous voudrez certainement examiner ceux là pour observer ce qu'est approximativement le module sprite. Le module chimp a de toutes façon son propre tutorial au ligne par ligne, lequel peut vous aider en plus à comprendre la programmation avec python et pygame.
 
La version 1.3 de Pygame inclut un nouveau module, <tt>pygame.sprite</tt>. Ce module est écrit en python et inclut quelques classes à haut niveau d'abstraction pour gérer vos objets de jeu. En utilisant ce module à son plein potentiel, vous pouvez facilement gérer et dessiner vos objets de jeu. Les classes du module sprite sont très optimisées, il est donc probable que votre jeu fonctionne plus rapidement avec ce module que sans.
Tenez compte du fait que cette introduction suppose que vous avez un peu d'expérience en programmation avec python, et que vous êtes d'une quelconque
façon familier avec les différentes parties de création d'un jeu simple. Dons ce tutorial, le mot "référence" est occasionellement utilisé. Il représente une variable python. Les variables avec python sont des références, donc vous pouvez avoir plusieurs variables qui pointent vers le même objet.
 
Le module sprite est censé être très générique. Il est possible de l'utiliser pour pratiquement n'importe quel type de gameplay. Cette grande flexibilité a toutefois un léger défaut, elle nécessite un peu de réflexion/compréhension pour pouvoir l'utiliser correctement. La [http://www.pygame.org/docs/ref/pygame_sprite.html documentation de référence] du module Sprite peut vous venir en aide, mais vous aurez probablement besoin d'un peu d'explications supplémentaires pour utiliser <tt>pygame.sprite</tt> dans votre jeu.
=Une leçon d'histoire=
 
Plusieurs des exemples d'utilisation de Pygame (comme ''chimp'' et ''aliens'') ont été mis à jour pour utiliser le module sprite. Vous voudrez certainement examiner ceux là d'abord pour observer ce qu'est approximativement le module sprite. Le module chimp possède de toutes façon son propre [[pygame - chimp ligne par ligne|tutoriel]] en ligne par ligne, qui pourra en plus vous aider à comprendre la programmation avec Python et Pygame.
Le terme "sprite" est une survivance des vieux ordinateurs et consoles de jeu. Ces vieilles choses étaient incapable de dessiner et d'effacer des graphiques assez rapidement pour que ça fasse fonctionner des jeux. Ces machines avaient un hardware spécial pour contenir les objets du jeu qui avaient besoin d'être animés très rapidement. Ces objets étaient appelés 'sprites' et avaient des limitations qui leur étaient propres, mais pouvaient être dessinés et mis à jour très rapidement. Ils étaient habituellement contenus dans des buffers spéciaux du circuit vidéo (traduction approximative). De nos jours, les ordinateurs sont généralement assez rapides pour contenir les sprites comme des objets standards sans nécessiter de hardware dédié. Le terme sprite est encore actuellement utilisé pour parler des objets animés dans les jeux en deux dimensions.
 
Tenez compte du fait que cette introduction suppose que vous ayez un peu d'expérience en programmation Python, et que vous êtes, d'une quelconque façon, familier avec les différentes étapes de création d'un simple jeu. Dans ce tutoriel, le mot ''référence'' est occasionnellement utilisé. Il représente une variable Python. Les variables avec Python sont des références, vous pouvez donc avoir plusieurs variables qui pointent vers le même objet.
=Les classes=
 
== Leçon d'histoire ==
Le module sprite utilise deux classes principales. La première est Sprite, qui est censé être utilisée comme classe de base pour tous les objets du jeu. Cette classe ne fait pas vraiment grand chose à elle seule, elle inclut seulement plusieurs fonctions pour aider à la gestion des objets du jeu. L'autre classe est Group. La classe Group constitue un conteneur pour différents objets sprite. Il y a actuellement différentes classes pour différents types de groupe. Certaines de Group peuvent dessiner tous les éléments qu'elles contiennent, par exemple.(traduction incertaine)
 
Le terme ''sprite'' est une survivance des vieux ordinateurs et consoles de jeu. Ces vieilles boîtes étaient incapables de dessiner et d'effacer des graphismes suffisamment rapidement pour faire fonctionner des jeux. Ces machines possédaient un matériel spécial pour manipuler les objets du jeu qui avaient besoin d'être animés très rapidement. Ces objets étaient appelés ''sprites'' et avaient des limitations qui leur étaient propres, mais pouvaient être dessinés et mis à jour très rapidement. Ils étaient habituellement contenus dans des tampons spéciaux du circuit vidéo. De nos jours, les ordinateurs sont généralement assez rapides pour manipuler les sprites comme des objets standards sans nécessiter de matériel dédié. Le terme sprite est toujours utilisé pour parler des objets animés dans les jeux en deux dimensions.
C'est vraiment tout ce qu'il y a. Nous commencerons avec une description de ce que fait chaque type des classes, et nous parlerons alors de la manière de les utiliser entre elles.
 
== Les classes ==
=La classe Sprite=
 
CommeLe mentionnémodule auparavant,sprite lautilise classedeux spriteclasses principales. La première est conçue''Sprite'', pourqui est censée être uneutilisée comme classe de base pour tous les objets de votredu jeu. VousCette classe ne pouvezfait pas vraimentgrand l'utiliserchose en tant que telleelle-même, car elle est faiteinclut seulement de plusieurs méthodesfonctions pour aider à travaillerla avec les différentes classes de Group. Le sprite garde une tracegestion des groupesobjets auxquelsdu il a appartenujeu. Le constructeur deL'autre classe (la méthode __init__) prend un argument de typeest ''Group''. (ouLa une listeclasse d'arguments de type 'Group)'' queconstitue l'instanceun deconteneur Spritepour devraitdifférents contenirobjets sprite. VousIl pouvezy égalementa changeractuellement les membres d'undifférents objettypes de typeclasses ''Group avec les méthodes add() et remove()''. IlCertains ytypes ade égalementclasse une méthode''Group'' groups()peuvent, quipar retourneexemple, unedessiner listetous desles groupeséléments contenant lequ'elles spritecontiennent.
 
C'est vraiment tout ce qu'il y a. Nous commencerons avec une description de ce que fait chaque type des classes, et nous discuterons sur la manière de les utiliser correctement.
Lorsque vous utilisez les classes Sprite, il est mieux de penser à eux comme "valide" ou "vivant" lorsqu'ils sont contenus dans un ou plusieurs groupes. Lorsque vous supprimez l'instance de tous les groupes, pygame va nettoyer l'objet. (Sauf si vous possédez une référence de l'objet quelque part). La méthode kill() supprime le sprite de tous les groupes qui le contiennent. Ça supprime proprement l'objet sprite. Si , par hasard, vous avez déjà rassemblé le code source de deux jeux, vous savez certainement que supprimer proprement un objet du jeu peut être ardu. Un sprite possède également une méthode alive(), qui retourne vrai si il est encore membre d'un groupe au moins.
 
== La classe GroupSprite ==
 
Comme mentionné auparavant, la classe Sprite est conçue pour être une classe de base pour tous les objets de votre jeu. Vous ne pouvez pas vraiment l'utiliser en tant que telle, car elle est constituée seulement de plusieurs méthodes pour faciliter le travail avec les différentes classes de Group. Le sprite garde une trace du groupe auquel il appartient. Le constructeur de classe (la méthode <tt>__init__()</tt>) prend un argument de type ''Group'' (ou une liste d'arguments de type ''Group'') que l'instance de Sprite devrait contenir. Vous pouvez également changer les membres d'un objet de type Group avec les méthodes <tt>add()</tt> et <tt>remove()</tt>. Il y a également une méthode <tt>groups()</tt>, qui retourne une liste des groupes actuels contenant le sprite
La classe Group est un simple conteneur. Comme sprite, elle a une méthode add() et une méthode remove() qui peuvent modifier un groupe tant que des sprites y sont contenus. Vous pouvez également passer un sprite ou une liste de sprites au constructeur (méthode __init__) pour créer une instance de Group qui contient quelques sprites initiaux.
 
Lorsque vous utilisez les classes Sprite, il est préférable de les considérer comme ''valides'' ou ''vivantes'' lorsqu'elles sont contenues dans un ou plusieurs groupes. Lorsque vous supprimez l'instance de tous les groupes, Pygame va supprimer l'objet (sauf si vous possédez votre propre référence de l'objet quelque part). La méthode <tt>kill()</tt> supprime le sprite de tous les groupes qui le contiennent. Elle supprime proprement l'objet sprite. Si, par hasard, vous avez déjà réuni le code source de deux jeux, vous savez certainement que supprimer proprement un objet du jeu peut être ardu. Un sprite possède également une méthode <tt>alive()</tt>, qui retourne <tt>true</tt> s'il est encore membre d'au moins un groupe.
Le groupe a quelques autres méthodes comme empty() pour supprimer tous les sprites du groupe et copy() qui va renvoyer une copie du groupe et de tous ses membres à l'identique. La méthode has() fait une vérification rapide du fait qu'un groupe contient un sprite ou une liste de sprites.
 
== La classe Group ==
L'autre fonction que vous utiliserez fréquemment est la méthode sprites(). Elle retourne un objet sur lequel il est possible de boucler pour avoir un accès à chacun des sprites que le groupe contient. Actuellement, c'est seulement une liste de sprites, mais dans les prochaines versions, elle utilisera les itérateurs pour de meilleures performances. (NdT : n'utilise-t-elle pas déjà les itérateurs ?)
 
La classe Group est un simple conteneur. Comme sprite, elle possède une méthode <tt>add()</tt> et une méthode <tt>remove()</tt> qui peuvent modifier un groupe tant que des sprites y sont contenus. Vous pouvez également passer un sprite ou une liste de sprites au constructeur (méthode <tt>__init__()</tt>) pour créer une instance de Group qui contiendra des sprites initiaux.
Comme un raccourci, la classe Group contient également une méthode update(), qui va appeler la méthode update() sur chacun des sprites du groupe. Chacune des méthodes update() appelées sur les sprites possèdent les mêmes arguments. Habituellement dans un jeu, vous avez besoin d'une fonction qui met à jour l'état des objets. Il est très simple d'utiliser vos propres méthodes en utilisant la méthode Group.sprites(), mais le raccourci est assez utilisée pour être inclusedans la classe Group. Remarquez également que la classe de base Sprite a une méthode update() "vide" qui prend n'importe quelle sorte d'argument et ne fait strictement rien.
 
Le groupe possède d'autres méthodes comme <tt>empty()</tt> pour supprimer tous les sprites du groupe et <tt>copy()</tt> qui va renvoyer une copie du groupe et de tous ses membres à l'identique. La méthode <tt>has()</tt> fait une vérification rapide sur le fait qu'un groupe contienne tel sprite ou telle liste de sprites.
Enfin, la classe Group a deux autres méthodes qui vous permettent d'utiliser la méthode interne len(), récupérant le nombre de sprites contenus. Et l'opérateur "truth", qui vous permet d'écrire "if mygroup:" afin de vérifier si le groupe a des sprites ou non.
 
L'autre fonction que vous utiliserez fréquemment est la méthode <tt>sprites()</tt>. Elle retourne un objet sur lequel il est possible de boucler pour avoir un accès à chacun des sprites que le groupe contient. Actuellement, c'est seulement une liste de sprites, mais dans les prochaines versions de Python, elle utilisera les itérateurs pour de meilleures performances. (NdT : n'utilise-t-elle pas déjà les itérateurs ?)
=Utilisation couplée des deux classes=
 
Tel un raccourci, la classe Group contient également une méthode <tt>update()</tt>, qui va appeler la méthode <tt>update()</tt> sur chacun des sprites du groupe, en passant les même arguments à chacune d'elles. Habituellement dans un jeu, vous avez besoin d'une fonction qui met à jour l'état des objets. Il est très simple d'appeler vos propres méthodes en utilisant la méthode <tt>Group.sprites()</tt>, mais c'est un raccourci suffisamment utilisé pour être inclus dans la classe Group. Remarquez également que la classe de base Sprite a une méthode <tt>update()</tt> vide qui prend n'importe quelle sorte d'argument et ne fait strictement rien.
Arrivé là, les deux classes semblent vraiment simples. Elles ne font pas beaucoup plus que ce que vous pouvez faire avec une simple liste et votre propre classe d'objets du jeu. Mais il y a quelques gros avantages à utiliser les modules Sprite et Group ensemble. Un seul sprite peut être contenu dans autant de groupe que vous voulez. Rappelez-vous que aussitôt qu'un sprite n'est plus contenu par aucun groupe, il sera automatiquement supprimé (sauf si la référence de cet objet existe ailleurs que dans un groupe).
 
Enfin, la classe Group a deux autres méthodes qui vous permettent d'utiliser la méthode interne <tt>len()</tt>, récupérant le nombre de sprites contenus. Et l'opérateur <tt>truth</tt>, qui vous permet d'écrire <tt>if mygroup:</tt> afin de vérifier si le groupe a des sprites ou non.
La première chose importante est que l'on a un moyen rapide et simple de séparer les sprites en catégories. Par exemple, supposons un jeu de type pacman-like. Nous pourrions faire des groupes séparés pour les différents types d'objet dans le jeu, par exemple, un pour les fantômes, un pour Pac et un pour les pilules. Quand pac mange une pilule de puissance, nous pouvons changer l'état de tous les fantômes en agissant sur le groupe des fantômes. C'est plus rapide et plus simple que de boucler au travers d'une liste sur tous les objets du jeu et de vérifier si chacun d'entre eux est un fantôme, puis alors de le modifier.
 
== Utilisation couplée des deux classes ==
 
Arrivé là, les deux classes semblent vraiment simples. Elles ne font pas beaucoup plus que ce que vous pourriez faire avec une simple liste et votre propre classe d'objets du jeu. Mais il y a de gros avantages à utiliser les modules ''Sprite'' et ''Group'' ensemble. Un seul sprite peut être contenu dans autant de groupe que vous voulez. Rappelez-vous que dès qu'un sprite n'est plus contenu dans aucun groupe, il sera automatiquement supprimé (sauf si la référence de cet objet existe ailleurs que dans un groupe).
 
La première chose importante est que l'on a un moyen rapide et simple de séparer les sprites en catégories. Par exemple, supposons que l'on ait un jeu de type ''pac-man''. Nous pourrions faire des groupes séparés pour les différents types d'objet dans le jeu, par exemple, un pour les fantômes, un pour pac-man et un pour les pilules. Quand pac-man mange une pilule de puissance, nous pouvons changer l'état de tous les fantômes en agissant sur le groupe des fantômes. C'est plus rapide et plus simple que de boucler à travers une liste de tous les objets du jeu et de vérifier si chacun d'entre eux est un fantôme, puis alors de le modifier.
Ajouter et déplacer des groupes et des sprites est une opération très rapide, plus rapide que d'utiliser des listes pour tout stocker. Ainsi, vous pouvez très efficacement changer les membres d'un groupe. Les groupes peuvent être utilisés pour fonctionner comme de simples attributs pour chaque objet du jeu. Au lieu de suivre un attribut comme "<tt>close_to_player"</tt> pour un groupe d'objets ennemis, vous pourriez les ajouter à un groupe séparé. Lorsque vous aurez besoin d'accéder à tous les ennemis qui sont proches du joueur, vous en aurez déjà la liste, au lieu de parcourir une liste de tous les ennemis, en vérifiant qu'elles ont l'attribut "<tt>close_to_player"</tt>. Plus tard surdans votre jeu, vous pourrez ajouter plusieurs joueurs, et au lieu d'ajouter des attributs supplémentaires "<tt>close_to_player2"</tt>, "<tt>close_to_player3"</tt>, vous pourrez facilement ajouter différents groupes correspondant à chacun de ces joueurs.
 
Un autre bénéfice important apporté par l'utilisation des classes ''Sprite'' et ''Group'' est que les groupes permettent la suppression facile des objets du jeu. Dans un jeu où beaucoup d'objets font référence à d'autres objets, parfois, supprimer un objet peut être très difficile, parce que ça nécessite que sa référence ne soit plus contenue nullenul part. Supposons que nous avonsayons un objet qui "cherche"en ''poursuive'' un autre objet par sa référence. Le chercheur''poursuivant'' serapourra avoir alors défini un simple groupe qui fait référence à l'objet (ou aux objets) qui leil recherchentest entrain de poursuivre. Si l'objet cherché''poursuivi'' est détruit, nous n'avons pas besoin de nous soucier de dire auxau utilisateurs de cet objet''poursuivant'' d'arrêter d'utiliserde sale référence''poursuivre''. LLe ''poursuivant''objet utilisateur de la référence peutpourra voir de lui même que son groupe de ''poursuivis'' est maintenant vide, et vapourra agirchercher enune nouvelle conséquencecible.
 
Encore une fois, la chose dont il faut se rappeler est que ajouter ou supprimer des sprites d'un groupe est une opération très peu consommatrice deen temps de calcul. Vous pouvez êtregagner plusen rapideefficacité en consituantconstituant directement plusieurs groupes pour contenir et organiser les objets du jeu. Ils peuvent rester inutilisés et vides danspour de grandes parties du jeu, vous n'avez pas besoin de vous en occuper, il n'y aura aucune contrepartie si vous créez directement tous les groupes dont vous pensez avoir besoin, sans les utiliser au premier abord.
 
== Les différents types de groupe ==
 
Les exemples ci-dessus et les raisons d'utiliser Sprite et les groupes sont seulement la partie émergée de l'iceberg. Un autre avantage est que le module sprite possède différents types de groupes. Ces différents types héritent tous du type ancêtre Group, mais ils possèdent également des fonctionnalités supplémentaires (où touchent à des fonctionnalités différentes). Voici une liste des classes de type Group présententprésentes dans le module sprite.
==;Group==
:C'est le type standardgroupe de groupetype standard, "''sans supplément" '', qui est explicité ci-dessus. La plupart des autres groupes sont dérivés de luicelui-ci, mais pas tous.
 
==;GroupSingle==
:Celui-ci fonctionne exactement comme lela groupeclasse class''Group'' régulierstandard, mais il contient seulement le sprite le plus récemment ajouté. Ainsi, lorsque vous ajoutez un sprite à ce groupe, il "''oublie"'' tout à propos du précédent sprite qui était stocké. De cette manière, un groupe de ce type contient toujours seulement un ou zéro sprites.
==;RenderPlain==
:C'est un type dérivé du type Group. Il apossède une méthode <tt>draw()</tt> qui dessine tous les sprites contenusqu'il contient à l'écran (ou sur une surface quelconque). Pour ce faire, il nécessite que tous les sprites qu'il contient possèdent les attributs "<tt>image"<tt> et "<tt>rect"<tt>. Il les utilise cela pour savoir surquoi lesquels agir,[[Pygame_-_comment_bouger_une_image#D.C3.A9finition_de_blit|bliter]] et où agirles bliter. (blit==agir ?)
 
;RenderClear
:Ce type est dérivé du type RenderPlain, et ajoute la méthode <tt>clear()</tt>. Cette méthode va effacer la position précédente de tous les sprites dessinés, en utilisant une image de fond pour les remplacer. Elle est suffisamment élégante pour gérer les sprites supprimés et les effacer proprement de l'écran lors de l'appel de la méthode <tt>clear()</tt>.
;RenderUpdates
==RenderClear==
:C'est la cadillac des groupes de rendu. Il hérite de ''RenderClear'', mais change la méthode <tt>draw()</tt> pour retourner une liste de <tt>Rects</tt> de Pygame, qui représente toutes les zones de l'écran qui ont été modifiées.
Ce type est dérivé du type RenderPlain, et ajoute la méthode clear(). Cette méthode va effacer la position précédente de tous les sprites affichés, en utilisant pour les remplacer une image de fond. Elle est parfaite pour réaliser la suppression et l'effacement propre des sprites possédés par le groupe.
 
Voici la liste des différents types de groupe disponibles. Nous discuterons plus longuement de ces groupes de rendu dans la prochaine section. Il n'y a rien qui doive vous empêcher de créer votre propre classe héritée de ''Group'' de cette façon. Ces groupes sont seulement du code python, donc vous pouvez hériter d'un des ces types explicités précédemment et ajouter ou modifier n'importe lequel des attributs ou des méthodes. À l'avenir, j'espère que nous pourrons ajouter quelques types de groupe supplémentaires dans cette liste. Par exemple un GroupMulti qui est comme GroupSingle, mais pourra contenir un nombre fixe de sprites (dans une sorte de buffer circulaire ?). Également un super-render group qui pourra effacer la position d'anciens sprites sans avoir besoin d'une image de fond pour le faire (en mémorisant une copie de l'écran avant le blit). Qui sait, mais dans l'avenir de nouvelles classes utiles seront susceptibles d'être ajoutées à cette liste.
==RenderUpdates==
 
C'est la cadillac des groupes de rendu. Il possède les attributs hérités de RenderClear, mais change la méthode draw() pour retourner également une liste de Rects pygame, lesquels représentent toutes les aires de l'écran qui ont été modifiées.
== Les groupes de rendu ==
 
Précédemment, nous avons vu qu'il existe trois groupes de rendu différents. Nous pouvons probablement débuter avec le ''RenderUpdates'', mais il intègre des manipulations supplémentaires qui ne sont pas réellement nécessaires pour un jeu en scrolling, par exemple. Nous avons donc ici plusieurs outils : à chaque type de travail correspond son outil.
 
Pour un jeu à scrolling, où l'arrière-plan change complètement à chaque image, nous n'avons manifestement pas besoin de nous soucier de la mise à jour des rectangles dans l'appel <tt>display.update()</tt>. Vous devriez en définitive, partir avec le groupe ''RenderPlain'' pour gérer votre rendu.
 
Pour les jeux où l'arrière-plan sera plus statique, vous ne voudriez pas que Pygame régénère entièrement l'écran (surtout qu'il n'y en a pas besoin). Ce type de jeu implique l'effacement de l'ancienne position de chaque objet, et son dessin à un nouvel endroit à chaque image. De cette façon, nous ne changeons que ce qui est nécessaire. La plupart du temps, vous utiliserez la classe ''RenderUpdates'' pour ces types de jeu, puisque vous voudrez passer cette liste de changements à la fonction <tt>display.update()</tt>.
 
La classe ''RenderUpdates'' effectue aussi un joli travail pour minimiser les zones qui se chevauchent dans la liste des rectangles actualisés. Si la position précédente et la position actuelle d'un objet se chevauchent, la classe ''RenderUpdates'' les fusionnera en un rectangle unique. Combinez ceci avec le fait qu'elle gère proprement les objets supprimés, et vous obtiendrez une classe de Groupe très puissante. Si vous avez écrit un jeu qui manipule les rectangles modifiés pour les objets dans un jeu, vous savez que c'est la cause d'une importante quantité de code ''sale'' dans votre jeu. Spécialement lorsque vous vous lancez dans les objets qui peuvent être effacés à chaque instant. Tout ce travail se réduit à une méthode <tt>clear()</tt> et <tt>draw()</tt> avec cette classe monstre. De plus avec le contrôle du chevauchement, c'est d'autant plus rapide que si vous le faisiez vous-même.
 
Sachez que rien ne vous empêche de mêler et d'associer ces groupes de rendu dans votre jeu. Vous pouvez finalement utiliser plusieurs groupes de rendu si vous voulez associer vos sprites en couches. Ainsi, si l'écran est séparé en plusieurs sections, peut-être que chaque section de l'écran devra utiliser un groupe de rendu approprié ?
 
== Détection de collision ==
 
Le module sprite inclut deux fonctions de détection de collision très génériques. Pour des jeux trop complexes, elles ne seront pas suffisantes, mais vous pouvez facilement vous inspirer du code source et le modifier comme voulu. Voici un résumé de ces fonctions et de ce qu'elles font.
 
=== spritecollide(sprite, group, dokill) -> liste ===
 
:Celle-ci contrôle les collisions entre un sprite unique et les sprites d'un groupe. Elle requiert un attribut <tt>rect</tt> pour tous les sprites utilisés. Elle retourne la liste de tous les sprites qui chevauchent le premier sprite. L'argument <tt>dokill</tt> est un booléen. S'il est vrai, la fonction appelle la méthode <tt>kill()</tt> sur tous les sprites. Ceci signifie que la dernière référence de chaque sprite est probablement dans la liste retournée. Une fois la liste disparue, les sprites le seront aussi. Un exemple rapide sur son utilisation dans une boucle.
 
<source lang="python">
>>> for bomb in sprite.spritecollide(player, bombs, 1):
... boom_sound.play()
... Explosion(bomb, 0)
</source>
 
:La fonction recherche tous les sprites du group <tt>bomb</tt> qui entrent en collision avec le joueur. A cause de l'argument <tt>dokill</tt>, elle supprime toutes les bombes écrasées. Pour chaque bombe entrée en collision avec le joueur, elle joue l'effet sonore <tt>boom_sound</tt> et crée une nouvelle explosion à l'endroit de la bombe. A noter ici que la classe Explosion sait ajouter chaque instance à la classe appropriée, ainsi nous n'avons pas besoin de l'enregistrer dans une variable, cette dernière ligne peut sembler légèrement ''amusante'' pour des programmeurs python.
 
=== groupcollide(group1, group2, dokill1, dokill2) -> dictionnaire ===
 
:Celle-ci est similaire à la fonction <tt>spritecollide()</tt>, mais est un peu plus complexe. Elle vérifie les collisions de tous les sprites d'un groupe avec les sprites d'un autre. Il y a également un argument ''dokill'' pour les sprites de chaque liste. Quand <tt>dokill1</tt> est vrai, les sprites en collision dans le groupe 1 subiront la méthode <tt>kill()</tt>. Si <tt>dokill2</tt> est vrai, nous obtiendrons les mêmes résultats pour le groupe 2. Le dictionnaire qu'elle retourne fonctionne comme ceci : chaque clé du dictionnaire est un sprite du groupe 1 pour lequel il y a collision. La valeur de cette clé est la liste des sprites du groupe 2 qui sont en collision avec lui. Peut-être qu'un rapide exemple sera plus explicite.
 
<source lang="python">
>>> for alien in sprite.groupcollide(aliens, shots, 1, 1).keys()
... boom_sound.play()
... Explosion(alien, 0)
... kills += 1
</source>
 
:Ce code vérifie les collisions entre les balles du joueur et tous les aliens qu'elles ont croisés. Dans ce cas nous bouclons simplement par les clés du dictionnaire, mais nous pouvons aussi boucler par les valeurs ou les items si nous voulons faire quelquechose avec les balles entrées en collision avec les aliens. Si nous bouclons par les valeurs, nous voudrions boucler les listes qui contiennent les sprites. Le même sprite peut toutefois apparaître plus d'une fois dans ces différentes boucles, puisque la même balle peut être entrée en collision avec de multiples aliens.
 
Ce sont les fonctions de collision fournies avec Pygame. Il devrait être simple de créer vos propres fonctions qui pourraient utiliser quelquechose de différent que les attributs <tt>rect</tt>. Ou peut-être essayer d'affiner un peu plus votre code en affectant directement les objets en collision, au lieu de construire une liste de collision. Le code des fonctions de collision de sprite est très optimisé, mais vous pouvez légèrement l'accélérer en supprimant certaines fonctionnalités qui ne vous sont pas nécessaires.
 
== Problèmes connus ==
 
Actuellement, il existe un problème principal soulevé par de nouveaux utilisateurs. Quand vous dérivez votre nouvelle classe de sprite, vous devez appeler la méthode <tt>Sprite.__init__()</tt> à partir de votre propre constructeur de classe <tt>__init__()</tt>. Si vous oubliez d'appeler la méthode <tt>Sprite.__init__()</tt>, vous obtiendrez une erreur assez énigmatique, du style : <tt>AttributeError: 'mysprite' instance has no attribute '_Sprite__g'</tt>.
 
== Dériver vos propres classes (Expert) ==
 
Concernant la rapidité, les classes de groupes courantes essaient de faire exactement ce dont elles ont besoin, et ne gère pas énormément de situations générales. Si vous décidez que vous avez besoin de fonctionnalités spéciales, vous devriez créer votre propre classe de groupe.
 
Les classes ''Sprite'' et ''Group'' sont conçues pour être dérivées, n'hésitez pas à créer vos propres classes ''Group'' pour effectuer des actions spécialisées. La meilleure manière de commencer est probablement le code source du module de sprite. L'examen des groupes ''Sprite'' actuels devrait constituer un bon exemple sur la façon de créer les vôtres.
 
Par exemple, voici le code source pour un groupe de rendu qui appelle une méthode <tt>render()</tt> pour chaque sprite, au lieu de simplement bliter une variable ''image''. Puisque nous voulons gérer uniquement les zones actualisées, nous démarrerons avec une copie du groupe original ''RenderUpdate'', en voici le code :
 
<source lang="python">
class RenderUpdatesDraw(RenderClear):
"""Appel de sprite.draw(screen) pour faire un rendu des sprites"""
def draw(self, surface):
dirty = self.lostsprites
self.lostsprites = []
for s, r in self.spritedict.items():
newrect = s.draw(screen) #Voici la principale modification
if r is 0:
dirty.append(newrect)
else:
dirty.append(newrect.union(r))
self.spritedict[s] = newrect
return dirty
</source>
 
Following is more information on how you could create your own Sprite and Group objects from scratch.
 
Les objets Sprite requièrent uniquement deux méthodes : <tt>add_internal()</tt> et <tt>remove_internal()</tt>. Elles sont appelées par les classes ''Group'' quand elles s'enlèvent un sprite d'elles-mêmes. Les fonctions <tt>add_internal()</tt> et <tt>remove_internal()</tt> possède un unique argument qui est un Groupe. Votre Sprite aura besoin d'une technique pour conserver une trace des Groupes auxquels il appartient. Vous voudriez peut-être essayer d'assortir les autres méthodes et arguments avec la vraie classe Sprite, mais si vous n'avez pas l'utilité de ces méthodes, vous êtes certains de ne pas en avoir besoin.
 
C'est presque les mêmes exigences pour la création de votre propre groupe. En fait, si vous examinez le code source, vous verrez que le ''GroupSingle'' n'est pas dérivé de la classe ''Group'', il implémente uniquement les mêmes méthodes, vous ne pouvez donc pas faire réellement la différence. Une fois encore, vous aurez besoin des méthodes <tt>add_internal()</tt> et <tt>remove_internal()</tt> que les sprites appellent lorsqu'ils veulent s'ajouter ou se retirer eux-mêmes du groupe. Les fonctions <tt>add_internal()</tt> et <tt>remove_internal()</tt> possède un unique argument qui est un sprite. La seule autre nécessité pour les classes groupes est d'avoir un attribut factice nommé <tt>_spritegroup</tt>. Sa valeur n'est pas importante, tant que cet attribut est présent. Les classes Sprite peuvent chercher cet attribut pour déterminer la différence entre un ''Group'' et un conteneur Python ordinaire. C'est important, car plusieurs méthodes de sprite peuvent prendre un argument d'un groupe unique, ou une séquence de groupes. Puisque les deux sont similaires, c'est la manière la plus flexible de ''voir'' la différence.
 
Vous devriez lire le code source du module sprite. Là où le code est un peu ''customisé'', il y a suffisamment de commentaires pour vous aider à suivre. Il existe également une section ''todo'' dans le code source, si vous voulez contribuer.
Voici la liste des différents types de groupe disponibles. Nous discuterons plus en avant à propos de ces groupes de rendu dans la prochaine section. Il n'y a rien qui doive vous empêcher de créer votre propre classe héritée de Group de cette façon. Ces groupes sont seulement du code python, donc vous pouvez faire hériter d'un des types explicités précédemment et ajouter ou changer n'importe lequel des attributs ou des méthodes. À l'avenir, j'espère que nous pourrons ajouter quelques types supplémentaires de groupe dans cette liste. par exemple un GroupMulti qui est comme GroupSingle, mais peut contenir un nombre donné de sprites (dans une sorte de buffer circulaire ?). Également un super-render group qui peut effacer la position d'anciens sprites sans avoir besoin d'une image de fond pour le faire (en mémorisant une copie de l'écran avant l'affichage). Personne ne sait vraiment, mais dans l'avenir de nouvelles classes utiles sont susceptibles d'être ajoutées à cette liste.