Les tirs sont destinés à abattre des ennemis, il faut donc d'abord les créer dans le jeu !
Les images sont affichées à l’écran à raison de 30 frames ( = images ) par seconde ( ceci est modifiable lors de la création de la fenêtre du jeu ).
L’attribut frame_count du module Pyxel comptabilise le nombre d’images affichées depuis le début du jeu.
Ainsi, pour créer un ennemi toutes les secondes par exemple, on vérifie que le nombres d’images est un multiple de 30 :
La création elle-même des ennemis repose sur le même principe que celui des tirs ( utilisation d'une liste liste_ennemis ), mais on utilise la fonction randint()
du module random
pour les créer de façon aléatoire selon l’axe des x.
Cette création pourra se faire directement dans la fonction update()
.
Compléter le code du script précédent en y ajoutant la création aléatoire d'ennemis toutes les secondes :
randint()
du module random
! ), et un y
égal à 0.ennemi_bouge()
et ennemi_draw()
qui géreront le déplacement des ennemis, et leur suppression de la liste liste_ennemis
lorsqu'il arriveront en bas de la fenêtre.update()
et draw()
pour y inclure la création et la gestion du mouvement des ennemis.Lorsqu'un des tirs touche un des ennemis, il faut faire disparaître les deux.
Deux problèmes se posent donc :
C'est donc deux boucles imbriquées de parcours de listes qu'il faudra utiliser.
Pour le cas de la collision d’un tir avec un ennemi, trois conditions sur les coordonnées du tir et de l'ennemi doivent être vérifiées simultanément :
update()
avec le code correspondant à la détection d'une collision tir/ennemi :Dans ce cas, il suffit de parcourir la liste liste_ennemis, et de détecter la collision entre chacun de ses éléments et le vaisseau ( plus besoin de boucles imbriquées ).
Par contre, les conditions à vérifier lorsqu'il y a collisions sont un peu plus délicates, car plusieurs situations peuvent se présenter.
Ne considérons pour l'instant que les conditions à vérifier sur l'axe des x; les deux situations limites pour lesquelles il peut y avoir collision sont :
xe - 8 <= xv <= xe + 8
Par un raisonnement similaire sur l'axe des y, on constaterait qu'il y a collision si : ye - 8 <= yv <= ye + 8
Il y a donc 4 conditions à vérifier simultanément pour détecter une collision entre le vaisseau et un ennemi.
Bien entendu, ces relations sont à adapter au cas où les deux acteurs n'ont pas la même taille...
Compléter la fonction update()
du script pour gérer la collision entre un ennemi et le vaisseau.
On pourra éventuellement gérer un système de vies pour le vaisseau, décrémentées lors d'une collision avec un ennemi; dans la fonction draw()
, on pourra alors n'afficher les acteurs que
si le nombre de vies est supérieur à 0, et sinon, afficher "GAME OVER" et le score ( méthode pyxel.text()
de Pyxel ).
Remarque : le jeu continue cependant à "tourner"; pour quitter complètement une application Pyxel, utiliser la méthode pyxel.quit()
.
Raffinement supplémentaire : rajouter des explosions lors de la destruction d'un ennemi.
Ces explosions peuvent être simplement représentées par quelques cercles de rayon croissant ( 5 par exemple dont le rayon va de 1 à 5 pixels ) qui se "propagent" depuis l'ancienne position de l'ennemi.
La gestion des explosions peut se faire sur le même principe que les tirs et les ennemis, à savoir utiliser une liste liste_explosions, dans laquelle on ajoutera/supprimera au besoin des éléments.
Cependant, en plus des coordonnées de "départ" de l'explosion ( qui seront bien entendu égales, lors de la création de l'explosion, au milieu de l'ancienne position de l'ennemi ), il faut prévoir un troisième élément, qui indiquera à quel "stade" l'explosion est, en stockant par exemple son rayon actuel; la valeur de cet élément sera incrémenté à chaque frame, et lorsqu'il sera devenu égal au rayon du plus grand cercle, l'explosion sera supprimée de la liste.
Écrire les fonctions bouge_explosion(explosion)
et affiche_explosion(explosion)
, qui seront appelées respectivement depuis les fonctions update()
et draw()
pour gérer les explosions.
La fonction bouge_explosion()
gérera également le cas où l'explosion a atteint son "maximum" et où il faut la supprimer de la liste.
Vous trouverez ici le code complet de cette première partie du tutoriel.