Nom du tutoriel : Balises PersonnaliséesNotre objectif : Ajouter des balise dans les messages pour afficher quelque chose en particulier.
Description du tutoriel : On verra ici deux exemples distinct, un remplaçant directement le texte, l'autre utilisant un charactère réservé qui appèlera une fonction plus complexe.
Auteur : Miraino Hikari
Liens utiles : Expressions régulière de substitution
Class::String - gsub
Tutoriel : Ce tutoriel vise à surcharger la classe Message. Donc premièrement partez avec ce code.
- Code:
-
class Window_Message < Window_Selectable
#--------------------------------------------------------------------------
# ● convert_special_characters
#--------------------------------------------------------------------------
alias old_csc convert_special_characters
def convert_special_characters
old_csc
end
#--------------------------------------------------------------------------
# ● Update Message
#--------------------------------------------------------------------------
alias old_update_m update_message
def update_message
old_update_m
end
end
C'est ce dont vous aurez besoin pour surcharger sans avoir à tout réécrire la classe Window_Message. Je vous propose cette architecture pour que vous puissiez ajouter des fonctionnalité tout en restant compatible avec les fonctionnalité déjà existante ou ajouter par d'autres modules.
Disons qu'on veut ajouter deux nouvelles balise qui font des chose de manière un peu différente... La première modifie directement le texte alors que l'autre envoie un charactère réservé pour effectuer une opération plus complexe. Ces balises doivent être ajoutée dans convert_special_characters. (Un exemple complèt final sera affiché à la toute fin du tutoriel
- Code:
-
@text.gsub!(/\\NS\[(\d+)\]/i) { $data_skills[$1.to_i].name } # Skill Name
@text.gsub!(/\\PF\[(\d+)\]/i) { "\x31[#{$1.to_i}]"} # Party Face
Donc tout d'abord, la première chose à savoir, c'est que le message est lu séquentiellement lorsqu'il est affiché dans la fenêtre. Chaque lettre est lu puis affichée. Cependant, lorsqu'on utilise une balise (ex. \C[0], \N[1], \V[1]) dans le texte, celle-ci doit être remplacer par ce qu'on veut qu'elle fasse ou écrive. Donc la première chose qui est faite est de remplacer les balises par le texte ou la fonction désiré.
Reprenons l'exemple suivant qui modifie directement le texte.
- Code:
-
@text.gsub!(/\\NS\[(\d+)\]/i) { $data_skills[$1.to_i].name } # Skill Name
@text.gsub! est une fonction qui remplace ce qu'il y a entre parenthèse par ce qu'il y a entre accolade. Elle remplace directement la string d'origine, ici le contenu de @text qui contient le texte à afficher. S'il n'y a pas de remplacement, la fonction renvoie nil. Dans la parenthèse, il y a beaucoup de chose, mais en fait, c'est assez simple à comprendre. La synthaxe de substitution demande la string à remplacer. Cette string se trouve entre barres obliques plutôt que les guillemets habituel. Donc si on a par exemple le code suivant :
- Code:
-
@text = "allo toi"
@text.gsub!(/l/){'t'}
print @text
Et bien la fenêtre de console affichera "atto toi", ayant remplacer tous les 'l' par des 't'. Le i qui se trouve à l'extérieur de la string signifie seulement que le texte n'est pas sensible à la case. Donc quand on écrit \V[1] ou \v[1] on obtient la variable 1 sans avoir à définir \V et \v.
Ensuite, nous avons \\ avec des lettres. Dans notre exemple, c'est NS. En fait il s'agit de notre séquence. NS est notre commande. Ici, on fait l'affichage du nom d'une skill, donc j'ai choisi \NS comme code séquence. Comme la barre oblique inversée est un caractère réservé de programation, pour pouvoir détecté cette string, il faut lui dire que c'est le caractère lui-même qu'on veut... Ainsi, pour une string, \\ signifie, le caractère \. Ceci est très important, il ne faut vraiment pas oublier ce détail. C'est la même chose pour l'autre caractère réservé qui suit, les crochets [ et ]. En mettant la barre oblique inversé devant, on dit au programe qu'on veut ce caractère et non pas évaluer son expression. Ensuite viens un parenthèse qui n'est pas précédé de la barre oblique inversé, donc il faut évaluer son expression. \d+ est une expression régulière qui dit à gsub qu'il doit récupérer tous les chiffres présent et qu'il doit y avoir au moins un chiffre. Pour toutes les expression régulières, référé vous au lien fourni. On referme le crochet (pour la syntaxe \NS[1]) puis on termine le string en refermant notre barre oblique.
Ensuite, on indique entre accolade la valeur que cette expression doit afficher. Il faut impérativement que cette valeur soit un string. Dans notre cas, $data_skills[$1.to_i].name est la valeur qui doit prendre la place. $data_skills[X].name est un tableau qui contient les nom des skills (fourni par la base de donnée de votre jeu) et X est le numéro de la skill. $1 signifie la valeur trouvé... Cette valeur viens de votre \d+. Donc si l'expression \d+ renvoie 1, $1 = 1, si \d+ renvoie 321, $1 = 321. On ajoute .to_i pour s'assurer que le nombre est un entier puisque l'index d'une table doit être un entier... Pour ce cas, c'est tout. À chaque utilisation de votre nouvelle balise \NS[1], vous afficherez le nom de votre skill #1 de votre basse de donnée. Vous n'aurez rien à ajouter dans update_message.
Maintenant, la prochaine.
- Code:
-
@text.gsub!(/\\PF\[(\d+)\]/i) { "\x31[#{$1.to_i}]"} # Party Face
Ce code affichera le visage d'un membre de l'équipe dans le texte. Nous utiliserons la balise \PF. Toute la première partie reste la même. Ce qui est différent, c'est l'accolade. L'idée est d'utilisé un caractère réservé (car nous devons absolument utiliser un string) qui nous permettra de lancer une fonction par update message. \x31 est un caractère réservé... En fait, il s'agit du code hexadécimal 31 (on dira trois-un et non trente-un). Puisque ce caractère est généralement suivit d'un crochet, il y a peu de chance que celui-ci soit modifier par malchance. Cependant, rappelez-vous qu'il sagit du code hexadécimal d'un caractère. Vous pouvez utilisez n'importe quel hexa de \x00 à \xFF, mais rappelez vous de ne pas changer un code déjà utilisé. Par défaut, VX utilise déjà de \x00 à \x08 pour les balises "normale". Si vous avez des conflits avec des balises, changer uniquement le numéros de caractères réservés. (Comment se fait-il qu'on ne frappe aucun caractère si toute les nombre hexa sont disponible? C'est parce que d'autre caractères le suivent. Cependant, si un code vous cause des problème, changez le simplement.) Donc maintenant que nous avons le caractère trois-un, alons lui faire faire quelquchose dans "update_message".
Note : Il est préférable de prendre des code inférieur à 0x32 car 0x32 est l'espace suivit des autres caractère (a,b,c,d,etc.) Cependant, toutes les possibilités sont acceptables.
Là, certain me détesterons jusqu'à la fin de leur jour, mais voici le code qui sera à ajouter.
- Code:
-
loop do
c = @text.slice(/./m) # Get next text character
case c
when "\x31" #SPM
@text.sub! (/\[(\d*)\]/, "") #récupère l'index du personnage
actor = $game_party.members[$1.to_i]
$game_message.face_name = actor.face_name
$game_message.face_index = actor.face_index
begin
draw_face(actor.face_name, actor.face_index, 0, 0)
rescue
end
@contents_x = 112
@text.slice!(/./) #retire cette commande de la liste
else # pour le reste, sortir de la boucle et se référer au code original
break
end
end
Ne vous préoccupez pas de
- Code:
-
loop do
c = @text.slice(/./m) # Get next text character
vous devez juste savoir que vous devez le mettre car ce code est ce qui regarde un a un chaque caractère de votre string pour l'afficher à l'écran. Remarquez cependant que contrairement au code originale, on utilise slice et non slice! car nous avons besoin de la string original pour appeler le code qui faisait les modification de bases.
Ce qui nous intéresse est dans le case. Un fois qu'on a retrouver notre \x31, que fait-on? Alors on lui dit, lorsque tu trouves \x31, fait ceci de cette façon :
- Code:
-
when "\x31" #SPM
@text.sub! (/\[(\d*)\]/, "") #récupère l'index du personnage
actor = $game_party.members[$1.to_i]
$game_message.face_name = actor.face_name
$game_message.face_index = actor.face_index
begin
draw_face(actor.face_name, actor.face_index, 0, 0)
rescue
end
@contents_x = 112
@text.slice!(/./) #retire cette commande de la liste
La dernière ligne est importante... @text.slice!(/./) retirera la commande \x31 de la liste et ne sera donc pas affiché ni évaluer par l'évaluateur original. Autre chose importante, le .sub! efface le paramètre en remplaçant par une string vide. Le reste, c'est votre fonction. Ici, on affiche simplement le visage de l'acteur correspondant au membre de l'équipe indiqué par le paramètre.
Donc au final, vous avez ajouter 2 balises, une qui crée du texte et l'autre qui fait une action non visible dans le texte lui-même. Cette deuxième peut faire ce que vous voulez, même jouer directement sur la carte ou lancer un événement.
Voici le code final :
- Code:
-
#==============================================================================
# MyMessage
#------------------------------------------------------------------------------
# Surcharge le script de base Window_Message
#==============================================================================
class Window_Message < Window_Selectable
#--------------------------------------------------------------------------
# ● convert_special_characters
#--------------------------------------------------------------------------
alias old_csc convert_special_characters
def convert_special_characters
old_csc
@text.gsub!(/\\PF\[(\d+)\]/i) { "\x31[#{$1.to_i}]"} # Party Face
@text.gsub!(/\\NS\[(\d+)\]/i) { $data_skills[$1.to_i].name } # Skill Name
end
#--------------------------------------------------------------------------
# ● Update Message
#--------------------------------------------------------------------------
alias old_update_m update_message
def update_message
loop do
c = @text.slice(/./m) # Get next text character
case c
when "\x31" #SPM
@text.sub! (/\[(\d*)\]/, "") #récupère l'index du personnage
actor = $game_party.members[$1.to_i]
$game_message.face_name = actor.face_name
$game_message.face_index = actor.face_index
begin
draw_face(actor.face_name, actor.face_index, 0, 0)
rescue
end
@contents_x = 112
@text.slice!(/./) #retire cette commande de la liste
else # pour le reste, sortir de la boucle et se référer au code original
break
end
end
old_update_m
end
end