Objet : Pokemon

Plonge dans le coding pour créer un monde virtuel et donne vie à tes propres pokémons avec la magie de la programmation orientée objet. 🌟💻🔮

Félicitations pour être arrivée jusqu’ici ! Tu as pu apprendre à faire tes premiers programmes, et à utiliser des types complexes comme les listes.

Nous allons à présent te parler de Programmation Orientée Objet (POO), ou plus simplement d’objets et de classes.

Et nous allons introduire ce sujet avec les très célèbres Pokémon !

Le but de ce TP sera de créer ton propre mini jeu Pokémon.

Pourquoi on a besoin de programmation objet pour notre jeu ?

Tout d’abord, réfléchissons à ce que nous voulons mettre dans un jeu Pokémon.

Nous aurons besoin :

  • d’avoir plusieurs Pokémon,
  • de leur donner des noms,
  • nous voulons également les capturer,
  • s’affronter avec les autres dresseurs,
  • etc

Pour pouvoir faire tout ça, nous allons avoir besoin de définir une manière de représenter un Pokémon.

Pika !

Pika !

Comment définir un Pokémon ? Qu’est ce qui le caractérise ?

Nous pouvons donner un nom à un Pokémon, pour qu’il soit facilement reconnaissable. Il aura également un nombre de points de vie, et un nombre de points d’attaque.

Pour faire simple, on va se limiter à ces caractéristiques dans ce mini jeu. Vous trouverez ici la liste des caractéristiques du jeu original.

Pour résumer, pour chaque Pokémon que nous utiliserons dans notre jeu, il faut qu’on définisse 3 variables (nom, points de vie, attaque). Facilement faisable si nous avons 1, 2, voire 3 Pokémon, mais ensuite ça va devenir très dur de s’y retrouver.

Une manière simple en programmation pour ce genre de problèmes est la programmation orientée objet. Elle utilise la notion d’objet qui rassemble variables et opérations.

Premier objet

Un objet est assimilé à une variable et le type d’un objet est appelé classe.

Définir une classe revient à créer un nouveau type de variable.

    
1
2
3
class Pokemon:
    def __init__(self):
        pass
4
pokemon1 = Pokemon()
Créons la classe Pokemon
pokemon1 est un objet de la classe Pokemon
Appuie sur Run pour lancer le code :

        

    

Grâce à ce petit bout de code, nous avons créé notre première classe et notre premier objet !

Une méthode

1
2
3
class Pokemon:
    def __init__(self):
        pass

La fonction __init__() est définie à l’intérieur de la classe Pokemon. On le voit grâce à l’indentation avant le mot-clé def (qui définit une fonction), sous la définition de la classe Pokemon.

__init__() est donc une méthode.

Voici d’autres exemples de méthodes :

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

Paramètres d’une méthode

Il est possible d’ajouter autant de paramètres que l’on souhaite à une méthode, tout comme on le ferait pour une fonction :

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

Constructeur d’un objet

Nous avons dit précédemment que __init__() était une méthode, c’est même une méthode particulière en Python.

La méthode __init__() est la méthode constructeur des objets de la classe.

Cette méthode peut également prendre plusieurs paramètres.

C’est la fonction appelée par Python lorsqu’on écrit toto = Toto():

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

Mais qu’est ce que self en paramètre des méthodes ?

Le mot-clé self est toujours le 1er paramètre d’une méthode.

Il permet de représenter l’objet, pour l’utiliser à l’intérieur de la méthode.

On peut l’utiliser notamment pour définir les attributs d’un objet.

Les attributs d’un objet

Un attribut est une variable contenue dans un objet.

L’accès à un attribut se fait depuis l’objet.

Au lieu de définir plusieurs variables à différents endroits, on les stocke toutes dans un objet :

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

Un attribut peut être récupéré et modifié par tout élément ayant accès à l’objet dans lequel il est contenu.

Si on reprend une méthode, elle peut y accéder avec self :

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

Créons un Pokémon !

Ayant appris à créer un objet, passons à la pratique !

Crée un Pokémon, avec :

  • un surnom,
  • un nombre de points de vie,
  • et une puissance d’attaque,

donnés dans le constructeur (__init__()).

Et affiche le nom du Pokémon créé !

Pokemon

Grâce à notre nouvelle classe Pokemon, nous pouvons commencer à jouer avec eux !

Crée un premier Pokemon, pourquoi pas Pikachu ?
Crée un autre Pokemon, un Piafabec ?

Attention, le Piafabec sauvage attaque Pikachu !

À l’attaque !

Pour savoir comment coder l’attaque du Pokemon, il faut d’abord réfléchir à ce qu’on veut.

Qu’est ce que ça signifie qu’un Pokemon attaque un autre Pokemon ?
Qu’avons nous comme paramètre ? Que faut-il regarder ?

On peut dire que lorsqu’un Pokemon attaque un autre, il va retirer des points de vie à celui-ci.

Mais combien ?
On peut par exemple, utiliser le nombre de points de dégâts du Pokemon attaquant.

En mathématiques, ça donnerait

1
2
vie du pokemon attaqué = vie du pokemon avant attaque
                         - points de dégâts du pokemon attaquant

Créons une nouvelle méthode dans la classe Pokemon, qui se nomme attaque.

Cette méthode sera appelée depuis le Pokemon attaquant, sur le Pokemon attaqué. Si on reprend l’exemple donné :

1
piafabec.attaque(pikachu)

Donc la méthode attaque aura un paramètre : le Pokemon attaqué.
Elle sera donc de la forme :

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

Remplace l’instruction pass par le calcul pour retirer des points de vie à pokemon_adverse.

Tu peux également afficher une phrase lorsqu’un Pokemon en attaque un autre, comme :

1
[...] attaque [...].

Combat

Suite à l’attaque du Piafabec, Pikachu replique !
S’en suit un combat entre les 2 Pokemon, jusqu’à ce que l’un d’entre tombe KO.

Créons une fonction combat, en dehors de la classe Pokemon, pour appliquer leur combat.

Cette fonction prend en paramètres les 2 Pokemon.

Un combat est un enchaînement d’attaques de chaque Pokemon l’un vers l’autre, le tout répété tant que les 2 Pokemon sont encore en vie.

Dès qu’un Pokemon est KO, le combat est arrêté, c’est le Pokemon opposant qui gagne le combat.

Si on traduit ces contraintes en programmation, on peut voir la structure d’une boucle, et celle-ci s’arrête lorsqu’un Pokemon est KO, donc lorsque sa vie tombe à 0. Il s’agit d’une boucle while.

Tu peux utiliser l’opérateur logique and pour tester 2 conditions en même temps :

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

L’opérateur and renvoit True si les conditions à droite et à gauche de l’opérateur sont vraies.

Si un des conditions, ou les 2, sont fausses alors l’opérateur and remvoit False.

Enfin, pour donner le résultat du combat, la fonction retournera :

  • 1 si le Pokemon gagnant est le premier donné,
  • 2 si le Pokemon gagnant est le deuxième paramètre de la fonction.

Le mot-clé return permet à une fonction ou à une méthode, de retourner une valeur.

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

On peut également afficher la phrase “[nom du Pokemon] est KO, [nom de l’autre Pokemon] a gagné !” à la fin du combat.

Dresseur

Cher dresseur, le monde Pokémon est vaste. Explore-le, rencontre un maximum de Pokémon et crée la meilleure équipe !

Créons une nouvelle classe Dresseur, pour créer ton personnage dans ce jeu Pokémon.

Chaque dresseur aura un nom et une liste de Pokémon.

Lors de la création d’un dresseur, le nom est donné en paramètre, et la liste est créée vide.

Rappel sur les listes

Une liste vide est définie avec :

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    
Solution
1
2
3
4
class Dresseur:
    def __init__(self, nom):
        self.nom = nom
        self.pokemons = []

Crée à présent le dresseur qui sera ton personnage dans la partie.

Attrapez-les tous !

Que serait un jeu Pokémon, sans capture Pokémon !

Nous allons pour le moment simplifier au maximum la capture.

Créons une nouvelle méthode capture dans la classe Dresseur, qui prend en paramètre le Pokémon à attraper, et qui l’ajoute à la liste de Pokémon du dresseur, sans aucune vérification.

Rappel sur les listes

Pour ajouter un élément à la fin d’une liste :

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

Crée ensuite un Pokémon, qui sera ton premier Pokémon, ton starter !

Tu n’as plus qu’à le capturer.

Un Pokémon sauvage apparaît !

Fort de ton premier Pokémon, tu te sens confiante pour t’aventurer dans les hautes herbes.

Oh ! Un Pokémon sauvage !

Vite, crée une méthode dans la classe Dresseur pour combattre ce Pokémon.

On peut nommer cette méthode combat, qui prend en paramètre le Pokémon adverse.

Nous allons pour le moment nous contenter d’un combat automatique, où le dresseur envoie un à un ses Pokémon lors du combat.

Pour donner un exemple :

Le dresseur a 2 Pokémon, le 1er étant Carapuce, et le 2e étant Salamèche.
Il rencontre un Pokémon sauvage, un Rattata.

  • Le dresseur va envoyer son 1er Pokémon automatiquement pour combattre le Pokémon sauvage. Donc vont d’abord s’affronter Carapuce et Rattata.
  • Si Rattata est mis KO, ça signifie que Carapuce a gagné, ainsi que le dresseur a gagné le combat.
  • Sinon, ça signifie que Carapuce est KO, le dresseur va ainsi envoyer son prochain Pokémon, Salamèche.
    Dans ce cas, si Salamèche gagne, c’est le dresseur qui l’emporte sur le Pokémon sauvage ; sinon, le dresseur n’a plus de Pokémon capable de se battre, c’est le Rattata sauvage qui gagne.

On peut voir dans cette trame que nous répétons l’action de combat de Pokémon tant que le Pokémon sauvage est en vie, et que le dresseur possède encore des Pokémon.

Si on exprime cette trame en utilisant des outils de programmation :

1
2
3
4
5
6
7
8
9
Méthode combat(dresseur, pokemon_sauvage):
    pokemon = 1er pokemon du dresseur
    tant que (pokemon_sauvage est en vie) et (pokemon existe):
        combat(pokemon, pokemon_sauvage)
        pokemon = pokemon suivant du dresseur
    si pokemon_sauvage est en vie:
        pokemon_sauvage a gagné
    sinon:
        dresseur a gagné

Traduisez ce texte pour créer la méthode combat.

Rappel sur les listes

Il est possible de parcourir tous les éléments d’une liste avec une boucle while:

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

Tu peux afficher à la fin de la méthode si le dresseur a gagné ou perdu face au Pokémon sauvage.

Vous n’avez plus de Pokémon en vie, vous avez perdu.
ou
Vous avez battu le Pokémon sauvage. Félicitations !

Go Pikachu !

Nous pouvons à present nous battre contre les Pokémon sauvages. Mais il serait préférable de pouvoir choisir quel Pokémon envoyer combattre, pour ajouter un élément de stratégie à notre jeu.

Créons une nouvelle méthode combat_interactif dans la classe Dresseur, qui prend en paramètre le Pokémon adverse.

Cette méthode aura les mêmes éléments que la méthode précédente.

Le changement principal sera le choix du Pokémon de l’équipe du dresseur qui va combattre.

Pour faciliter le choix du joueur, nous allons lui afficher la liste de ses Pokémon en vie, avec un nombre associé, que le joueur devra par la suite entrer, pour sélectionner le Pokémon.

Pour faciliter l’utilisation de ce nombre, nous allons simplement utiliser l’indice du Pokémon dans l’équipe de Pokémon du dresseur.

Par exemple :

1
2
0 Carapuce
1 Salamèche

Affiche uniquement les Pokemon qui ne sont pas KO.

Après cet affichage, nous allons demander quel Pokémon le dresseur choisit pour combattre le Pokémon sauvage.

Pour cela, nous allons utiliser la fonction input.

Rappel sur input

La fonction input permet de poser une question à l’utilisateur, d’attendre sa réponse, et de la récupérer :

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

Demande à l’utilisateur quel Pokémon il veut envoyer et stocke sa réponse dans une variable.

Attention, la réponse envoyée par input est tout le temps du type string (chaîne de caractères).

Il faut donc transformer le nombre entré en entier, avant de s’en servir.

Pour cela, il suffit d’utiliser int():

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

Il est maintenant possible de récupérer le Pokémon désiré dans l’équipe du dresseur, avec un simple accès à un élément dans la liste, à l’indice donné.

Ensuite, nous pouvons reprendre la méthode précédente pour le combat entre le Pokémon choisi et le Pokémon adverse.

Comme pour la méthode précédente, on envoie un autre Pokémon lorsque celui de l’équipe du dresseur est KO. Nous allons donc retrouver une boucle while, qui demande à chaque fois au dresseur quel Pokémon envoyer.

Le choix du Pokémon étant dépendant du dresseur, nous devons modifier la condition de la boucle pour s’arrêter, nous ne pouvons pas juste regarder si on a fini la liste.

Pour cela, nous pouvons créer une nouvelle variable, qui va compter le nombre de Pokémon en vie du joueur.

Et à chaque fin de combat entre 2 Pokémon, si le Pokémon du dresseur est KO, on peut retirer 1 à cette variable.

Et le combat continue tant que le dresseur a encore au moins 1 Pokémon en vie.

La Team Rocket veut se battre !

Dans les hautes herbes, il y a des Pokemon sauvages mais aussi des Dresseurs qui cherchent à s’affronter.

Et il s’agit même de la team Rocket !

Pour le bien du monde Pokemon, il faut les battre !

Crée une fonction duel qui prend en paramètre 2 dresseurs.

Nous allons créer un combat automatique, où les dresseurs enverront chacun leur premier Pokemon, puis leur second et ainsi de suite, jusqu’à ce qu’un dresseur ait tous ses Pokemon KO.

Pour cela, comme dans la méthode précédente combat de la classe Dresseur où le dresseur affrontait un Pokemon sauvage de manière automatique, nous allons parcourir les listes de Pokemon des dresseurs.

D’abord, les dresseurs envoient chacun leur premier Pokemon.
Ensuite, suite au combat :

  • si le Pokemon KO appartient au 1er dresseur, alors celui-ci envoie son 2e Pokemon pour se battre ; tandis que l’autre dresseur garde le même Pokemon pour combattre,
  • sinon, c’est l’autre dresseur qui envoie son prochain Pokemon. Et ainsi de suite, jusqu’à ce qu’un dresseur n’ait plus de Pokemon.

La boucle va ressembler à ceci :

1
2
3
4
5
6
7
8
poke1 = 0
poke2 = 0
while poke1 < len(dresseur1.pokemons) and poke2 < len(dresseur2.pokemons):
    resultat = combat(pokemon1, pokemon2)
    if resultat == 1: # le 1er Pokemon est gagnant
        poke2 = poke2 + 1 # passe au Pokemon suivant du 2e dresseur
    else:
        poke1 = poke1 + 1

Attention, dans le code donné ci-dessus, pokemon1 et pokemon2 n’existent pas.

À toi de les remplacer par la bonne instruction.

À la fin du combat, tu peux afficher quel dresseur a gagné le combat !

Bienvenue au centre Pokémon

Suite à autant de combats Pokémon, votre équipe peut avoir du mal à continuer.

Créons un centre Pokémon pour les soigner !

Nous allons définir le passage dans un Centre Pokémon comme une simple fonction, visite_PokeCenter().

Pour cette partie, tu auras besoin des fonctions print et input, ainsi que de savoir parcourir une liste.

Dialogue

Tout d’abord, lorsqu’un dresseur entre dans un Centre Pokémon, l’infirmière Joëlle l’acceuille avec le texte :

1
Bienvenue au centre Pokémon. Nous pouvons soigner vos Pokémon.

Puis, l’infirmière propose au dresseur de soigner ses Pokémon :

1
Voulez-vous les soigner ?

Si le dresseur répond “oui” à sa question, l’infirmière demande d’attendre un instant, récupère les Pokémon et les soigne.

En Python, il est possible de comparer des chaînes de caractères entre elles simplement :

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

Soigner les Pokémon

Pour soigner les Pokémon du dresseur, l’infirmière va avoir besoin d’accéder à l’équipe du dresseur.

Pour cela, nous pouvons ajouter un paramètre dresseur à la fonction visite_PokeCenter.

Grace au dresseur, nous pouvons accéder à la liste de Pokémon, avec :

1
dresseur.pokemons

Ainsi, il est possible de changer l’attribut vie de chaque Pokémon de la liste, avec une simple boucle.

Mais quelle est la valeur maximum de la vie de chaque Pokémon ?

Nous avons à présent, aucun moyen de savoir quels étaient les points de vie maximum des Pokémon, valeur qu’ils avaient avant de combattre.

Pour résoudre ce problème, ajoutons un attribut vie_max à la classe Pokemon.

Il sera défini lors de la création d’un Pokémon, avec la même valeur que l’attribut vie.

Mais la valeur vie_max ne sera jamais modifiée lors d’un combat, contrairement à vie. Donc nous pouvons l’utiliser dans la fonction visite_PokeCenter pour remettre vie du Pokémon à sa valeur initiale.

Dialogue de fin

L’infirmière Joëlle, après avoir soigné les Pokémon du dresseur, l’informe que tout s’est bien passé :

1
Merci d'avoir attendu. Vos Pokémon sont en super forme.

Enfin, lorsque le dresseur s’éloigne de l’infirmière, elle l’incite à revenir une prochaine fois :

1
À une prochaine fois peut-être.

Ton jeu est quasi complet ! Félicitations ! 🎉

Nous allons maintenant créer la partie “chef d’orchestre” de notre jeu, l’endroit où le joueur va pouvoir choisir ce qu’il veut faire, la boucle de jeu.

Dresseur et son starter

Premièrement, nous allons pouvoir créer le dresseur du joueur, avec son prénom.

Il nous faut donc :

  • Demander son prénom
  • Créer le dresseur

Avant de lui demander, on peut également commencer le jeu est souhaitant la bienvenue au joueur :

1
Cher nouveau dresseur, bienvenue dans le monde Pokémon !

Ensuite, il va pouvoir choisir son Pokémon de départ, son starter !

Le choix portera uniquement sur le nom du Pokémon. Ses statistiques seront fixes.
On peut par exemple mettre 40 en points de vie et 12 en points de dégats.

Voici un exemple de dialogue pour le choix du starter, tu peux le modifier à ta guise :

1
2
3
Choisis ton Pokémon de départ :
Comment s'appelle-t-il ?
Félicitations pour avoir choisi [...] !

Choisir une action

Après la mise en place du joueur, celui-ci va pouvoir effectuer des actions, comme :

  • aller au centre Pokémon
  • voyager dans les hautes herbes (rencontre avec un Pokémon sauvage ou un Dresseur)

Voici un exemple de dialogue pour le choix des actions :

1
2
Que souhaites-tu faire :
'voyager' ou aller au 'pokecenter' ?

Visite du centre Pokémon

Si la réponse du joueur est “pokecenter”, alors nous pouvons l’emmener au centre Pokémon, en utilisant la fonction visite_PokeCenter.

Voyager

Si le joueur choisit l’action “voyager”, alors celui-ci se balade dans les hautes herbes.

Sur le chemin, il peut croiser un Pokemon sauvage ou un Dresseur ennemi.

Pour choisir entre les 2, nous pouvons utiliser de l’aléatoire.
Générons un nombre aléatoirement entre 1 et 2, si celui-ci est égal à 1, alors le joueur rencontre un Pokemon sauvage, sinon le joueur rencontre un dresseur de la Team Rocket !

Il est très facile de générer un nombre aléatoirement, avec le module random.

Pour créer un nombre aléatoirement compris entre 2 nombres :

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

Pokemon sauvage

Si le joueur rencontre un Pokemon sauvage, plusieurs choix s’offrent à lui :

  • le capturer
  • le combattre
  • fuire

Tout d’abord, créons un Pokemon, celui qui vient d’apparaître devant le joueur.
Par exemple, ce Pokemon peut s’appeler “Rattata”, et avoir 20 points de vie et 8 points de dégâts.

On peut également afficher au joueur quel Pokemon il vient de rencontrer :

1
Un [nom du pokemon] sauvage apparaît !

Ensuite, nous lui demandons ce qu’il veut faire :

1
Souhaites-tu le 'capturer', se 'battre' ou 'fuire' ?

Si le joueur souhaite capturer le Pokemon, on peut simplement appeler la méthode capture de la classe Dresseur avec ce Pokemon.

1
Tu as capturé [nom du pokemon] !

Si le joueur souhaite se battre contre le Pokemon, on peut appeler la méthode combat de la classe Dresseur avec ce Pokemon.

Sinon, le joueur fuit le Pokemon, aucune action n’est faite.

1
Tu as pris la fuite...

Team Rocket

Si le joueur rencontre un dresseur ennemi sur son chemin, celui-ci provient certainement de la Team Rocket !

Créons ce dresseur, et donnons lui de nouveaux Pokemons, disons 2 Pokemons assez faibles : 25 points de vie et 10 points de dégâts.

Ensuite appelons la méthode duel de la classe Dresseur pour le battre !

Après un combat

Le joueur peut se retrouver avec tous ses Pokemon KO suite à un combat, contre un Pokemon sauvage, ou un dresseur de la Team Rocket.

Dans cette éventualité, le joueur doit courir vers le centre Pokemon le plus proche pour les soigner, ce que nous pouvons forcer :

1
Tu cours vers un centre Pokémon pour soigner tes Pokemon.

Ensuite, on appelle la fonction visite_PokeCenter.

Autre

Si le joueur entre un nom d’action différent de ‘voyager’ ou ‘pokecenter’, cette action n’est pas reconnue par notre programme.

Nous pouvons lui signifier avec la phrase :

1
Je n'ai pas compris ce que tu voulais faire.

Une structure conditionnelle nous permet de récupérer tous les autres cas en Python.

Rappelons que :

  • if, signifie “si” en français, et permet de tester une condition, avant de faire des actions
  • else, signifie “sinon” en français, et permet d’exécuter des actions, si la condition du if précédent est fausse
  • elif, est la contraction de else et if, “sinon si” en français, et permet d’exécuter des actions si les conditions précédentes sont fausses et que la condition actuelle est vraie.
Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

En utilisant cette structure pour comparer nos actions, nous pouvons récupérer toutes les actions non reconnues dans la partie else.

Boucle de jeu

Après avoir lié la réponse du joueur aux actions qu’il va effectuer, il ne nous reste plus qu’à faire en sorte que le jeu ne s’arrête pas. Il continue tant que le joueur souhaite jouer.

Pour cela, nous allons créer une boucle de jeu.

Ne connaissant pas le nombre de tours de boucle que le joueur souhaite faire à l’avance, ce sera une boucle while et non une boucle for.

On peut créer une variable en_cours qui décide si le jeu doit continuer, ou s’arrêter.

Elle sera la condition de la boucle while, ainsi les instructions de la boucle se répéterons tant que en_cours vaut True, et la boucle s’arrête lorsque en_cours vaut False.

La variable en_cours est initialisée à True au début du jeu.

Qu’est ce qu’on veut répéter ?

Pour savoir où mettre la boucle, et définir les lignes qui doivent se répéter, nous devons relire notre programme.

Tout d’abord, nous avons créé un dresseur, avec le nom du joueur.
Est ce qu’il faut créer plusieurs dresseurs pour le joueur pendant la partie ?
Non, un seul suffit. Donc cette partie ne sera pas dans la boucle.

Ensuite, nous avons défini le Pokemon de départ du joueur.
Est ce qu’il aura plusieurs Pokemon de départ ?
Non, il peut ensuite en capturer lors de ses voyages. Donc cette partie ne sera pas dans la boucle.

Après, nous demandons au joueur quelle action il souhaite faire (voyage ou centre Pokemon).
Est ce qu’il peut faire plusieurs actions lors du jeu ?
Oui ! Donc nous allons commencer la boucle juste avant de demander l’action que le joueur souhaite faire.

Quitter le jeu

Pour pouvoir quitter le jeu, maintenant que celui-ci se répète, nous pouvons ajouter un nouveau choix d’actions : “quitter”.

Si la réponse du joueur est “quitter”, alors nous pouvons changer la valeur de la variable en_cours, valeur qui va arrêter la boucle.

Bonus

Avec de la couleur !

Pour rendre ton jeu plus agréable à lire et à jouer, tu peux changer la couleur des textes que tu affiches.

Par exemple, lorsque ton Pokemon gagne un combat, on peut afficher la phrase “[…] a gagné !” en bleu, et si c’est le Pokemon adverse qui gagne, on peut l’afficher en rouge.

Ou encore, on peut afficher les phrases de victoire sur un dresseur en vert, de même que le soin de tes Pokemon.

Pour cela, nous allons rajouter un caractère spécial au début de la chaîne de caractères à afficher.

1
2
3
4
5
6
print("\033[0;32m Félicitations !")
print("normal ?")
print("\033[0m Il faut reset la couleur")

print("\033[0;34m Comme ceci \033[0m")
print("ici tout va bien")

Les couleurs ne marchant pas sur notre site, copie colle les lignes ci-dessus et teste les sur ton ordinateurs.

Rappel sur les f-string

Python permet d’utiliser rapidement des variables dans les chaînes de caractères, avec ce qu’on appelle les f-string.

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

Grâce aux f-string, il est possible de sauvegarder ces valeurs spécifiques dans des variables.

1
2
3
4
red = "\033[0;31m"
reset = "\033[0m"

print(f"{red}Bravo!{reset}, vous avez réussi")

Il existe énormément de couleurs disponibles, voici une liste non exhaustive :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
BLACK = "\033[0;30m"
RED = "\033[0;31m"
GREEN = "\033[0;32m"
BROWN = "\033[0;33m"
BLUE = "\033[0;34m"
PURPLE = "\033[0;35m"
CYAN = "\033[0;36m"
GRAY = "\033[0;37m"
MAGENTA = "\033[0;95m"
RESET = "\033[0m"

Voir les stats de ses Pokemons

Il peut être très pratique de connaître les statistiques de tes Pokemon, ne serait ce que pour savoir s’il faut aller les soigner, avant qu’ils ne tombent tous KO.

Pour cela, nous allons ajouter une méthode dans la classe Dresseur, qui peut s’appeller affiche_stats.

Cette méthode pourra parcourir tous les Pokemon du dresseur, et appeler une nouvelle méthode de la classe Pokemon, qui peut s’appeler affiche_infos.

La méthode affiche_infos peut afficher le nom du Pokemon, ainsi que son nombre de points de vie, son nombre de points de dégâts.

Un format possible d’affichage :

1
2
Carapuce
  Vie : 24/24 | Dégâts : 13

Pour pouvoir l’utiliser dans la boucle de jeu, nous pouvons ajouter une action possible, par exemple avec le nom clé “equipe”.
Si le joueur entre “equipe”, on affiche les statistiques des Pokemon du dresseur.

Rencontre avec des Pokemons et Dresseurs aléatoires

Pour ajouter plus de suspense dans ton jeu, tu peux rendre les rencontres avec des Pokemon sauvages ou des dresseurs ennemis plus aléatoires.

Tu peux par exemple, faire en sorte que le nombre de points de vie et nombre de dégâts varient.

Tu peux également rendre le nombre de Pokemon d’un dresseur ennemi aléatoire, potentiellement compris entre 1 et 3.

Tous ces aléatoires portent sur des nombres. On peut donc utiliser la même fonction qu’auparavant :

Appuie sur le bouton Run pour exécuter le code python ci-dessous
Le résultat :

        

    

Veux-tu donner un surnom à ton Pokemon ?

Pour que le dresseur puisse personnaliser son équipe, donnons lui la possibilité de donner des surnoms à ses Pokemon.

Lors de la phase de capture dans la boucle de jeu, demande au dresseur s’il souhaite donner un nom à son nouveau Pokemon !

1
Veux-tu lui donner un nom ? 'oui' / 'non'

Pense à la fonction input !

Si le joueur répond non, nous avons rien à modifier, le dresseur capture le Pokemon directement.

Si le joueur répond oui, nous devons ensuite lui demander quel nom il souhaite donner au Pokemon.
Ensuite, on change le nom de celui-ci.

Il est possible de changer le nom du Pokemon, avant ou après l’appel à la méthode capture.

En effet, l’objet Pokemon sera donné en référence à la fonction capture et dans la liste dresseur.pokemons. Ce qui signifie que le même objet est utilisé à plusieurs endroits, et que s’il est modifié d’un côté, alors il sera aussi modifié de l’autre.

Potion

Lorsque l’on voyage, on peut faire de très longs chemins sans passer devant un centre Pokemon.

Pour revigorer ses Pokemon fatigués, il existe un certain objet, les potion. Celles-ci sont capables de redonner des points de vie à un Pokemon choisi.

Habituellement dans les jeux Pokemon, les potions sont mélangés aux autres objets dans le Sac du dresseur.
Ici, nous allons utiliser qu’un seul type d’objets : les potions, donc nous allons les gérer spécifiquement.

Prenons des potions toutes simples, celle qui donne 20 points de vie à un Pokemon.

Toutes les potions étant les mêmes, nous pouvons gérer nos potions avec un simple entier, qui comptera le nombre de potions que le dresseur possède.

Pour utiliser une potion, nous allons créer la méthode utilise_potion.
La potion s’utilisant sur un Pokemon précis, la méthode prendra un paramètre, qui permet de retrouver le Pokemon en question.
Pour plus de simplicité, ce paramètre sera l’indice du Pokemon choisi dans la liste de Pokemon du dresseur.

À quel moment l’utiliser ?

Tu peux ajouter l’action d’utilisation d’une potion où tu le souhaites.
Nous te conseillons d’ajouter directement l’action à la boucle de jeu, avec le mot-clé “potions”.

Une fois l’action choisie, il faut demander au joueur sur quel Pokemon l’utiliser.

Étapes à réaliser :

  • ajouter un attribut potions, un entier, à la classe Dresseur
  • créer la méthode utilise_potion qui prend en paramètre l’indice d’un Pokemon dans la liste du dresseur, et qui lui ajoute 20 points de vie
  • ajoute l’action dans le jeu, pour pouvoir l’utiliser

Pense à retirer 1 à l’attribut lorsque la méthode utilise_potion est appelée.

Attention à ne pas dépasser le nombre de points de vie maximal des Pokemon.

Attention, lorsque le nombre de potions tombe à 0, il n’est plus possible d’en utiliser.

Le joueur peut commencer la partie avec 2 potions.

Pokemoney

Allons encore plus loin !

Grâce au bonus précédent, nous avons accès à un objet : les potions. Mais celles-ci sont à usage unique, donc rapidement épuisées.

Rajoutons un système d’argent à notre jeu, pour pouvoir en acheter !

L’argent serait possédé par le dresseur, et acquis grâce à ses combats contre d’autres dresseurs.

On peut par exemple donner 200 Pokédollar (monnaie des jeux Pokémon) au joueur au début de sa partie.

Ensuite, à chaque dresseur vaincu, on ajouterait 100 Pokédollar.

Attention, on retire également de l’argent lorsque le joueur perd un combat !

Enfin, le joueur doit pouvoir choisir d’aller au PokeShop, pour acheter des potions. Il nous faut donc rajouter une action à notre boucle de jeu, qui appelerait une nouvelle fonction : visite_PokeShop.

Cette fonction ressemblerait à la fonction visite_PokeCenter dans sa forme :

  • Souhaiter la bienvenue au dresseur
  • Demander le nombre de potions que le joueur souhaites acheter en affichant le prix
  • Remercier le joueur

Il faudra vérifier que le joueur possède assez d’argent pour acheter les potions demandées.

Étapes à réaliser :

  • ajouter un attribut à la classe Dresseur pour gérer son argent
  • ajouter de l’argent au joueur lorsque celui-ci bat un autre dresseur
  • retirer de l’argent au joueur lorsque celui-ci est mis KO (attention à ne pas passer en négatif)
  • coder la fonction visite_PokeShop qui permet au joueur d’acheter des potions avec son argent
  • ajouter l’action d’aller au PokeShop dans la boucle de jeu

Pikachu monte au niveau 10 !

Rendons nos Pokemon encore plus forts et devenons Maître Pokemon !

Pour le moment, les Pokemon d’un dresseur ne s’améliorent pas avec les combats, ils restent avec leurs caractéristiques définies lors de la capture de chacun.

Faisons en sorte que les Pokemon du joueur deviennent les meilleurs.

Pour cela, ajoutons 2 caractéristiques :

  • xp : pour les points d’expérience
  • niveau : pour le niveau actuel d’un Pokemon

Au cours d’un combat, si un Pokemon met KO un autre Pokemon, alors il gagne de l’expérience (pourquoi pas le montant de la vie maximale du Pokemon adverse ?).

Lorsque l’expérience d’un Pokemon atteint un certain palier, par exemple 100 points, alors le Pokemon monte de niveau et devient plus puissant !

On peut ajouter une nouvelle méthode à la classe Pokemon : augmente_niveau.
Cette méthode va :

  • augmenter le niveau du Pokemon,
  • remettre à 0 ses points d’expérience
  • et augmenter chacune de ses caractéristiques, avec les valeurs que tu as choisies.

Ensuite, il ne reste plus qu’à appeler cette méthode lorsqu’un Pokemon dépasse le palier d’expérience suite à un combat contre un autre Pokemon (donc dans la méthode combat de la classe Pokemon).


Félicitations !

Tu es arrivée à la fin de ce projet Pokemon.

On espère que tu as aimé, n’hésite pas à nous faire des retours et à améliorer ton jeu avec tout ce qu’il te passe par la tête !

Retour au Menu