AGSScriptModuleKitaiMessages lettre par lettreLettre par Lettre1.2±//=================================================================== // *** AGS MODULE SCRIPT *** // // Module: Parler // // Author: Maky Kitai // // Require: AGS 3.0 // // Affichage de message caractère par caractère. // // Ce module permet d'afficher du texte caractère par caractère, // que ce soit pour un personnage ou un message général. // // License : // This module is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License // as published by the Free Software Foundation; either version 2.1 // of the License, or any later version. // //------------------------------------------------------------------- //------------------------------------------------------------------- // Static Variables //------------------------------------------------------------------- Overlay* Bulle; // Le calque texte contenant le message. Parler Propos; // L'objet Parler "Propos", associé au message. bool Pressed = false; //=================================================================== // Member Functions //------------------------------------------------------------------- // Cette fonction initialise la structure et crée le calque textuel. function Parler::Initialize(String message, Character* perso, BlockingStyle blocking) { message = GetTranslation(message); int width = GetTextWidth(message, Game.SpeechFont); int wlimit = FloatToInt(IntToFloat(System.ViewportWidth) / 2.0); // Largeur limitée à la moitié de l'écran. if (width > wlimit) this.width = wlimit + 4; // On ne veut pas que le message soit trop large. else this.width = width + 4; // On met 4 pixels de "bordure de sûreté". this.mess = message; this.cycle = 1; this.len = message.Length; this.unedeux = 0; if (blocking == eBlock) this.blocking = true; else this.blocking = false; this.xport = this.width / 2; this.yport = GetTextHeight(message, Game.SpeechFont, this.width) + 5; // xport et yport définissent le décallage du texte pour le centrer aux coordonnées données. this.perso = perso; // Ici, on traite l'initialisation selon qu'on est en message de personnage ou non. if (this.perso) { // On va récupérer la hauteur de la sprite du personnage qui parle. ViewFrame* frame = Game.GetViewFrame(perso.View, perso.Loop, perso.Frame); int scaledheight = FloatToInt(IntToFloat(Game.SpriteHeight[frame.Graphic]) * IntToFloat(perso.Scaling) / 100.0); // La taille du personnage à l'écran, selon son zoom. this.color = perso.SpeechColor; // La couleur du message correspond à celle du texte prononcé par le perso. this.x = perso.x - GetViewportX(); this.y = perso.y - GetViewportY(); this.yport += scaledheight; perso.LockView(perso.SpeechView); // On anime le personnage qui parle. perso.Animate(perso.Loop, 2, eRepeat, eNoBlock); } int x = this.x - this.xport; int y = this.y - this.yport; // On réajuste le décallage du calque en fonction des débordements à l'écran. int xlimit = System.ViewportWidth - wlimit; if (x < 0) this.xport = this.x + GetViewportX(); if (x > xlimit) this.xport += x - xlimit; if (y < 0) this.yport = this.y + GetViewportY(); Bulle = Overlay.CreateTextual(0, 0, this.width, Game.SpeechFont, this.color, ""); // Création du calque textuel. } // Cette fonction gère la fin du message : elle peut l'effacer de l'écran ou juste cesser l'animation // du personnage parlant. function Parler::Stop(Parler_Stop stop) { if (this.perso) this.perso.UnlockView(); if (stop == eParler_All) { if (this.blocking) UnPauseGame(); if (Bulle == null) return; this.color = 0; this.blocking = true; this.len = 0; this.mess = null; this.perso = null; this.unedeux = 0; this.width = 0; this.x = 0; this.xport = 0; this.y = 0; this.yport = 0; this.cycle = 0; if (Bulle.Valid != 0) Bulle.Remove(); } } // Cette fonction permet de mettre à jour le placement du message à l'écran. function Parler::Place() { if (!this.cycle) return; int x = this.x; int y = this.y; if (this.perso) { x = this.perso.x - GetViewportX(); y = this.perso.y - GetViewportY(); } Bulle.X = x - this.xport; Bulle.Y = y - this.yport; // Si le calque "déborde" à gauche ou en haut, on efface le message de l'écran. // (AGS recentrerait automatiquement le calque sur l'axe dont la coordonnée est négative) if ((Bulle.X < 0) || (Bulle.Y < 0)) this.Stop(); } // Cette fonction met à jour les lettres affichées dans le message. function Parler::UpLettre() { if (!this.cycle) return; this.unedeux++; // Cette variable augmente à CHAQUE cycle du jeu. if ((this.unedeux % 3) < 2) { // On affiche la prochaine lettre tous les deux cycles sur trois. if (this.cycle <= this.len) Bulle.SetText(this.width, Game.SpeechFont, this.color, this.mess.Substring(0, this.cycle)); this.cycle++; // Cette variable augmente deux cycles sur trois. } if (this.cycle > this.len) { // cycle == len : toutes les lettres sont affichées. this.Stop(eParler_View); // On cesse d'animer le personnage. if ((this.cycle > this.len + 30) || (Mouse.IsButtonDown(eMouseLeft) && this.blocking && !Pressed)) { // if (this.cycle > this.len + 30) { // On attend un court moment pour permettre de finir de lire, puis on supprime le calque. this.Stop(); // Supression du calque et du message. } return; } // Si le joueur clique sur le bouton gauche, le message s'affiche d'un coup. // Pour être sûr que la souris a bien été relâchée (ce qui est vérifié dans // le repeatedly_execute_always), on attend un cycle de jeu (unedeux > 1). else if ((this.unedeux > 1) && Mouse.IsButtonDown(eMouseLeft) && this.blocking && !Pressed) { this.cycle = this.len; Pressed = true; } } // La fonction que l'utilisateur appelle pour afficher un message général. static function Parler::Afficher(int x, int y, String message, int color, BlockingStyle blocking) { Propos.x = x; Propos.y = y; Propos.color = color; Propos.Initialize(message, null, blocking); if (blocking == eBlock) PauseGame(); } //=================================================================== // Global Functions //------------------------------------------------------------------- // La fonction que l'utilisateur appelle pour afficher un message de personnage. function Dire(this Character*, String message, BlockingStyle blocking) { if (this.Room != player.Room) return; Propos.Initialize(message, this, blocking); if (blocking == eBlock) { while (Propos.cycle) Wait(1); } } //=================================================================== // Ags Standard Events //------------------------------------------------------------------- //================================================================== function on_event (EventType event, int data) { // // On efface le message lorsqu'on quitte la pièce. //------------------------------------------------------------------- if (event == eEventLeaveRoom) Propos.Stop(); } //================================================================== function repeatedly_execute_always() { // // On s'occupe ici d'afficher lettre par lettre et de replacer le calque correctement. //------------------------------------------------------------------- Propos.UpLettre(); // Mise à jour des lettres affichées. Propos.Place(); // Mise à jour des coordonnées du message. if (Mouse.IsButtonDown(eMouseLeft)) Pressed = true; else if (Pressed) Pressed = false; } Â//=================================================================== // *** AGS MODULE HEADER *** // // Module: Parler // // Author: Maky Kitai // //------------------------------------------------------------------- //=================================================================== // Enumerated Types: // The following enumerated data types are defined by this module. //------------------------------------------------------------------- enum Parler_Stop { // Les types possibles pour la fin du message. eParler_View, // Cesse l'animation de message du personnage uniquement. eParler_All // Cesse l'animation de message du personnage et efface le message de l'écran. }; //=================================================================== struct Parler { // La structure représentant le message. protected int len; // Nombre de caractères du message. protected int xport; // Décallage du message sur l'axe horizontal. protected int yport; // Décallage du message sur l'axe vertical. protected int width; // Largeur du message. protected int unedeux; // Permet de n'agir que tous les 2 cycles. protected Character* perso; // Le personnage qui parle protected String mess; // Le texte du message. writeprotected int cycle; // Augmente tous les 2 cycles. writeprotected bool blocking; // Si le message bloque ou non l'exécution. int color; // La couleur du message. int x; // Coordonnée x du message. int y; // Coordonnée y du message. import function Initialize(String message, Character* perso, BlockingStyle blocking); import function Stop(Parler_Stop stop = eParler_All); import function Place(); import function UpLettre(); import static function Afficher(int x, int y, String message, int color = 15, BlockingStyle blocking = eBlock); }; //=================================================================== // Importations: // The following imported functions are defined by this module. //------------------------------------------------------------------- import function Dire(this Character*, String message, BlockingStyle blocking = eBlock);(ª“pej÷´