Projet 2 : Dodge the Creep
Préparation
Récupérez le fichier projet2.zip
qui contient ce qu'il faut pour notre programme
Décompressez-le dans vos documents
Méthode : Le background
Notre fond d'écran sera l'image water.png
du dossier images qui a pour dimension 800x600 pixels (notre taille de fenêtre)
le code ci-dessous
import pgzrun
from pgzhelper import *
WIDTH = 800
HEIGHT = 600
background = Actor('water') # la variable background contient l'image
def draw():
background.draw() # on affiche le fond
pgzrun.go() # doit toujours être la dernière ligne
Méthode : Le player
On crée le player en début de programme
On crée une liste d'images pour simuler la marche
On définit la position initiale du player
# création du player
player = Actor('p1_front')
# création d'une liste d'images
player.images = ['p1_walk01', 'p1_walk02', 'p1_walk03', 'p1_walk04', 'p1_walk05', 'p1_walk06', 'p1_walk07', 'p1_walk08', 'p1_walk09', 'p1_walk10','p1_walk11']
# position du player
player.x = 400
player.y = 300
On dessine le player dans la fonction draw()
def draw():
background.draw() # on affiche le fond
player.draw() # affichage du player
Méthode : Déplacement du player
On crée une fonction mouvement__player()
qui gérera les déplacements du player
def mouvement_player():
# mouvement du player avec les flèches du clavier
if keyboard.up:
player.y -= 5
player.next_image()
if keyboard.down:
player.y += 5
player.next_image()
if keyboard.left:
player.x -= 5
player.next_image()
if keyboard.right:
player.x += 5
player.next_image()
Et on met à jour cette fonction dans une fonction update()
def update():
mouvement_player() # mise à jour du player
Pour empêcher que notre player ne sorte de la fenêtre on ajoute à la fonction mouvement_player()
le code suivant :
# pour empêcher le player de sortir de la fenêtre
if player.x < player.width/2:
player.x = player.width/2
if player.x > WIDTH - player.width/2:
player.x = WIDTH - player.width/2
if player.y < player.height/2:
player.y = player.height/2
if player.y > HEIGHT - player.height/2:
player.y = HEIGHT - player.height/2
Méthode : Ennemis (partie 1)
Dans cette partie nous allons :
créer une liste vide pour contenir les ennemis
faire en sorte que les ennemis arrivent du côté droit de la fenêtre et le traverse vers la gauche
éliminer les ennemis lorsqu'ils traversent le côté gauche de la fenêtre
faire afficher les ennemis
Pour cela on crée la liste ennemis
en début de programme et on crée deux fonctions create_enemy()
et mouvement enemy()
que l'on appellera dans la fonction update()
et enfin on fera afficher les ennemis dans le fonction draw()
De plus on prendras le soins d'écrire en début de programme qu l'on importe la méthode randint
du module random
( from random import randint
)
# les ennemis
ennemis = []
def create_enemy():
if randint(0,60) == 0: # une chance sur 61
enemy = Actor('worm.png') # création de l'ennemi
enemy.images = ['worm','worm_walk'] # une liste d'images pour le mouvement
enemy.y = randint(0,600) # ordonnée aléatoire entre 0 et 600
enemy.x = 850 # abscisse en dehors de la fenêtre à droite
ennemis.append(enemy) # on l'ajoute à la liste
def mouvement_enemy():
for enemy in ennemis: # pour chaque ennemi
enemy.x = enemy.x - 3 # on décrémente son abscisse
enemy.next_image() # changement d'image
for enemy in ennemis:
if enemy.x < -50: # s'il sort à gauche
ennemis.remove(enemy) # on l'élimine de la liste
Dans les fonctions draw()
et update()
:
def update():
mouvement_player() # mise à jour du player
create_enemy() # on crée les ennemis
mouvement_enemy() # on met à jour leur mouvement
def draw():
background.draw() # on affiche le fond
player.draw() # affichage du player
for enemy in ennemis: # on affiche les ennemis
enemy.draw()
Méthode : Ennemis (partie 2)
Nos ennemis arrivent tous par la gauche...
Nous allons faire en sorte que certains arrivent par la gauche et d'autres par la droite.
Pour cela lors de la création de l'ennemi, on lui affectera un côté (side) qui vaut 1 si il doit arriver par la gauche et 2 si il doit arriver par la droite.
De plus avec pygame zero, on peut préciser l'angle de rotation de l'image (0 pour pas de rotation et 180 pour une rotation de 180° c.à.d : une symétrie de l'image)
Modifiez votre programme comme suit
def create_enemy():
if randint(0,60) == 0:
enemy = Actor('worm.png')
enemy.images = ['worm','worm_walk']
side = randint(1,2) # on choisit 1 ou 2
if side == 1: # ceux-là arriveront par la gauche
enemy.y = randint(0,600)
enemy.x = 850
enemy.angle = 0
elif side == 2: # et ceux-là par la droite
enemy.y = randint(0,600)
enemy.x = -50
enemy.angle = 180 # l'image sera inversée
ennemis.append(enemy)
def mouvement_enemy():
for enemy in ennemis:
if enemy.angle == 0: # ceux qui arrivent par la gauche
enemy.x = enemy.x - 3
enemy.next_image()
elif enemy.angle == 180: # ceux qui arrivent par la droite
enemy.x = enemy.x + 3
enemy.next_image()
for enemy in ennemis:
if enemy.x < -50 or enemy.x > 850: # ceux qui sortent de la fenêtre
ennemis.remove(enemy)
Méthode : Ennemis (partie 3)
Faites en sorte que les ennemis arrivent également par le haut et le bas.
les angles à utiliser sont 270 pour le bas et 90 pour le haut.
side devra prendre 4 valeurs possibles (1 pour la gauche, 2 pour la droite et 3 ou 4 pour le bas et haut)
Si vous avez réussi vous devriez voir cela
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger le média.
Méthode : Les collisions...
Dans ce jeu on perd si le joueur entre en collision avec un ennemi.
On crée donc une variable game_over
initialisée à False
, elle sera mise à True
si une collision est détectée, sinon le jeu continue.
Pour les collisions, on dispose d'une méthode
player.collidelist(ennemis)
, qui renvoie l'indice de l'ennemi entré en collision avec le player et -1 sinon
Il faudra penser également à rajouter global game_over
dans la fonction où cette variable sera modifiée, car il s'agit d'une variable globale
À faire :
créez le variable game_over initialisée à False
trouvez l'endroit approprié pour mettre le code suivant ( n'oubliez pas le
global game_over
)
if player.collidelist(ennemis) != -1:
game_over = True
Modifier la fonction draw()
comme suit
def draw():
if game_over: # si elle est à True ( cette instruction est équivalente à if game_over == True)
screen.clear() # on efface l'écran
screen.draw.text('Game Over', (350,270), color=(255,255,255), fontsize=30) # on affiche Game Over
else:
background.draw()
player.draw()
for enemy in ennemis:
enemy.draw()
Méthode : Un score...
Nous dirons que l'on gagne 1 point par seconde de survie...
En initialisant une variable globale score
à 0 et comme la fonction update()
s'exécute 60 fois par seconde, il suffira d'ajouter 1/60
à score
dans cette fonction.
Réaliser ces changements... ne pas oublier global score...
Voilà les modifications à apporter à la fonction draw()
def draw():
if game_over:
screen.clear()
screen.draw.text('Game Over', (350,270), color=(255,255,255), fontsize=30)
screen.draw.text('Score: ' + str(round(score)), (350,330), color=(255,255,255), fontsize=30)
else:
background.draw()
player.draw()
for enemy in ennemis:
enemy.draw()
screen.draw.text('Score: ' + str(round(score)), (15,10), color=(255,255,255), fontsize=30)
Complément : Améliorations...
Comme vous l'aurez constaté le score continue d'augmenter après un game over, corrigez cela.
On peut ajouter une musique pour le jeu , le dossier sounds contient des sons et musique.
Pour une musique d'ambiance, écrire le code suivant en dehors des fonctions
sounds.sneakingaround.play(-1)
Le code ci-dessous permet de faire jouer un son lors du déplacement du joueur
def mouvement_player():
# mouvement du player avec les flèches du clavier
play_walking_sound = False # initialisation
if keyboard.up:
player.y -= 5
play_walking_sound = True
if keyboard.down:
player.y += 5
play_walking_sound = True
if keyboard.left:
player.x -= 5
play_walking_sound = True
if keyboard.right:
player.x += 5
play_walking_sound = True
#### on joue un sons lors du déplacement du joueur
if play_walking_sound:
if sounds.footsteps.get_num_channels() == 0:
sounds.footsteps.play()
On peut aussi ...
Augmenter le nombre d'ennemis en fonction du temps qui passe..
faire en sorte que les ennemis aient des vitesse différente..
Faire arrêter la musique ou en jouer une autre sur l'écran de game over.. ;
...