Solarus Wiki

A wiki for the Solarus engine community

Outils pour utilisateurs

Outils du site


fr:tutorial:npc_first_part

Différences

Cette page vous affiche les différences entre la révision choisie et la version actuelle de la page.

Lien vers cette vue comparative

fr:tutorial:npc_first_part [2018/12/22 14:14] (Version actuelle)
Ligne 1: Ligne 1:
 +[[{:​wiki:​arrow_left.png|width:​137px;​float:​left;​}fr:​tutorial:​how_to_make_a_shop|Chap. 15]][[{:​wiki:​arrow_right.png|width:​137px;​float:​right;​}fr:​tutorial:​npc_second_part|Chap. 17]][[{:​wiki:​home.png|width:​132px;​}fr:​tutorial:​create_your_2d_game_with_solarus|Sommaire]]
  
 +====== Chapitre 16 : Les Personnages Non Joueurs ======
 +
 +Dans ce chapitre, nous allons créer la chaîne d'​échange dont nous parlions au chapitre précédent. Le premier objet sera achetable et servira à être échangé contre le second, qui lui-même sera échangeable contre le dernier. Pour cela, nous allons créer des Personnages Non Joueurs, ou PNJs (en anglais : Non Playing Characters, ou NPCs), afin d'​instaurer un dialogue ;)
 +
 +===== Ressources =====
 +
 +Aucune nouvelle ressource n'est nécessaire du fait que nous avions déjà téléchargé les sprites des PNJs dans le chapitre précédent.
 +
 +===== Types de PNJs =====
 +
 +Il y a deux types de PNJs : PNJ habituel (une personne) et PNJ généralisé. La différence entre les deux est plus ou moins expliquée par la parenthèse : un PNJ habituel représentera plutôt une personne, c'​est-à-dire que le sprite du PNJ se mettra automatiquement à marcher si on lui donne un mouvement, il sera consultable depuis les quatre directions et se tournera dans la bonne lorsque le héros lui parlera, etc. Dans le cadre d'un PNJ généralisé,​ tout devra être codé par vous, c'est plutôt du code qui s'​adresse à un objet ou à un élément "​invisible"​. Par exemple, les pancartes sont des PNJ généralisés : ils ont le même comportement qu'un PNJ habituel (elles ne servent qu'à "​parler"​),​ mais il faut regarder dans la bonne direction. ​
 +
 +Dans ce chapitre nous verrons les PNJs habituels, et dans le prochain les PNJs généralisés.
 +
 +===== Un bug embêtant de la 1.0 =====
 +
 +Il existe un bug pour le choix du sprite d'un PNJ usuel dans la version 1.0 de l'​éditeur : la case à cocher "​sprite"​ est grisée. En fait, elle devrait l'​être mais en étant cochée pour permettre de toujours choisir un sprite vu que justement, c'est pour les PNJs habituels qu'il faut obligatoirement un sprite. Pour cela, choisissez d'​abord de mettre un PNJ généralisé,​ cochez la case pour mettre un sprite, choisissez un sprite (mais vous pourrez aussi le faire désormais depuis le PNJ usuel) et rechoisissez le type PNJ usuel. Ce bug n'est plus d'​actualité avec les versions 1.1+, mais étant donné qu'il est pas mal handicapant,​ il valait la peine d'​être décrit plus avant dans ce chapitre.
 +
 +===== Un vendeur à notre boutique =====
 +
 +Faire une boutique c'est bien, mais sans vendeur, pourquoi payerait-on ? Faites donc un PNJ usuel, choisissez le sprite que vous souhaitez lui donner (étant donné que le PNJ ne bougera pas, regardez plutôt dans la catégorie "ALTTP static villager"​),​ par exemple "ALTTP static villager 6" correspond bien à un vendeur généralement.
 +
 +Créez le dialogue suivant juste après le dialogue des coeurs, à la ligne 315 du fichier des dialogues :
 +
 +<code lua>
 + 
 +-- Vendeur du village
 +dialog{
 +  id = "​shop.npc",​
 +  text = [[
 +Salutations,​ voyageur.
 +Bienvenue à la Maison
 +des Affaires !
 +Choisis l'​objet que tu
 +souhaites acheter.
 +]]
 +}
 +-------------------
 +</​code>​
 +
 +Dans l'​action de votre NPC, vous pouvez désormais mettre "Show a message",​ et l'id sera bien sûr "​shop.npc"​.
 +
 +Les autres actions sont "Call a map script"​ et "Call an item script"​. Appeler le script de la map nous allons le faire pour la chaîne d'​échange,​ cela va appeler l'​événement du PNJ ''​on_interaction'',​ et cela se déclenchera au moment où le joueur utilise la touche "​action"​ devant le PNJ. La dernière action possible appellera soit l'​événement ''​item:​on_interaction_npc'',​ soit ''​item:​on_interaction_npc_item''​. Nous verrons comment l'​utiliser dans un futur chapitre.
 +
 +===== Perdu dans les bois =====
 +
 +Nous allons faire la première chaîne de notre échange. Pour cela dans la map de la forêt, faites un PNJ (plutôt à l'​entrée le temps de faire les tests, après vous pourrez le perdre plus profondément dans la map si vous le souhaitez mais attention aux téléportations invisibles, il ne devra jamais se trouver dans la zone visible depuis la téléportation !). Nommez ce PNJ "​mirror_npc",​ choisissez lui un sprite et son action devra être "Call the map script"​.
 +
 +==== Code du PNJ ====
 +
 +Ouvrez le fichier lua de la map correspondante,​ ajoutez la ligne ''​game = map:​get_game()''​ en seconde ligne et ajoutez le code suivant à la fin :
 +
 +<code lua>
 +
 +function mirror_npc:​on_interaction()
 +    local mirror = game:​get_item("​mystic_mirror"​)
 +    if mirror:​get_variant() == 0 then
 +        map:​start_dialog('​forest.mirror_npc.wants_mirror'​)
 +    else
 +        map:​start_dialog('​forest.mirror_npc.asks_mirror',​ function(answer)
 +            if answer == 1 then
 +                map:​start_dialog('​forest.mirror_npc.yes',​ function()
 +                    mirror:​set_variant(0)
 +                    hero:​start_treasure('​fire_stone'​)
 +                end)
 +            else
 +                map:​start_dialog('​forest.mirror_npc.no'​)
 +            end
 +        end)
 +    end
 +end
 +</​code>​
 +
 +Petite analyse bien que très simpliste : nous récupérons l'​objet "​mystic_mirror"​ pour en définir la variant possédée par le héros. Si cette variant est 0, c'est qu'il ne l'a pas, donc on enclenche le dialogue indiquant que ce PNJ recherche un miroir. Si au contraire il l'a, on démarre le dialogue demandant au héros de donner le miroir, en laissant le choix de ne pas le faire. Selon la réponse, on donne la Pierre de Feu après le dialogue de remerciement,​ sinon on affiche un dialogue de déception car le héros a refusé la requête du PNJ.
 +
 +Il y a cependant un problème : si nous avons déjà donné le miroir, le dialogue indiquant que le PNJ cherche le miroir se déclenchera. Il faut plutôt définir un dialogue différent car cette partie de la quête d'​échange est complète. Changez donc le code comme suit pour mieux satisfaire à cette contrainte :
 +
 +<code lua>
 +function mirror_npc:​on_interaction()
 +    local gave_mirror = game:​get_value('​gave_mirror'​)
 +    if gave_mirror then
 +        map:​start_dialog('​forest.mirror_npc.already_gave_mirror'​)
 +        return
 +    end
 +    ​
 +    local mirror = game:​get_item("​mystic_mirror"​)
 +    if mirror:​get_variant() == 0 then
 +        map:​start_dialog('​forest.mirror_npc.wants_mirror'​)
 +    else
 +        map:​start_dialog('​forest.mirror_npc.asks_mirror',​ function(answer)
 +            if answer == 1 then
 +                map:​start_dialog('​forest.mirror_npc.yes',​ function()
 +                    mirror:​set_variant(0)
 +                    hero:​start_treasure('​fire_stone',​ 1, "​gave_mirror"​)
 +                end)
 +            else
 +                map:​start_dialog('​forest.mirror_npc.no'​)
 +            end
 +        end)
 +    end
 +end
 +</​code>​
 +
 +Comme vous pouvez le constater, donner la Pierre de Feu sauvegarde une variable qui est vérifiée au début de l'​interaction avec le PNJ. Si cette variable existe, on enclenche le nouveau dialogue.
 +
 +==== Dialogue du PNJ ====
 +
 +Bien sûr, tous les dialogues que vous voyez ici doivent exister dans le fichier correspondant,​ aussi ouvrez-le et ajoutez ceci à la ligne 328 (juste après le dialogue du vendeur) :
 +
 +<code lua>
 +-- PNJ au miroir
 +dialog{
 +  id = "​forest.mirror_npc.wants_mirror",​
 +  text = [[
 +Je suis archéologue
 +et il me manque un
 +objet d'une grande
 +rareté. Il s'agit d'un
 +miroir qui permet de
 +voir le monde par les
 +yeux de la déesse et
 +dévoile ses plus grands
 +secrets.
 +]]
 +}
 +
 +dialog{
 +  id = "​forest.mirror_npc.asks_mirror",​
 +  question = true,
 +  text = [[
 +Tu... Tu possèdes le
 +Miroir Mystique !?
 +Il me le FAUT ! Si tu
 +me le donnes, tu ne le
 +regretteras pas. J'ai
 +en ma possession des
 +reliques intéressantes.
 +Donner le miroir...
 +Pas question !
 +]]
 +}
 +
 +dialog{
 +  id = "​forest.mirror_npc.yes",​
 +  text = [[
 +Vraiment ? Aussi
 +simplement que ça ? Je
 +ne sais pas quoi dire.
 +Prends donc cette
 +Pierre de Feu, c'est
 +une roche très rare !
 +]]
 +}
 +
 +dialog{
 +  id = "​forest.mirror_npc.no",​
 +  text = [[
 +Je m'en doutais... Je
 +ne t'en veux pas.
 +J'​aurais sans doute
 +réagi pareil si j'​avais
 +un trésor d'une telle
 +rareté. Mais si tu
 +changes d'​avis,​ surtout
 +n'​hésite pas. Je reste
 +ici encore un peu...
 +]]
 +}
 +
 +dialog{
 +  id = "​forest.mirror_npc.already_gave_mirror",​
 +  text = [[
 +Oh, c'est toi. Encore
 +merci pour le Miroir
 +Mystique, il m'a fait
 +énormément avancer dans
 +mes recherches.
 +
 +La Pierre de Feu
 +t'​a-t-elle été utile ?
 +]]
 +}
 +-------------------
 +</​code>​
 +
 +Et voilà, votre premier maillon devrait fonctionner désormais.
 +
 +===== Exercice =====
 +
 +Peuplez un peu le village. Mettez deux PNJs en extérieur, un bibliothécaire (ou deux si vous voulez en faire un par étage) qui indiquera où se trouve quel rayon, et deux autres personnes qui chercheront dans ces mêmes rayons. Cet exercice n'est clairement pas compliqué, il va surtout servir à rendre le village un peu plus agréable à la visite. Un des deux personnages dans la bibliothèque sera la suite de la chaîne. Il demandera la Pierre de Feu pour sa collection et donnera en échange la Clé d'Os.
 +
 +===== Correction =====
 +
 +Vous pouvez récupérer la [[https://​github.com/​Renkineko/​solarus_tutorial/​archive/​chapter16.0.zip|version finale de ce chapitre ici]], contenant aussi l'​exercice corrigé. Un NPC supplémentaire a été ajouté, un bon point à celui qui trouvera la référence. Et un autre bon point à celui qui donnera la référence de la découverte du collectionneur :)
 +
 +[[{:​wiki:​arrow_left.png|width:​210px;​float:​left;​}fr:​tutorial:​how_to_make_a_shop|Chap. 15 : Les Rubis]][[{:​wiki:​arrow_right.png|width:​210px;​float:​right;​}fr:​tutorial:​npc_second_part|Chap. 17 : Les PNJ]][[{:​wiki:​home.png|width:​203px;​}fr:​tutorial:​create_your_2d_game_with_solarus|Sommaire]]
fr/tutorial/npc_first_part.txt · Dernière modification: 2018/12/22 14:14 (modification externe)