Accueil

Traduction

Tutoriel Python - sommaire

Tutoriel Python - recherche

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

Pygame - Encore des jeux

Premier jeu :"savane cruelle"

Les classes

class Proies(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("images_sons/gazelle.png").convert_alpha()
        self.image.set_colorkey((255, 255, 255))
        self.rect = self.image.get_rect()
        self.deltax = 10
        self.deltay = random.randint(5,15)
      
    def update(self):
    # gestion rebond du troupeau
        if self.rect.left <= 0:
            self.deltax = - self.deltax
        if self.rect.right >= largeur:
            self.deltax = - self.deltax
        if self.rect.top <= 0:
            self.deltay = - self.deltay
        if self.rect.bottom >= hauteur:
            self.deltay = - self.deltay
            
         # déplacement des proies
        self.rect.x +=self.deltax
        self.rect.y +=self.deltay
#------------------------
class Predateurs(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("images_sons/lion.png").convert_alpha()
        self.image.set_colorkey((255, 255, 255))
        self.rect = self.image.get_rect()

self.image.set_colorkey((255, 255, 255)) : les images "gazelle.png" et "lion.png" n'ont pas un fond transparent mais un fond blanc. Cette instruction convertit en transparent le fond blanc.
self.deltay = random.randint(5,15) : le déplacement sur l'axe des X est aléatoire : entre 5 et 15.

Création du troupeau de proies

col,lig = 50,40
for i in  range(1,5) :
    for j in range(1,6) :
       proie = Proies()
       proie.rect.x = col
       proie.rect.y = lig
       troupeau.add(proie)
       tous.add(proie)
       col+=50
    col = 50
    lig += 60
# -----------------

Il faut deux groupes de sprites : "troupeau" & "tous".

Autres instructions avant la boucle de jeu

debut_jeu = pygame.time.get_ticks()
encore = True

debut_jeu = pygame.time.get_ticks() : récupère le temps écoulé

Déplacement du prédateur

# deplacement du predateur
    touches = pygame.key.get_pressed()
    if predateur.rect.left >=0 : 
        if touches[pygame.K_LEFT]:
            predateur.rect.x -= 10
    if predateur.rect.right <= largeur :
        if touches[pygame.K_RIGHT]:
            predateur.rect.x += 10
    if predateur.rect.top >= 0 :
        if touches[pygame.K_UP]:
            predateur.rect.y -= 10
    if predateur.rect.bottom <= hauteur :
        if touches[pygame.K_DOWN]:
            predateur.rect.y += 10

Le lion ne peut sortir de la fenêtre de jeu.
Remarque : on utilise dans les instructions des propriétés d'un objet rect : left, right, top, bottom, x, y ...

Gestion des collisions

    if pygame.sprite.spritecollide(predateur,troupeau,True):
        print("une gazelle dévorée")

Autres instuctions de la boucle de jeu

	if len(troupeau) ==0 :
        print("Gagné ; toutes les gazelles dévorées ! ")
        encore = False
	# effacer fenetre précédente
    fenetre.fill('wheat')
    # déplacement troupeau
    troupeau.update()
    # affichage des sprites
    tous.draw(fenetre)
    # actualisation 
    pygame.display.flip()
    frequence.tick(8)

La méthode update() : déplacement du troupeau
La méthode draw() s'applique au groupe "tous" donc à tous les sprites (gazelles et lion) sont dessinés.

Le bloc à la sortie de la boucle de jeu

fin_jeu = pygame.time.get_ticks()
duree = (fin_jeu - debut_jeu) //1000
print(f" temps pour tuer toutes les gazelles : {duree} secondes")
time.sleep(3) # pause pour lire le score
pygame.quit()

duree = (fin_jeu - debut_jeu) //1000 : calcul de la durée du jeu en secondes

Déplacer une balle avec la souris

Il peut être utile de déplacer un sprite non pas via les touches de direction mais via la souris.

Principes du déplacement de la souris

Dans un chapitre précédent et concernant la gestion de la souris nous avons vu les événements MOUSEBUTTONUP et MOUSEBUTTONDOWN.
Je rappelle que le premier est appelé dès qu’on appuie sur un bouton et le deuxième quand on relâche un bouton.
L'attribut button permet de préciser sur quel bouton l'appui (ou le relachement a été effectué. Un appui sur le bouton gauche de la souris retourne 1.
Dans ce paragraphe je vais utilisé un troisième événement : MOUSEMOTION qui se produit lorsqu'on déplace la souris (et uniquement lors de son déplacement).

Le script

Dans ce script je peux déplacer la balle et par ailleurs je vous indique deux solutions pour obtenir la position du pointeur de souris dans la fenêtre : event.pos() OU pygame.mouse.get()
Dans les deux cas l'info est affichée sous forme d'un tuple de deux valeurs.

Le rendu

pygame - déplacer un sprite avec la souris

"Drag and drop" ou "glisser-déposer"

Dans une chapitre précédent je vous ai montré comment créer à la volée des objets de type rect.
Voir le script "rect_a_la_volee.py" dans "pygame3_prog".
Cette fois nous allons voir comment déplacer ces objets un par un avec la souris.

Le code

# pygame_drag_drop.py
# création de plusieurs rectangles 
# chaque rectangle peut être déplacé via la souris
import pygame
from pygame.locals import *
import random
pygame.init()

largeur = 600
hauteur = 600

fenetre = pygame.display.set_mode((largeur, hauteur))
pygame.display.set_caption("objets rect à la pelle")

boite_active = None
boites =[]   
for i in range(7) :
    x = random.randint(50,largeur -70)
    y =  random.randint(50,hauteur -70)
    w = random.randint(30,70)
    h = random.randint(30,70)
    boite =pygame.Rect(x,y,w,h)
    boites.append(boite)

continuer = True
 #boucle infinie
while continuer :
    for event in pygame.event.get():
        if event.type == QUIT:
            continuer = False
        if event.type == MOUSEBUTTONDOWN and event.button == 1 :
              for num, boite in enumerate(boites) :
                  if boite.collidepoint(event.pos) :
                      boite_active = num
        if event.type == MOUSEMOTION :
            if boite_active != None :
                boites[boite_active].move_ip(event.rel)
        if event.type   == MOUSEBUTTONUP and event.button == 1 :
            boite_active = None
            
    fenetre.fill("white")
    for boite in boites :
        pygame.draw.rect(fenetre, "purple", boite)
    pygame.display.update()
 # fin boucle infinie
pygame.quit()

Ajouts par rapport à "rect_a_la_volee.py"

Ajout avant la boucle de jeu

Dans la boucle de jeu

Dans la boucle de jeu il faut rajouter le code pour le "glisser-déposer".

		if event.type == MOUSEBUTTONDOWN and event.button == 1 :
              for num, boite in enumerate(boites) :
                  if boite.collidepoint(event.pos) :
                      boite_active = num
        if event.type == MOUSEMOTION :
            if boite_active != None :
                boites[boite_active].move_ip(event.rel)
        if event.type   == MOUSEBUTTONUP and event.button == 1 :
            boite_active = None

Étude de ce code compliqué ...

Ce code doit être inséré dans la boucle for event in pygame.event.get().
Notez que nous utilisons tous les évènements de la souris. Par ailleurs nous n'avons pas besoin de préfixer les constantes avec "pygame." car le programme comporte l'instruction from pygame.locals import *

Dans ce code il y a une boucle bizarre : for num, boite in enumerate(boites)
Cette structure permet de parcourir une structure itérable mais de récupérer non seulement l'élément de la liste mais aussi son index.

Dans cette boucle il y a un test :
if boite.collidepoint(event.pos) : teste si le pointeur de souris est dans un des rectangles.
Donc la variable boite_active récupère l'index de la boite survolée par la souris :boite_active = num
boites[boite_active].move_ip(event.rel) : déplacement du rectangle sélectionné par la souris
boite_active = None : sur relachement du bouton gauche de la souris on remet à None la variable ; il n'y a plus de boite sélectionnée ; vous pouvez en sélectionner une autre pour la déplacer à son tour.

Le rendu

Situation au départ

pygame - drag and drop

Les rectangles sont éparpillés suite à leur génération aléatoire.

Situation à l'arrivée

pygame - drag and drop

Grâce à des "glisser-déposer" successifs j'ai regroupé les rectangles en un grand carré.