Et c'est parti pour le quatrème tuto / cours de SNT, consacré à la découverte de Pygame en Python ! 😃

   Pour cette nouvelle étape, nous allons déplacer notre sprite ! 😋

   Avant de nous lancer tête bêche dans le code, réfléchissons à ce que nous voulons faire ! 🙃

   On veut que notre lapin ninja puisse aller à droite en appuyant sur la flèche droite, s'arrêter si on appuie plus et aller à gauche si on appuie sur la flèche gauche. Cela signifie qu'il va falloir tester les touches du clavier pour voir quelle touche est enfoncée et déplacer notre bonhomme progressivement dans un sens ou dans l'autre. 🧐

   Il va aussi falloir lui donner une certaine vitesse (qu'on pourra changer selon le type de jeu qu'on veut faire 🤠).

   Et enfin, il faudra l'afficher, en prenant soin de le retourner quand il ira à gauche (sinon, il va faire du Moonwalk comme Michael...). 👻

   Bon, dit comme ça, ça a pas l'air trop compliqué ! (Mais, en fait ça va l'être un petit peu quand même...) 🤯

   

  Bon, on va commencer par le plus simple avec le fichier Constantes.py ! 🤪

 

Fichier : Constantes.py

# Créé par Jay81, le 16/06/2024 en Python 3.7

"""Constantes du jeu"""

# Paramètres de la fenêtre
LARGEUR = 640
HAUTEUR = 360

# Personnalisation de la fenêtre
TITRE = "Rabidja"
ICONE = ""

# Listes des images du jeu (graphics)
BACKGROUND = "graphics/background.png"
SPRITE_JOUEUR = "graphics/rabidja.png"

# Taille du sprite du jouer
PLAYER_HEIGHTH = 50
PLAYER_WIDTH = 40

# Machine à états
NONE = 0
DROITE = 1
GAUCHE = 2

IDLE = 0
WALK = 1
JUMP = 2
DOUBLEJUMP = 3
DEAD = 4

# Timer pour l'animation
TIMER = 4

# Vitesse du joueur
PLAYER_SPEED = 4

   

   Pas grand chose à rajouter ici... Juste un état : NONE quand notre joueur sera immobile et la vitesse de notre joueur : PLAYER_SPEED, qu'on va régler à 4 pour l'instant (mais que vous pourrez changer à la fin pour tester !) 😎

   Passons maintenant au Main() (programme principal).

   

Fichier : Main.py

# Créé par Jay81, le 16/06/2024 en Python 3.7

# Import de pygame
import pygame
from pygame.locals import *

#Import des constantes et classes du jeu
from Constantes import *
from Player import *

#Initialisation de pygame
pygame.init()
clock = pygame.time.Clock()

# Ouverture de la fenêtre de jeu en résolution 640 x 360 pixels
fenetre = pygame.display.set_mode((LARGEUR, HAUTEUR)) #, pygame.FULLSCREEN|SCALED)

#Titre
pygame.display.set_caption(TITRE)

#Chargement du fond d'écran (background)
fond = pygame.image.load(BACKGROUND).convert()

#Création du joueur
player = Player()

# Boucle principale du jeu
continuer = True
while continuer :

    # On teste les événements
    for event in pygame.event.get():
        # Si on appuie sur quitter, on ferme le jeu
        if event.type == QUIT:
            continuer = False

    # On teste les appuis sur le touches Gauche / Droite
    dicKeys = pygame.key.get_pressed()
    if dicKeys[K_LEFT]:
        player.input = GAUCHE
    elif dicKeys[K_RIGHT]:
        player.input = DROITE
    elif dicKeys[K_ESCAPE]:
        continuer = False
    else:
        player.input = NONE

    # On affiche le fond d'écran (background)
    fenetre.blit(fond,(0,0))

    #On met à jour le joueur
    player.update()

    # On affiche le sprite
    player.draw(fenetre)

    #On rafraichit l'écran
    pygame.display.update()

    clock.tick(60)  # limite les FPS à 60

pygame.quit()

    

   Et voilà ! Maintenant, on va expliquer ces modifications pas à pas. 😄

   D'abord, j'ai un peu modifié l'ouverture de la fenêtre, pour pouvoir tester le Fullscreen (ou plein écran). Ainsi, si vous enlevez le commentaire # de la ligne suivante, ainsi qu'une parenthèse après HAUTEUR et que vous lancez le jeu, celui-ci prendra tout votre écran ! 😃 Magique, non ? 🤩

  


# Ouverture de la fenêtre de jeu en résolution 640 x 360 pixels
fenetre = pygame.display.set_mode((LARGEUR, HAUTEUR)) #, pygame.FULLSCREEN|SCALED)

    

   Passons maintenant à la gestion du clavier. Cela fonctionne de la même façon qu'avec toutes les bibliothèques (et forcément plus encore avec la SDL... 😋). On crée une variable dicKeys et on appelle Pygame pour enregistrer dedans la ou les touche(s) du clavier enfoncée(s). On fait ensuite une série de tests (if / elif) pour enregistrer dans player.input si notre joueur doit aller à DROITE, à GAUCHE ou glander ne rien faire : NONE. En fait, c'est plutôt simple ici. 😉

   Notez que si on appuie sur la touche ESCAPE / ECHAP, on quitte le jeu en interrompant sa boucle infinie. 🙂

   


    # On teste les appuis sur le touches Gauche / Droite
    dicKeys = pygame.key.get_pressed()
    if dicKeys[K_LEFT]:
        player.input = GAUCHE
    elif dicKeys[K_RIGHT]:
        player.input = DROITE
    elif dicKeys[K_ESCAPE]:
        continuer = False
else: player.input = NONE

    

   Et voilà, comme d'habitude, passons maintenant à notre dernier fichier ! Là, où les plus gros changements se situent ! ☺️

   Ouvrez donc Player.py et mettez à jour le texte ci-dessous :

Fichier : Player.py

  

# Créé par Jay81, le 16/06/2024 en Python 3.7

# Import de pygame
import pygame
from pygame.locals import *

#Import des constantes et classes du jeu
from Constantes import *


"""Classe permettant de créer un personnage"""
class Player:

    def __init__(self):
         # Chargement du fichier du sprite
         self.sprite = pygame.image.load(SPRITE_JOUEUR).convert_alpha()

         # Coordonnées du sprite
         self.x = 0
         self.y = HAUTEUR - PLAYER_HEIGHTH - 40

         # Direction du sprite
         self.direction = DROITE

         # Animation
         self.frame = 0
         self.timer = TIMER
         self.state = IDLE
         self.maxframes = 7

         # Gestion des inputs (entrées) clavier
         self.input = NONE


    # Mise à jour du sprite
    def update(self):

         # On gère le timer (compte à rebours pour faire défiler l'animation)
         if self.timer < 0:
             if self.frame < self.maxframes:
                  self.frame += 1
             else:
                  self.frame = 0
             self.timer = TIMER
         else:
            self.timer -= 1

         # Gestion des inputs (entrées) clavier
         if self.input == GAUCHE:
            if self.x > 5:
                self.x -= PLAYER_SPEED
                self.state = WALK
                self.direction = GAUCHE
         elif self.input == DROITE:
            if self.x < LARGEUR - PLAYER_WIDTH:
                self.x += PLAYER_SPEED
                self.state = WALK
                self.direction = DROITE
         else:
             self.state = IDLE

         self.input = NONE


    # On dessine le sprite du joueur def draw (self, surface): # Selon la drection, on oriente le joueur en faisant un flip pour la gauche if self.direction == GAUCHE: spritecopy = pygame.transform.flip(self.sprite, True, False)
# On rajoute 2 à notre frame, car à gauche, les frames vont de 2 à 9             surface.blit(spritecopy, (self.x, self.y),
((self.frame + 2) * PLAYER_WIDTH,self.state * PLAYER_HEIGHTH,PLAYER_WIDTH,PLAYER_HEIGHTH)) else: spritecopy = self.sprite surface.blit(spritecopy, (self.x, self.y),
(self.frame * PLAYER_WIDTH,self.state * PLAYER_HEIGHTH,PLAYER_WIDTH,PLAYER_HEIGHTH))

  

   Premièrement, on va créer notre variable input et la mettre par défaut à NONE, car on veut que notre personnage commence le niveau en étant immobile (il va pas partir sans nous, non plus ! 😮).

   Notez que pour gérer la variable input, on doit écrire Player.input quand on est en-dehors de la class (par exemple dans le Main()) et self.input quand on est dedans. C'est logique et ça permet de créer, par exemple deux objets Player (pour le joueur 1 et 2) sans que ceux-ci n'aient les mêmes valeurs. 😁 Mais c'est un petit peu compliqué pour ce tuto (vous pourrez voir ça plus tard dans un autre tuto sur les class). 🧐

  


         # Gestion des inputs (entrées) clavier
         self.input = NONE

    

   Ici, on va gérer le déplacement de notre sprite. C'est simple :

  • S'il va à gauche :
    • On le déplace à gauche en enlevant PLAYER_SPEED de son abscisse x SAUF s'il est à moins de 4 pixels du bord (sinon il va sortir de l'écran et on le reverra peut-être plus jamais... SNIF ! 😅)
    • On met son état / state sur WALK / Marche
    • On met sa direction à GAUCHE (tout ça sera utile pour savoir comment le dessiner à l'écran)
  • S'il va à droite :
    • On le déplace à droite en ajoutant PLAYER_SPEED de son abscisse x SAUF s'il est au bord de l'écran à droite (soit la LARGEUR de l'écran moins la LARGEUR du sprite si on ne veut pas qu'il disparaisse... Essayez d'enlever - PLAYER_WIDTH pour voir. Vous allez vite comprendre ! 😂)
    • On met son état / state sur WALK / Marche.
    • On met sa direction à DROITE.
  • S'il ne fait rien :
    • On met son état / state sur IDLE / Immobile.

   Dans tous les cas, après, on remet input à NONE, sinon, le jeu va croire que la touche reste enfoncée, même si on la relâche !!! 😱

   


         # Gestion des inputs (entrées) clavier
         if self.input == GAUCHE:
            if self.x > 5:
                self.x -= PLAYER_SPEED
                self.state = WALK
                self.direction = GAUCHE
         elif self.input == DROITE:
            if self.x < LARGEUR - PLAYER_WIDTH:
                self.x += PLAYER_SPEED
                self.state = WALK
                self.direction = DROITE
         else:
             self.state = IDLE

         self.input = NONE

    

   Et voilà, passons maintenant à l'affichage du sprite ! 😅

   Si on commence par le blit de notre personnage à droite, c'est le plus simple, car c'est la même chose que dans le tuto précédent (il s'agit du else).

   Là où ça se complique, c'est pour le blit à gauche car il faut retourner notre feuille de sprites en utilisant une variable temporaire spritecopy et en faisant appel à Pygame qui se charge de tout (pygame.transform.flip). Ici, on met le premier flag à True pour un flip vertical, le deuxième à False est pour le flip horizontal. 😉

   Maintenant, quand on va à droite, nos frames vont toujours de 0 à 7 comme dans le tuto précédent.

   Mais quand on va à gauche, nos frames vont aller de 2 à 9 car on va être obligé de retourner (flip) notre spritesheet et on va donc commencer par deux frames vides (si vous n'y faites pas attention, votre sprite va clignoter comme un sapin de Noël ! 😅). 

   

   On va donc devoir rajouter 2 à la variable frame quand on va à gauche, pour avoir la bonne frame. 😉


   


# Selon la drection, on oriente le joueur en faisant un flip pour la gauche
        if self.direction == GAUCHE:
            spritecopy = pygame.transform.flip(self.sprite, True, False)
            surface.blit(spritecopy, (self.x, self.y), 
((self.frame + 2) * PLAYER_WIDTH,self.state * PLAYER_HEIGHTH,PLAYER_WIDTH,PLAYER_HEIGHTH)) else: spritecopy = self.sprite surface.blit(spritecopy, (self.x, self.y),
(self.frame * PLAYER_WIDTH,self.state * PLAYER_HEIGHTH,PLAYER_WIDTH,PLAYER_HEIGHTH))

    

   Notez que l'appel à spritecopy n'est pas obligatoire quand on va à droite, mais c'est toujours mieux d'uniformiser le code, par souci de simplicité 😉.

    Voilà ! Si vous lancez le jeu en appuyant sur la flèche verte dans le MAIN, vous pourrez maintenant déplacer votre lapin favori de droite à gauche ! Bon jeu ! 😅

   A bientôt pour la suite ! 😄

   

  

This site uses cookies to enable you to log in. We do not store or sell any personal data. By continuing to use this website, you agree to their use. Thanks!