Utilisation GUI Tonyryu pour réaliser un HUD
Mer 18 Nov 2015 - 17:23
Attention : Ce tutoriel s'adresse à des programmeurs connaissant bien le JavaScript et sachant se débrouiller avec les librairies RpgMaker MV.
Ce tuto a pour but de montrer comment s'utilise mes Guis, afin de créer un petit hud, certes moche, mais fonctionnel directement sur la map.
Ces Guis étant en cours de développement, de nouveaux composants sont ajoutés d'une semaine à l'autre.
Pour ce tutoriel, je ferais évoluer le programme d'un bloc code à l'autre, sachant qu'à chaque fois il sera fonctionnel, mais augmentera en fonctionnalité au fur et à mesure. Je ne reprendrais pas le bloc commentaire du plugin, ne l'écrasez pas.
1 - Préparer son projet
- Créer un nouveau projet
- Et ajouter en plugin mes GUIs : Tonyryu_GUI.js sur BitBucket
- Créer un nouveau plugin qui vous servira de base : https://rpgmakervx.1fr1.net/t19009-creer-son-propre-plugin
- Créer un nouveau dossier /hud dans le dossier /img/pictures/, ce qui permettra d'y placer les images utilisées pour le hud
2 - Ajouter une nouvelle fenêtre
Pour plus de détails sur les Scene et les Window : https://rpgmakervx.1fr1.net/t19012-une-nouvelle-fenetre-et-son-ajout-sur-une-scene
- Ajouter cette image dans le dossier /img/pictures/hud/ :
- Ajouter ce code dans votre plugin :
Si vous lancer votre projet à ce stade, il n'y a rien de différent sur votre map ce qui est tout à fait normal, car nous n'avons pas ajouter notre fenêtre sur une Scene. Cependant, plusieurs points sont déjà à noter sur la création même de la fenêtre :
Window_HUD.prototype = Object.create(Window_Gui.prototype);
En effet, la fenêtre mère doit être Window_Gui, car elle contient des fonctions nécessaires à la gestion des composants ajoutés sur celle-ci.
this.addGui('guiFondHud', new Gui_Base({x:0, y:0, width:400, height:80, imageUrl:'img/pictures/hud/fond.png'}));
La fonction addGui, fait justement parti des fonctions présentes sur Window_Gui et permet d'ajouter un composant sur la fenêtre, en spécifiant son nom 'guiFondHud' et son composant, nouvelle instance de Gui_Base.
Le nom du composant doit être unique sur la fenêtre, c'est à dire que vous ne pouvez pas avoir 2 composants avec le même nom sur une même fenêtre.
Le constructeur du composant Gui_Base peut prendre en paramètre un objet Json de configuration, dont voici la liste des options :
- active : permet d'activer le composant (défaut : true)
- x : coordonnée x du composant sur la fenêtre (défaut : 0)
- y : coordonnée x du composant sur la fenêtre (défaut : 0)
- width : Largeur du composant (obligatoire)
- height : hauteur du composant (obligatoire)
- imageUrl : url de l'image utilisée dans le composant (défaut : null)
- rectBitmap : objet Json (x,y,width, height) permettant de définir le fragment de l'image à intégrer dans le composant (défaut ; toute l'image) (defaut : null)
- backColor : couleur de fond du composant (défaut : '')
- frameColor : couleur du cadre du composant (défaut : '')
- text : texte dans le composant (defaut : définit par la police par défaut du bitmap)
- textColor : couleur du texte (defaut : définit par la police par défaut du bitmap)
- textAlign : alignement du texte (defaut : définit par la police par défaut du bitmap)
- fontFace : Nom de la police d'écriture (defaut : définit par la police par défaut du bitmap)
- fontSize : Taille de la police d'écriture (defaut : définit par la police par défaut du bitmap)
- fontItalic : Flag indiquant si le texte est écrit en italique (defaut : définit par la police par défaut du bitmap)
- padding : décalage du contenu dans le composant haut, bas gauche et droite (defaut : 0)
- visible : flag de visibilité du composant (defaut : true)
Le composant ajouté dans le code ci-dessus contient ces options :
x:0
y:0
width:400
height:80
imageUrl:'img/pictures/hud/fond.png'
Il sera donc positionné en 0,0 sur la fenêtre avec une largeur de 400pxl, une hauteur de 80pxl et contiendra l'image se trouvant à l'url 'img/pictures/hud/fond.png'
Il faut aussi savoir que Gui_Base, possède des événements qui se déclenche dans certaines conditions et sur lesquels on peut ajouter des appels de fonctions, mais nous verrons ce plus tard.
- onrollover
- onrollout
- onfocusin
- onfocusin
- onclick
3 - Modifier Scene_Map pour utiliser la nouvelle fenêtre
Tout d'abord, sachez bien que la notion de profondeur (Z) pour les sprite, view, fenêtres, n'existe plus sur ce RpgMaker et que l'ordre d'affichage des éléments graphiques est très très important. Je ne rentrerai pas dans le détail dans ce tuto, car j'estime que ça nécessite une explication à part entière dans un autre tuto. Mais dans notre contexte, le choix de rattachement de la fenêtre sur l'arbre d'affichage est important, et dans Scene_Map, il y a déjà plein de chose.
J'ai pris le choix de l'ajouter directement après le spriteset_map, qui contient la map tileset, les event, les personnages... et avant toutes les autres fenêtres.
Quoi de nouveau?
- La surcharge de la fonction Scene_Map.prototype.createSpriteset pour ajouter l'appel à la nouvelle fonction Scene_Map.prototype.createWindowHud qui ajoutera la fenêtre dans l'arbre d'affichage de la scene via addChild et non plus addWindow.
Si vous lancez le projet, vous voyez maintenant le fond du hud ajouté sur la scene_map.
4 - Ajouter un bouton
- Ajouter cette image dans le dossier /img/pictures/hud/ :
Cette image comporte les 3 états d'un bouton, (repos, survol, clic) chacune des images doivent avoir la même dimension, le composant doit donc avoir pour dimension, la largeur de l'image et la hauteur divisé par 3 de l'image
Une seule ligne de code pour ajouter un bouton :
this.addGui('guiButton', new Gui_Button({x:67, y:10, width:60, height:60, imageUrl:'img/pictures/hud/btn_menu.png'}));
Il n'y a que très peu de différence entre le Gui_Base et le Gui_Button. Seule la gestion de la fragmentation de l'image est ajoutée en fonction de l'état du composant.
Donc, si on lance le projet, nous avons maintenant le bouton d'ajouté, et si l'on clic dessus, rien ne se passe, enfin si, et quelque chose de plutôt génant. En effet, le clic de la souris est géré pour déplacer notre personnage.
5 - Gérer des événements des composants
On va donc commencer par bloquer cela quant la souris est sur le composant du hud :
Alors, on commence a rentrer dans le dur, là.
- on ajoute une variable (this._onHud) qui va permettre de gérer le fait que la souris est sur le hud ou non, dans la fonction createWindowHud.
- on ajoute une nouvelle fonction setOnHud à Scene_Map, prenant en paramètre un booléen qui sera utilisé pour changer la valeur de la variable _onHud
- on surcharge la fonction isMapTouchOk de Scene_Map, afin de retourner faux si la variable _onHud vaut vrai, ce qui permettra de ne pas gérer le clic de souris dans ce cas.
- et l'on ajoute des créations de Handle dans la fonction createWindowHud de Scene_Map, sur les événements onrollover et onrollout du composant 'guiFondHud', pour appeler la fonction setOnHud avec un paramètre différent selon l'événement.
Si l'on test le projet, on constate bien que le clic de souris pour le déplacement n'est géré que si la souris est hors du hud.
Il nous reste donc une petite chose à faire, ajouter une action lors du clic sur le bouton. On va dire que celui-ci, sert a ouvrir le menu.
on a donc ajouté une nouvelle fonction clickBtnMenu sur Scene_Map permettant d'ouvrir le menu principal, et on l'a liée a l'événement onclick du composant 'guiButtonMenu'
Voila qui clos ce tutoriel, n'hésitez pas à poser des questions si vous n'avez pas tout compris. Attention, je rappel qu'il n'est pas destiné à des novices, posez des questions pertinentes.
Ce tuto a pour but de montrer comment s'utilise mes Guis, afin de créer un petit hud, certes moche, mais fonctionnel directement sur la map.
Ces Guis étant en cours de développement, de nouveaux composants sont ajoutés d'une semaine à l'autre.
Pour ce tutoriel, je ferais évoluer le programme d'un bloc code à l'autre, sachant qu'à chaque fois il sera fonctionnel, mais augmentera en fonctionnalité au fur et à mesure. Je ne reprendrais pas le bloc commentaire du plugin, ne l'écrasez pas.
1 - Préparer son projet
- Créer un nouveau projet
- Et ajouter en plugin mes GUIs : Tonyryu_GUI.js sur BitBucket
- Créer un nouveau plugin qui vous servira de base : https://rpgmakervx.1fr1.net/t19009-creer-son-propre-plugin
- Créer un nouveau dossier /hud dans le dossier /img/pictures/, ce qui permettra d'y placer les images utilisées pour le hud
2 - Ajouter une nouvelle fenêtre
Pour plus de détails sur les Scene et les Window : https://rpgmakervx.1fr1.net/t19012-une-nouvelle-fenetre-et-son-ajout-sur-une-scene
- Ajouter cette image dans le dossier /img/pictures/hud/ :
- Ajouter ce code dans votre plugin :
- Code:
(function() {
function Window_HUD() {
this.initialize.apply(this, arguments);
}
Window_HUD.prototype = Object.create(Window_Gui.prototype);
Window_HUD.prototype.constructor = Window_HUD;
Window_HUD.prototype.initialize = function() {
Window_Gui.prototype.initialize.call(this, 0, 0, Graphics.width, Graphics.height);
this.padding = 0;
this.opacity = 0;
this.active = true;
this.addGui('guiFondHud', new Gui_Base({x:0, y:0, width:400, height:80, imageUrl:'img/pictures/hud/fond.png'}));
};
})();
Si vous lancer votre projet à ce stade, il n'y a rien de différent sur votre map ce qui est tout à fait normal, car nous n'avons pas ajouter notre fenêtre sur une Scene. Cependant, plusieurs points sont déjà à noter sur la création même de la fenêtre :
Window_HUD.prototype = Object.create(Window_Gui.prototype);
En effet, la fenêtre mère doit être Window_Gui, car elle contient des fonctions nécessaires à la gestion des composants ajoutés sur celle-ci.
this.addGui('guiFondHud', new Gui_Base({x:0, y:0, width:400, height:80, imageUrl:'img/pictures/hud/fond.png'}));
La fonction addGui, fait justement parti des fonctions présentes sur Window_Gui et permet d'ajouter un composant sur la fenêtre, en spécifiant son nom 'guiFondHud' et son composant, nouvelle instance de Gui_Base.
Le nom du composant doit être unique sur la fenêtre, c'est à dire que vous ne pouvez pas avoir 2 composants avec le même nom sur une même fenêtre.
Le constructeur du composant Gui_Base peut prendre en paramètre un objet Json de configuration, dont voici la liste des options :
- active : permet d'activer le composant (défaut : true)
- x : coordonnée x du composant sur la fenêtre (défaut : 0)
- y : coordonnée x du composant sur la fenêtre (défaut : 0)
- width : Largeur du composant (obligatoire)
- height : hauteur du composant (obligatoire)
- imageUrl : url de l'image utilisée dans le composant (défaut : null)
- rectBitmap : objet Json (x,y,width, height) permettant de définir le fragment de l'image à intégrer dans le composant (défaut ; toute l'image) (defaut : null)
- backColor : couleur de fond du composant (défaut : '')
- frameColor : couleur du cadre du composant (défaut : '')
- text : texte dans le composant (defaut : définit par la police par défaut du bitmap)
- textColor : couleur du texte (defaut : définit par la police par défaut du bitmap)
- textAlign : alignement du texte (defaut : définit par la police par défaut du bitmap)
- fontFace : Nom de la police d'écriture (defaut : définit par la police par défaut du bitmap)
- fontSize : Taille de la police d'écriture (defaut : définit par la police par défaut du bitmap)
- fontItalic : Flag indiquant si le texte est écrit en italique (defaut : définit par la police par défaut du bitmap)
- padding : décalage du contenu dans le composant haut, bas gauche et droite (defaut : 0)
- visible : flag de visibilité du composant (defaut : true)
Le composant ajouté dans le code ci-dessus contient ces options :
x:0
y:0
width:400
height:80
imageUrl:'img/pictures/hud/fond.png'
Il sera donc positionné en 0,0 sur la fenêtre avec une largeur de 400pxl, une hauteur de 80pxl et contiendra l'image se trouvant à l'url 'img/pictures/hud/fond.png'
Il faut aussi savoir que Gui_Base, possède des événements qui se déclenche dans certaines conditions et sur lesquels on peut ajouter des appels de fonctions, mais nous verrons ce plus tard.
- onrollover
- onrollout
- onfocusin
- onfocusin
- onclick
3 - Modifier Scene_Map pour utiliser la nouvelle fenêtre
Tout d'abord, sachez bien que la notion de profondeur (Z) pour les sprite, view, fenêtres, n'existe plus sur ce RpgMaker et que l'ordre d'affichage des éléments graphiques est très très important. Je ne rentrerai pas dans le détail dans ce tuto, car j'estime que ça nécessite une explication à part entière dans un autre tuto. Mais dans notre contexte, le choix de rattachement de la fenêtre sur l'arbre d'affichage est important, et dans Scene_Map, il y a déjà plein de chose.
J'ai pris le choix de l'ajouter directement après le spriteset_map, qui contient la map tileset, les event, les personnages... et avant toutes les autres fenêtres.
- Code:
(function() {
function Window_HUD() {
this.initialize.apply(this, arguments);
}
Window_HUD.prototype = Object.create(Window_Gui.prototype);
Window_HUD.prototype.constructor = Window_HUD;
Window_HUD.prototype.initialize = function() {
Window_Gui.prototype.initialize.call(this, 0, 0, Graphics.width, Graphics.height);
this.padding = 0;
this.opacity = 0;
this.active = true;
this.addGui('guiFondHud', new Gui_Base({x:0, y:0, width:400, height:80, imageUrl:'img/pictures/hud/fond.png'}));
};
var _Scene_Map_createSpriteset = Scene_Map.prototype.createSpriteset;
Scene_Map.prototype.createSpriteset = function() {
_Scene_Map_createSpriteset.call(this);
this.createWindowHud();
};
Scene_Map.prototype.createWindowHud = function() {
this._hudWindow = new Window_HUD();
this.addChild(this._hudWindow);
};
})();
Quoi de nouveau?
- La surcharge de la fonction Scene_Map.prototype.createSpriteset pour ajouter l'appel à la nouvelle fonction Scene_Map.prototype.createWindowHud qui ajoutera la fenêtre dans l'arbre d'affichage de la scene via addChild et non plus addWindow.
Si vous lancez le projet, vous voyez maintenant le fond du hud ajouté sur la scene_map.
4 - Ajouter un bouton
- Ajouter cette image dans le dossier /img/pictures/hud/ :
Cette image comporte les 3 états d'un bouton, (repos, survol, clic) chacune des images doivent avoir la même dimension, le composant doit donc avoir pour dimension, la largeur de l'image et la hauteur divisé par 3 de l'image
- Code:
(function() {
function Window_HUD() {
this.initialize.apply(this, arguments);
}
Window_HUD.prototype = Object.create(Window_Gui.prototype);
Window_HUD.prototype.constructor = Window_HUD;
Window_HUD.prototype.initialize = function() {
Window_Gui.prototype.initialize.call(this, 0, 0, Graphics.width, Graphics.height);
this.padding = 0;
this.opacity = 0;
this.active = true;
this.addGui('guiFondHud', new Gui_Base({x:0, y:0, width:400, height:80, imageUrl:'img/pictures/hud/fond.png'}));
this.addGui('guiButtonMenu', new Gui_Button({x:67, y:10, width:60, height:60, imageUrl:'img/pictures/hud/btn_menu.png'}));
};
var _Scene_Map_createSpriteset = Scene_Map.prototype.createSpriteset;
Scene_Map.prototype.createSpriteset = function() {
_Scene_Map_createSpriteset.call(this);
this.createWindowHud();
};
Scene_Map.prototype.createWindowHud = function() {
this._hudWindow = new Window_HUD();
this.addChild(this._hudWindow);
};
})();
Une seule ligne de code pour ajouter un bouton :
this.addGui('guiButton', new Gui_Button({x:67, y:10, width:60, height:60, imageUrl:'img/pictures/hud/btn_menu.png'}));
Il n'y a que très peu de différence entre le Gui_Base et le Gui_Button. Seule la gestion de la fragmentation de l'image est ajoutée en fonction de l'état du composant.
Donc, si on lance le projet, nous avons maintenant le bouton d'ajouté, et si l'on clic dessus, rien ne se passe, enfin si, et quelque chose de plutôt génant. En effet, le clic de la souris est géré pour déplacer notre personnage.
5 - Gérer des événements des composants
On va donc commencer par bloquer cela quant la souris est sur le composant du hud :
- Code:
(function() {
function Window_HUD() {
this.initialize.apply(this, arguments);
}
Window_HUD.prototype = Object.create(Window_Gui.prototype);
Window_HUD.prototype.constructor = Window_HUD;
Window_HUD.prototype.initialize = function() {
Window_Gui.prototype.initialize.call(this, 0, 0, Graphics.width, Graphics.height);
this.padding = 0;
this.opacity = 0;
this.active = true;
this.addGui('guiFondHud', new Gui_Base({x:0, y:0, width:400, height:80, imageUrl:'img/pictures/hud/fond.png'}));
this.addGui('guiButtonMenu', new Gui_Button({x:67, y:10, width:60, height:60, imageUrl:'img/pictures/hud/btn_menu.png'}));
};
var _Scene_Map_createSpriteset = Scene_Map.prototype.createSpriteset;
Scene_Map.prototype.createSpriteset = function() {
_Scene_Map_createSpriteset.call(this);
this.createWindowHud();
};
Scene_Map.prototype.createWindowHud = function() {
this._onHud = false;
this._hudWindow = new Window_HUD();
this._hudWindow.setHandlerGui('guiFondHud', 'onrollover', this.setOnHud.bind(this, true));
this._hudWindow.setHandlerGui('guiFondHud', 'onrollout', this.setOnHud.bind(this, false));
this.addChild(this._hudWindow);
};
var _Scene_Map_isMapTouchOk = Scene_Map.prototype.isMapTouchOk;
Scene_Map.prototype.isMapTouchOk = function() {
return !this._onHud && _Scene_Map_isMapTouchOk.call(this);
};
Scene_Map.prototype.setOnHud = function(pOnHud) {
this._onHud = pOnHud;
};
})();
Alors, on commence a rentrer dans le dur, là.
- on ajoute une variable (this._onHud) qui va permettre de gérer le fait que la souris est sur le hud ou non, dans la fonction createWindowHud.
- on ajoute une nouvelle fonction setOnHud à Scene_Map, prenant en paramètre un booléen qui sera utilisé pour changer la valeur de la variable _onHud
- on surcharge la fonction isMapTouchOk de Scene_Map, afin de retourner faux si la variable _onHud vaut vrai, ce qui permettra de ne pas gérer le clic de souris dans ce cas.
- et l'on ajoute des créations de Handle dans la fonction createWindowHud de Scene_Map, sur les événements onrollover et onrollout du composant 'guiFondHud', pour appeler la fonction setOnHud avec un paramètre différent selon l'événement.
Si l'on test le projet, on constate bien que le clic de souris pour le déplacement n'est géré que si la souris est hors du hud.
Il nous reste donc une petite chose à faire, ajouter une action lors du clic sur le bouton. On va dire que celui-ci, sert a ouvrir le menu.
- Code:
(function() {
function Window_HUD() {
this.initialize.apply(this, arguments);
}
Window_HUD.prototype = Object.create(Window_Gui.prototype);
Window_HUD.prototype.constructor = Window_HUD;
Window_HUD.prototype.initialize = function() {
Window_Gui.prototype.initialize.call(this, 0, 0, Graphics.width, Graphics.height);
this.padding = 0;
this.opacity = 0;
this.active = true;
this.addGui('guiFondHud', new Gui_Base({x:0, y:0, width:400, height:80, imageUrl:'img/pictures/hud/fond.png'}));
this.addGui('guiButtonMenu', new Gui_Button({x:67, y:10, width:60, height:60, imageUrl:'img/pictures/hud/btn_menu.png'}));
};
var _Scene_Map_createSpriteset = Scene_Map.prototype.createSpriteset;
Scene_Map.prototype.createSpriteset = function() {
_Scene_Map_createSpriteset.call(this);
this.createWindowHud();
};
Scene_Map.prototype.createWindowHud = function() {
this._onHud = false;
this._hudWindow = new Window_HUD();
this._hudWindow.setHandlerGui('guiFondHud', 'onrollover', this.setOnHud.bind(this, true));
this._hudWindow.setHandlerGui('guiFondHud', 'onrollout', this.setOnHud.bind(this, false));
this._hudWindow.setHandlerGui('guiButtonMenu', 'onclick', this.clickBtnMenu.bind(this));
this.addChild(this._hudWindow);
};
var _Scene_Map_isMapTouchOk = Scene_Map.prototype.isMapTouchOk;
Scene_Map.prototype.isMapTouchOk = function() {
return !this._onHud && _Scene_Map_isMapTouchOk.call(this);
};
Scene_Map.prototype.setOnHud = function(pOnHud) {
this._onHud = pOnHud;
};
Scene_Map.prototype.clickBtnMenu = function() {
SceneManager.push(Scene_Menu);
};
})();
on a donc ajouté une nouvelle fonction clickBtnMenu sur Scene_Map permettant d'ouvrir le menu principal, et on l'a liée a l'événement onclick du composant 'guiButtonMenu'
Voila qui clos ce tutoriel, n'hésitez pas à poser des questions si vous n'avez pas tout compris. Attention, je rappel qu'il n'est pas destiné à des novices, posez des questions pertinentes.
- diewebMembre
- Nombre de messages : 4
Distinction : aucune
Date d'inscription : 07/08/2016
Re: Utilisation GUI Tonyryu pour réaliser un HUD
Ven 12 Aoû 2016 - 14:12
superbe tuto, merci.
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum