Ajouter des personnages non joueurs
L’objectif de cette partie est d’ajouter des personnages dans les différents lieux de la map, et de permettre au joueur d’interagir avec eux. Par la suite, ces personnages seront appelés des personnages non joueurs (PNJ).
GitHub stuff
Ouvrir la [REPOSITORY_HOMEPAGE]
et démarrer le codespace associé :
Code Codespaces
A partir du terminal du codespace, récupérer la dernière version du jeu depuis votre dépôt
$ git pull
Utiliser l’extension GitLens
pour examiner l’historique des commits, et en particulier les différences entre la version actuelle et la version précédente.
Créer un PNJ
Tous les personnages non joueurs auront des caractéristiques communes. Il est donc intéressant de créer une classe Character
qui permettra de les instancier.
Note
On pourrait remarquer que la classe Character
est très similaire à la classe Player
. En effet, le joueur et les personnages non joueurs ont un nom, une description, un lieu dans lequel ils sont, une façon de se déplacer, etc. On pourrait donc imaginer que les classes Character
et Player
héritent d’une même classe mère qui contiendrait les attributs/méthodes communs aux deux classes. C’est un développement intéressant qu’on pourra aborder de façon optionnelle plus tard.
A faire
Créer un fichier character.py
dans le répertoire v5
. Ce fichier contiendra la classe Character
. Cette classe sera utilisée pour représenter les différents personnages non joueurs. Elle contiendra les attributs suivants :
name
: le nom du personnage ;description
: la description du personnage ;current_room
: le lieu où se trouve le personnage ;msgs
: une liste des messages à afficher lorsque le joueur interroge le personnage non joueur.
Comme pour les lieux et les items, on a besoin d’une représentation textuelle des personnages non joueurs.
A faire
Redéfinir la méthode __str__()
pour qu’elle retourne une représentation textuelle du personnage. Un exemple:
>>> from room import Room
>>> forest = Room("Forest", "une forêt enchantée. Vous entendez une brise légère à travers la cime des arbres.")
>>> gandalf = Character("Gandalf", "un magicien blanc", forest, ["Abracadabra !"])
>>> print(gandalf)
Gandalf : un magicien blanc
Intégrer les PNJ à la map
Pour intégrer les personnages non joueurs dans le jeu, il faut pouvoir les associer aux lieux, à l’image de ce qu’on a fait pour la classe Item
.
Quelle est la classe concernée par cette modification ?
Quelle est le type d’objet le plus adaptée pour réaliser l’association ?
A faire
Modifier la classe identifiée ci dessus pour qu’elle contienne un attribut characters
qui référence les personnages non joueurs présents dans le lieu.
Cette structure de données doit être initialisée à vide. Elle sera renseignée depuis la classe Game
, dans la fonction setup()
, comme on l’a fait pour les items.
A faire
La commande look
permettant d’observer l’environnement du lieu où se trouve le joueur doit maintenant permettre d’afficher, non seulement les items, mais également les personnages non joueurs présents dans le lieu.
Quelle est la classe concernée par cette modification ?
Quelle est la méthode de cette classe concernée par cette modification ?
Modifier la méthode identifiée ci dessus pour produire un affichage des items et des personnages non joueurs présents dans le lieu. Un exemple d’exécution est donné ci dessous:
> look
On voit:
- shield : un bouclier léger et résistant (1 kg)
- Gandalf : un magicien blanc
Déplacer les PNJ
Pour donner un peu de dynamisme au jeu, on va faire en sorte que les personnages non joueurs se déplacent d’un lieu à l’autre.
A faire
Pour cela, on va créer une méthode move()
sans paramètres, qui fonctionne de la façon suivante. A chaque tour de jeu :
le personnage non joueur a une chance sur deux de se déplacer ou de rester sur place ;
s’il se déplace, il va dans une pièce adjacente au hasard.
Astuce
La fonction random.choice()
permet de choisir un élément au hasard dans une liste selon une loi de probabilité uniforme. Par exemple, pour choisir un élément au hasard dans une liste l
on peut écrire random.choice(l)
.
La méthode move()
doit retourner True
si le personnage non joueur s’est déplacé, et False
sinon.
Maintenant que le jeu est dynamique (les personnages non joueurs se déplacent), il est intéressant de pouvoir vérifier le bon déroulement du jeu, au fur et à mesure de son exécution.
A faire
Créer une variable booléenne DEBUG
dans game.py
pour contrôler l’affichage.
Si cette variable est True
, alors le jeu affiche les messages de débogage placés judicieusement dans les classes/méthodes dont on veut contrôler le fonctionnement.
Sinon, il n’affiche que les messages de l’utilisateur.
Cette variable devra être importée dans les modules pour lesquels on souhaite contrôler l’affichage des messages de débogage. Par exemple, on pourra écrire dans le module concerné:
from game import DEBUG
...
if DEBUG: print("DEBUG: message")
Interagir avec les PNJ
Pour l’intérêt du jeu, le joueur doit pouvoir interagir avec les personnages non joueurs. Pour cela, on va créer une command talk <someone>
déclenchant une action talk()
sur le personnage non joueur passé en argument. Cette action devra appeler une méthode get_msg()
définie dans la classe appropriée.
Quel est la classe concernée par l’ajout de la méthode
get_msg()
?
A faire
Créer la méthode get_msg()
dans la classe identifiée ci dessus. Cette méthode doit afficher cycliquement les messages associés au personnage non joueur. Ce qui signifie qu’il faudra garder la mémoire des messages déjà affichés, et ne plus les afficher lors des appels suivants à cette méthode.
Astuce
Pour cela, on pourra utiliser la méthode pop(i)
de la classe list
qui permet de supprimer et retourner le ième élément d’une liste. Par exemple, pour supprimer et retourner le premier élément de la liste l
, on peut écrire l.pop(0)
.
Si on crée un PNJ de la façon suivante:
gandalf = Character("Gandalf", "un magicien blanc", forest, ["Je suis Gandalf", "Abracadabra !"])
L’exécution doit produire un résultat similaire à:
> talk gandalf
Je suis Gandalf
> talk gandalf
Abracadabra !
> talk gandalf
Je suis Gandalf
En choisissant astucieusement les items et les lieux où se trouvent les personnages non joueurs, on peut créer des situations de jeu intéressantes. On peut imaginer que le personnage non joueur ne parle qu’après avoir trouvé un objet particulier. Ou donne un indice pour trouver (ou interagir avec) un objet ou un autre personnage non joueur.
Ces situations nécessitent des développements supplémentaires.
La suite…
A cette étape, votre dépôt doit contenir les seuls fichiers suivants :
actions.py
character.py
command.py
game.py
item.py
player.py
room.py
Le jeu doit être fonctionnel et avoir intégré les consignes précédentes. La commande
$ python game.py
doit pouvoir permettre d’activer la fonction back
sans erreur.
GitHub stuff
Enregistrer les modifications apportées aux fichiers dans le repo local au codespace
$ git add .
$ git commit -m "Ajouter des personnages non joueurs"
Pour référencer plus facilement cette version dans le futur, créer un tag
$ git tag v5
Synchroniser votre codespace avec votre dépôt GitHub
$ git push
Vérifier que les modifications sont bien présentes dans le dépôt GitHub.