Domaine : RGSS
Niveau : Moyen Bon les fenêtres qu'est ce que c'est???
Ce sont les principales composants des écrans "systèmes"(menu, boite de dialogue, statut.. etc), donc des Scene_xxxx.
Je parlerai d'abord de l'interaction de la fenêtre dans une scène... puis de la création à proprement parler de celle-ci.
On a donc Scene_xxxx qui appelle une ou des Window_xxxx.
Elle les appelle en les attribuant à des variables de sa classe.
Exemple :
Class Scene_xxxx
def main
@fenetre = Window_xxxx.new
....
end
@fenetre est donc un objet "de type" Window_xxxx, appartenant à Scene_xxxx.
Par conséquent à chaque fois que l'on veut faire quelque chose avec cette fenetre, à partir de la Scene... il faut utiliser @fenetre.
Maintenant regardons dans Scene_xxxx, ce qui se passe avec @fenêtre.
class Scene_xxxx
def main
@fenetre = Window_xxxx.new
Graphics.transition
loop do
Graphics.update
Input.update
update
if $scene != self
break
end
end
Graphics.freeze
@fenetre.dispose
end
#-----------------------
def update
@fenetre.update
if trigger?(Input::B)
$scene= Scene_yyyy.new
end
end
end
Le principe de Scene_xxxx est d'afficher une fenetre de type Window_xxxx et de passer à Scene_yyyy si j'appuie sur la touche B.
On voit 2 autres interactions avec @fenetre :
le .dispose et le .update ^^
Le dispose permet de détruire la fenêtre ^^
et le update, de la mettre à jour.
Une Scene doit toujours avoir au moins ces 3 appels(new, dispose, et update) pour qu'une fenêtre fonctionne correctement.
Bon maintenant qu'on a vu comment ca marche dans Scene_xxxx,
regardons dans Window_xxxx.
Exemple de Window_xxxx :
class Window_xxxx < Window_Base
def initialize
super(0,0,320,240)
self.contents = Bitmap.new(width - 32, height - 32)
refresh
end
def refresh
self.contents.clear
end
end
Bon, alors qu'est ce qu'on a ???
Très important la définition de la classe :
class Window_xxxx < Window_Base
Le "< Window_Base" indique que Window_xxxx est une classe de type Window_Base, et que par conséquent elle hérite des méthodes et attributs de cette dernière.
Bon C'est pas le plus important dans notre tuto...^^
On a 2 fonctions obligatoires pour ce type de classe:
- Initialize
- Refresh
Initialize crée la fenêtre^^, elle appele la fonction Initialize de Window_Base, grâce au "SUPER" (super appelle la méthode de nom identique mais appartenant à la classe parente)
Ici le Initialize de Window_Base prend des paramètres qui sont, dans cet ordre :
- Position en X(0 à gauche)
- Position en Y(0 en haut)
- Largeur
- Hauteur
Dans mon exemple, toutes les fenêtres de types Window_xxxx s'afficheront en 0,0 avec une largeur de 320 et une hauteur de 240 (soit un quart de l'écran).
Puis je spécifie que contents est de type bitmap, qui a pour dimension la largeur - 32pixel et la hauteur - 32pixel.
Il est très important de créer ce bitmap, car c'est sur lui qu'on affichera le texte et autres. Ce bitmap, ce nomme contents, et on l'appelle grace à self.
Puis on appelle refresh...
refresh est la méthode où l'on spécifie le contenu de la fenêtre.
Ici notre fenêtre n'a aucun contenu, mais dispose quand meme d'une ligne de code :
self.contents.clear
Donc ^^ le clear permet d'effacer le contenu du bitmap^^ on le place généralement au début de refresh pour être sur de travailler sur une zone vide.
Si vous avez suivi ce que j'ai dit^^ vous comprendrez que clear est une méthode de la classe "Bitmap".
Bref...^^
Vous me dîtes : "c'est bien gentil une fenêtre vide... mais comment j'affiche mon texte ??"
Très simplement :
def refresh
self.contents.clear
self.contents.draw_text(10, 10, 80, 32, "EXP",0)
end
Grâce à la méthode "draw_text" de la classe ?????
.
.
.
.
.
Bitmap bien sur ! ( c'est bien ils suivent au fond de la classe ! )
Voyons ses paramètres :
- Position en X
- Position en Y
- Largeur en Pixel
- Hauteur en Pixel
- La chaine de caractère (String en anglais)
- L'alignement (optionnel) -> 0 à gauche, 1 centre, 2 à droite
Donc là rien de bien sérieux...
Maintenant vous me dite.. et là couleur ???
Ben il existe aussi une propriété de Bitmap , qui s'appelle Font (police), qui a elle meme une propriété qui s'appelle color (couleur).
Il suffit donc de changer cette propriété pour notre Bitmap, qui s'appelle ????
.
.
.
.
.
self.contents ! ^^
on obtient donc
def refresh
self.contents.clear
self.contents.font.color = normal_color
self.contents.draw_text(10, 10, 80, 32, "EXP",0)
end
Bon là vous me dîtes,"Treb arrete de nous prendre pour des idiots, j'ai jamais vu de couleur s'appeler "normal_color"..."
C'est vrai^^... c'est ici, un raccourci fourni par RMXP, qui évite de devoir écrire ceci :
Color.new(255, 255, 255, 255)
C'est en fait une méthode(appartenant à Window_Base)^^ qui ressemble à ceci:
def normal_color
return Color.new(255, 255, 255, 255)
end
Donc ^^ comment ca marche :
C'est du R,V,B (Rouge, vert, bleu) la dernière est le niveau de transparence, ce niveau est facultatif, si vous ne le spécifiez pas, il sera à 255.
On aurait donc pu faire celà dans notre refresh:
def refresh
self.contents.clear
self.contents.font.color = Color.new(255, 255, 255, 255)
self.contents.draw_text(10, 10, 80, 32, "EXP",0)
end
Ca aurait aussi bien marché...
Et pour changer la police de cette fenêtre??
Très facile :
au lieu de color c'est name...
self.contents.font.name="Comic sans MS"
Voilà on sait remplir notre bitmap avec du texte...
reste les images...
C'est pas beaucoup plus dur^^ vous inquiétez pas: :twisted:
bitmap = RPG::Cache.character(actor.character_name, actor.character_hue)
cw = bitmap.width / 4
ch = bitmap.height / 4
src_rect = Rect.new(0, 0, cw, ch)
self.contents.blt(x - cw / 2, y - ch, bitmap, src_rect)
Voici le code de la méthode Draw_actor_graphic(avec actor, x, et y comme paramètre).
Le processus est très simple.. ^^ je créer un nouveau bitmap temporaire, ici avec le fichier du perso passé en paramètre, puis je sélectionne avec un rectangle que je définie, la zone de ce bitmap "à copier"...
ici, notre rectangle se place en 0,0 et ne prend qu' 1/16ème(largeur/4 et hauteur/4) de l'image, ce qui correspond au perso vu de face à l'arrêt.
Enfin je fusionne, ce bout de bitmap copié, avec celui de la fenêtre à la position x et y. (ici la position est calculé en plus.. je vous passe ce détail)
Voilà ^^.. pour les images.
Bon reste à comprendre le update ?? parce que dans scene j'appelle @fenetre.update
mais y'a pas de update dans Window_xxxx
Ben ^^ Ruby est malin... si une méthode n'existe pas dans une classe il vérifie dans sa classe parente et utilise celle ci alors^^ mais si y en a aucune ... alors il plante^^
c'est pareil pour dispose... qui est définie dans Window_Base.
Ne définissez update que si vous en avez besoin... par exemple si y'a un truc pour la fenêtre qui se passe à chaque frame, ou un certain nombre de frame... et n'oubliez pas alors de passez un ptit appel "super"
Voili voulou;. j'espère avoir été assez clair...
PS : Bientot la partie 2 sur les Fenêtres avec curseur ..!!!
staiber