Créer une simple fenêtre (personnalisable !)

L’auteur de ce contenu recherche un repreneur. N’hésitez pas à le contacter par MP pour proposer votre aide !

Dans ce chapitre, nous allons voir comment créer une fenêtre, et quelles possibilités nous sont offertes pour la personnaliser.

Créons une fenêtre basique

Attention les yeux, c’est très simple !

Voici le code d’une fenêtre basique :

1
2
3
4
5
6
7
import pygame

pygame.init()

ecran = pygame.display.set_mode((300, 200))

pygame.quit()

Si vous avez lancé ce script, ne partez pas ! C’est normal si votre fenêtre s’est fermée en moins d’une fraction de seconde.

Détaillons ce code :

ligne 1 : on importe Pygame

ligne 3 : on initialise Pygame, très important ! C’est cette ligne qui va charger tous les modules de Pygame (comme font, draw, display …) et les initialiser

ligne 5 : on crée une fenêtre avec le module display de Pygame, en lui passant en paramètre un tuple contenant 300 et 200. Cela veut dire que la fenêtre fera 300 pixels de large sur 200 pixels de haut

ligne 7 : il faut quitter proprement Pygame, cela va libérer toutes nos ressources, nous n’en avons plus besoin

Avec ce code, la fenêtre se ferme toute seule, car Pygame a considéré qu’il avait fini son travail. On ne lui a pas demandé de gérer autre chose, comme des événements (qui pourraient par exemple dire à Pygame : "attends que je clique sur la croix pour fermer ma fenêtre") !

Pour cela, il faut demander à Pygame de vérifier s’il y a des événements en cours (touche du clavier appuyée, clic souris …) et il nous faut les traiter par la suite pour agir en conséquence :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import pygame
# par la même occasion cela importe pygame.locals dans l'espace de nom de Pygame

pygame.init()

ecran = pygame.display.set_mode((300, 200))

continuer = True

while continuer:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            continuer = False

pygame.quit()

Maintenant, lancez votre code, et appuyez sur n’importe quelle touche du clavier. La fenêtre va se fermer !

Alors on reprend son calme, l’excitation de la première fenêtre va passer, ne vous inquiétez pas

ligne 2 : très intéressante ! On ne vous en avait par parlé dans la section précédente, en fait Pygame importe toutes un tas de constantes. De manière générale, les noms de tous les événements de Pygame sont importés dans votre programme. Sans ces constantes, nous aurions dû taper le code de chaque événement ! Et oui, car KEYDOWN n’est autre qu’un entier (ayant pour valeur 2) ! Tout comme les codes K_a, K_g … qui représentent respectivement les touches A et G

lignes 10 à 13 : le code le plus intéressant se trouve là. Une boucle for qui appelle une fonction obscure.

Oui oui, c’est bien ça. Dans l’ordre on fait ceci :

  • on récupère l’événement que Pygame a capturé que l’on nomme event (il se peut qu’il n’y en ai pas, dans ce cas, le code n’est pas exécuté, et la boucle (qui contiendra tout le code d’affichage d’images, qui gérera les événements …) continue de boucler)

  • dans le if maintenant :

    • on regarde si le "type" de l’événement est une entrée clavier
      • si oui, alors on met continuer à False, donc on quitte la boucle

On utilise un bool que l’on a appelé continuer pour savoir si la boucle doit continuer de tourner ou non.

Pour un début, cela peut paraitre compliqué. Mais ne vous inquiétez surtout pas, c’est normal, et nous allons éclairer toutes ces nouvelles notions dans les prochains chapitres :)

Personnalisons notre fenêtre

Tout d’abord, nous allons voir quels arguments nous pouvons passer à pygame.display.set_mode(), autre que la taille de notre fenêtre.

La documentation de Pygame nous informe de ceci :

pygame.display.set_mode() Initialize a window or screen for display set_mode(resolution=(0,0), flags=0, depth=0) -> Surface

This function will create a display Surface. The arguments passed in are requests for a display type. The actual created display will be the best possible match supported by the system.

The resolution argument is a pair of numbers representing the width and height. The flags argument is a collection of additional options. The depth argument represents the number of bits to use for color.

The Surface that gets returned can be drawn to like a regular Surface but changes will eventually be seen on the monitor.

If no resolution is passed or is set to (0, 0) and pygame uses SDL version 1.2.10 or above, the created Surface will have the same size as the current screen resolution. If only the width or height are set to 0, the Surface will have the same width or height as the screen resolution. Using a SDL version prior to 1.2.10 will raise an exception.

It is usually best to not pass the depth argument. It will default to the best and fastest color depth for the system. If your game requires a specific color format you can control the depth with this argument. Pygame will emulate an unavailable color depth which can be slow.

When requesting fullscreen display modes, sometimes an exact match for the requested resolution cannot be made. In these situations pygame will select the closest compatible match. The returned surface will still always match the requested resolution.

The flags argument controls which type of display you want. There are several to choose from, and you can even combine multiple types using the bitwise or operator, (the pipe “|” character). If you pass 0 or no flags argument it will default to a software driven window. Here are the display flags you will want to choose from:

pygame.FULLSCREEN create a fullscreen display pygame.DOUBLEBUF recommended for HWSURFACE or OPENGL pygame.HWSURFACE hardware accelerated, only in FULLSCREEN pygame.OPENGL create an OpenGL renderable display pygame.RESIZABLE display window should be sizeable pygame.NOFRAME display window will have no border or controls

http://www.pygame.org/docs/ref/display.html#pygame.display.set_mode

On voit que l’on peut passer une résolution (la taille de notre fenêtre) et que si on ne met pas de taille ou que l’on met (0, 0) comme taille, la fenêtre fera la taille de votre écran.

La documentation nous informe aussi qu’il est préférable de ne pas changer l’argument depth, car cela pourrait ralentir votre jeu, Pygame pouvant essayer de créer des couleurs n’existant pas.

Et enfin nous arrivons aux flags. Ce sont des arguments que nous pouvons passer à pygame.display.set_mode(), mais ils ne sont en aucun cas obligatoires.

Les flags

  • pygame.FULLSCREEN

    • cela permet de créer une fenêtre en plein écran (donc plus de bordures, on ne pourra pas, à ce stade du tutoriel, fermer la fenêtre. Attendez que l’on ai vu les événements avant d’utiliser ce flag !)
  • pygame.DOUBLEBUF

    • à utiliser pour un usage conjoint à OpenGL, nous ne nous s’en servirons pas dans ce tutoriel
  • pygame.HWSURFACE

    • seulement pour le mode plein écran, cela utilise une accélération matérielle
  • pygame.OPENGL

    • crée une fenêtre de rendu compatible avec OpenGL
  • pygame.RESIZABLE

    • la fenêtre sera redimensionnable
  • pygame.NOFRAME

    • la fenêtre n’aura pas de bordures, il sera donc impossible de la déplacer
NOFRAME
Une fenêtre avec le flag FULLSCREEN (oui, le code a été modifié pour que l’on puisse voir la fenêtre :P )

On vous doit sûrement des explications pour le mode FULLSCREEN, du moins si vous avez essayé (alors que l’on vous l’avait défendu :pirate: ). En mettant pygame.display.set_mode((300, 200), pygame.FULLSCREEN) vous aurez des surprises, car votre fenêtre prendra tout l’écran. Et oui, ici, Pygame va considérer que votre écran à une résolution de 300 sur 200.

Pour obtenir une fenêtre comme nous, donc ne pas avoir ce "petit" problème en mode FULLSCREEN, il faut utiliser l’astuce avec pygame.display.set_mode((0, 0), pygame.FULLSCREEN), qui veut dire : "crée une fenêtre qui fait toute la taille de l’écran, et ce en FULLSCREEN". Sauf que vous ne voudrez peut-être pas utiliser tout l’écran, donc il faut créer une "sous surface" que l’on considérera comme notre fenêtre (oui, c’est tout à fait possible, étant donné que chacun de nos objets ecran sont eux même des images).

Voici donc le code que l’on a utilisé :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import pygame

pygame.init()

ecran = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)

continuer = True

while continuer:
    # ici on crée un rectangle de couleur rose, en x=0, y=0 et de taille 300 sur 200
    # nous verrons plus tard comment faire plus en détail :)
    pygame.draw.rect(ecran, (180, 20, 150), (0, 0, 300, 200))
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            continuer = False
    # ici on actualise l'écran, car on a affiché un rectangle rose, et on veut qu'il soit
    # visible. Si l'on avait pas mit cette instruction, on n'aurait jamais vu le rectangle !
    pygame.display.flip()

pygame.quit()

Ici le rectangle rose sera votre "écran", mais vous pourrez dessiner à côté bien entendu (ici, en FULLSCREEN, ce n’est qu’un cadre si vous voulez).

Changer le titre et l’icône de notre fenêtre

Pour changer le titre de votre fenêtre, il faut jouer avec les méthodes offertes par le module display, comme ceci :

1
pygame.display.set_caption("Mon super titre de Ouf !")

Et pour changer l’icône de votre fenêtre, ce sera :

1
pygame.display.set_icon(image)

Ici, image est un objet Surface de Pygame. Autrement dit, il vous faut savoir charger une image pour changer l’icône de votre fenêtre :)

Là on peut se demander si notre icône doit être au format ico pour Windows, et xbm pour Linux. Sauf que … sur ce coup là, Pygame réconcilie tout le monde, c’est juste une image !

En petite avant-première, voici comment en charger une :

1
image = pygame.image.load("monimage.png").convert()

Voilà ! Maintenant, vous savez comment créer une fenêtre, lui donner un titre, changer son icône, et bien d’autres choses ! Passons à la suite matelot !