Projet 0 : Découverte
Découverte de l'utilisation du module pgzrun
Pour ce projet, vous aurez au préalable :
installé le module pgzero dans Thonny
créé un dossier : projet0
ce dossier contient deux sous-dossiers (images et sounds) et un fichier
projet0.py
créé avec thonnytéléchargé le pack d'images [zip][1] qui contient des images pour notre projet que vous décompresserez.
Récupérez dans le pack d'images, l'image p3_front.png
se trouvant dans le dossier alien3 du dossier player et mettez-là dans le dossier images de votre projet
Le programme de base
Le programme de base
Le programme suivant affiche notre alien dans une fenêtre de 800 x 600 pixels
Remarque :
Le code est commenté ( le texte se trouvant après un # est du commentaire)
import pgzrun # on importe le module pgzrun
WIDTH = 800 # variable qui définit la largeur de la fenêtre
HEIGHT = 600 # pour la hauteur de la fenêtre
alien = Actor('p3_front.png') # création de l'objet alien
alien.x = 100 # abscisse de la position de l'alien
alien.y = 56 # ordonnée de l'alien
def draw(): # fonction qui s'exécute 60 fois par seconde
alien.draw() # on affiche l'alien
pgzrun.go() # exécution ( doit toujours se trouver en dernière ligne du programme )
Remarque : Constantes et variables globales
Il est d'usage d'écrire les constantes en majuscules et les variables en minuscule. Cependant, Python ne fera pas de différence entre les deux (dans certains langages, il existe un type de variables constantes).
Remarquez que WIDTH et HEIGHT sont des noms reconnus par Pygame Zero, ce ne serait pas le cas de LARGEUR et HAUTEUR...
Les variables définies en dehors des fonctions sont dîtes globales. Leur utilisation doit être limitée mais dans les projets un peu complexes elles évitent de devoir passer ces valeurs en paramètre de chaque fonction. Un cas de figure fréquent est celui des constantes, qui par définition, n'ont pas à être modifiées par les fonctions !
Mouvement de l'alien
On va faire en sorte que l'alien se déplace dans la fenêtre en utilisant les flèches du clavier
Ajoutez cette fonction et terminez les commentaires
def mouvement_alien():
if keyboard.left: # si on appuie sur la flêche gauche du clavier
alien.x = alien.x - 5 # on recule de 5 pixels
if keyboard.right:
alien.x = alien.x + 5
if keyboard.up:
alien.y = alien.y - 5
if keyboard.down:
alien.y = alien.y + 5
Puis ajoutez la fonction update() qui comme son nom l'indique sert à mettre à jour les positions de l'alien
def update():
mouvement_alien()
Méthode : Notre alien laisse des traces...
Pour éviter cela , il suffit d'effacer l'écran à chaque tour de la fonction draw()
Complétez la fonction draw()
def draw(): # fonction qui s'exécute 60 fois par seconde
screen.clear() # on efface l'écran
alien.draw() # on affiche l'alien
Méthode : Notre alien sort de l'écran...
Pour que l'alien ne puisse pas sortir de l'écran on va compléter la fonction mouvement_alien()
en précisant que si on arrive sur un bord alors on ne peux pas le traverser.
Remarques :
Les coordonnées de l'alien (alien.x
et alien.y
) sont celles du centre de l'image.
Les instructions alien.width
et alien.height
donnent accès aux dimensions de l'image.
donc :
Si
alien.x
est inférieur àalien.width/2
alors l'image est sur le bord gauche , il suffit alors de repositionner l'alien.x
àalien.width/2
( il ne bouge plus)Si
alien.x
est supérieur àWIDTH - alien.width/2
alien.x
àWIDTH - alien.width/2
( il ne bouge plus)de même pour les bords supérieur et inférieur
Voilà le code à mettre dans la fonction mouvement_alien()
# ne pas sortir de la fenêtre
if alien.x < alien.width/2:
alien.x = alien.width/2
if alien.x > WIDTH - alien.width/2:
alien.x = WIDTH - alien.width/2
if alien.y < alien.height/2:
alien.y = alien.height/2
if alien.y > HEIGHT - alien.height/2:
alien.y = HEIGHT - alien.height/2
Ajoutons des gemmes à attraper
Méthode : faisons simple...
Dans le pack images récupérez une image de gemme, par exemple gemgreen.png
et placez-là dans votre dossier images.
Nous allons faire en sorte que la gemme apparaisse depuis le bord supérieur de manière aléatoire et tombe vers le bas pour réapparaître depuis le bord supérieur dès qu'elle a franchit le bord inférieur.
En python, on utilise le module random
pour pouvoir utiliser la méthode random.randint(a,b)
qui permet de choisir aléatoirement un entier entre a et b.
Voici les lignes de codes à rajouter dans notre programme
import pgzrun # on importe le module pgzrun
import random # on importe le module random
alien.y = 56 # ordonnée de l'alien
gem = Actor('gemgreen.png') # création de l'objet gem
gem.x = random.randint(20,780)
gem.y = 0
def mouvement_gemme(): # fonction pour le mouvement de gem
gem.y = gem.y + 4
if gem.y > 600: # si gem sort de l'écran
gem.x = random.randint(20,780)
gem.y = 0
def update():
mouvement_alien() # mise à jour de alien
mouvement_gemme() # mise à jour de gem
def draw(): # fonction qui s'exécute 60 fois par seconde
screen.clear() # on efface l'écran
alien.draw() # on affiche l'alien
gem.draw() # on affiche la gemme
Gestion des collisions
Avec le module pgzrun, la gestion des collisions se fait avec la méthode :
if gem.colliderect(ship):
ouif ship.colliderect(gem): (les deux ont le même effet)
Donc s'il y a collision, on fait repartir la gemme depuis une position aléatoire du bord supérieur.
Modifiez la fonction mouvement_gemme()
comme suit :
def mouvement_gemme(): # fonction pour le mouvement de gem
gem.y = gem.y + 4
if gem.y > 600:
gem.x = random.randint(20,780)
gem.y = 0
if gem.colliderect(alien): # collision
gem.x = random.randint(20,780)
gem.y = 0
Ajoutons un score et un Game Over
Dans un premier temps il faut créer une variable globale
score
et l'initialiser à 0
Puis on incrémente de 1 cette variable à chaque fois qu'une collision est détectée :
score = score + 1
Et on affiche le score dans la fenêtre :
screen.draw.text('Score: ' + str(score), (15,10), color=(255,255,255), fontsize=30) (à écrire dans la fonction draw() )
Cette dernière instruction dit : on affiche le texte score suivit du score aux coordonnées (15,10) en blanc avec une taille de police de 30/
L'instruction str(score)
permet de transformer en chaîne de caractère le score .
Méthode : les variables score et game_over sont globales...
la variable score est définie en début de programme et est par ce fait globale, si on souhaite la modifier dans la fonction mouvement_gemme(),
il faut le préciser, en rajoutant l'instruction global score
dans cette fonction.
voici les modification à apporter à notre programme :
score = 0 # création de la variable score
def mouvement_gemme(): # fonction pour le mouvement de gem
global score # on précise que score va être modifiée dans la fonction
gem.y = gem.y + 4
if gem.y > 600:
gem.x = random.randint(20,780)
gem.y = 0
if gem.colliderect(alien): # collision
gem.x = random.randint(20,780)
gem.y = 0
score = score + 1 # incrémentation du score
def draw(): # fonction qui s'exécute 60 fois par seconde
screen.clear() # on efface l'écran
alien.draw() # on affiche l'alien
gem.draw() # on affiche la gemme
screen.draw.text('Score: ' + str(score), (15,10), color=(255,255,255), fontsize=30) # affichage du score
Game Over....
On doit pouvoir perdre dans un jeu...
Disons que si on laisse passer une gemme alors on a perdu...
On commence par créer une variable game_over
initialisée à False
( game_over
est donc une variable booléenne globale qui ne peut avoir que deux valeur True
ou False
).
Si on souhaite la modifier dans la fonction mouvement_gemme()
, comme pour la variable score
il faudra le préciser
L'idée est donc la suivante :
si game_over vaut False, le jeu continue sinon il s'arrête et on affiche GAME OVER et le score
Voici les modifications à apporter
score = 0
game_over = False
def mouvement_gemme(): # fonction pour le mouvement de gem
global score,game_over
gem.y = gem.y + 4
if gem.y > 600:
game_over = True
if gem.colliderect(alien): # collision
gem.x = random.randint(20,780)
gem.y = 0
score = score + 1
def draw(): # fonction qui s'exécute 60 fois par seconde
screen.clear() # on efface l'écran
if game_over == False:
alien.draw() # on affiche l'alien
gem.draw() # on affiche la gemme
screen.draw.text('Score: ' + str(score), (15,10), color=(255,255,255), fontsize=30)
else:
screen.draw.text('Game Over', (360, 300), color=(255,255,255), fontsize=60)
screen.draw.text('Final Score: ' + str(score), (360, 350), color=(255,255,255), fontsize=60)
Complément : Ajoutons un sons lors des collisions
Dans le dossier sounds ajouter le son contenu dans ce fichier [zip]que vous aurez au préalable téléchargé de décompressé
puis modifiez le programme comme suit :
def mouvement_gemme(): # fonction pour le mouvement de gem
global score,game_over
gem.y = gem.y + 4
if gem.y > 600:
game_over = True
if gem.colliderect(alien): # collision
gem.x = random.randint(20,780)
gem.y = 0
score = score + 1
sounds.boing.play() # jouer le son
Vous trouverez sur internet des sons gratuit et libre de droit( par exemple lesanotheque.org )
Notez que l'on peut charger des sons au format .wav et .ogg
Le format .wav est adapté aux petit effet sonores
Le format .ogg est un format compressé qui convient mieux à de la musique
De plus si notre son se nomme boing :
sounds.boing.play() : joue le son
sounds.boing.play(n) : joue le son n fois
sounds.boing.play(-1) : joue le son indéfiniment
sounds.boing.stop() : stoppe le son
Complément : Rendre le jeu plus difficile...
On peut modifier la vitesse des gemmes en fonction du score, en remplaçant
gem.y = gem.y + 4
par
gem.y = gem.y + 4 + score / 5
Complément : Et....
On peut ajouter d'autres gemmes de couleurs différentes qui rapporte plus de points
On peut créer un système de vie ( le joueur à au début 5 vies...)
Laissez libre cours à votre imagination