Bonsoir, en ce moment, c'est
Nicert qui reprend forme, et surtout le
GUI des dialogues qui est une reprise de celui de
Discworld, ou celui de
SAM & MAX si vous ne connaissez pas, bref avant de faire les dialogues il faudrait faire en sorte que quand on pointe sur un des boutons : il y ait une animation.
Or, il n'y a pas de fonctionnalité qui permettent de mettre une animation aux les boutons avec
AGS.
Ça ne veut pas dire que c'est impossible
![^^](/users/3313/62/11/77/smiles/697251.png)
Par contre, ce n'est peut être pas très propre je pense, mais au moins, on peut le faire, je vais essayé de vous expliquer ma méthode :
1) On importe tous les frames d'un coup dans le sprites manager :Vu qu'on ne peut pas faire d'animation sur les boutons, on ne peut pas mentionner de
view à
AGS, donc notre seul moyen de pouvoir faire une animation est d'importer dans l'ordre toutes les frames des boutons, comme ceci, avec 4 boutons animés dans mon cas :
![[Tuto] Animer un bouton 110](https://i.servimg.com/u/f83/12/23/92/43/110.png)
Dans le
cadre en rouge, c'est ce qu'on ne doit pas faire, c'est-à-dire ne pas intercaler les frames des autres boutons, on met toutes les frames d'une animation à la fois, comme dans le
cadre en vert ![^^](/users/3313/62/11/77/smiles/697251.png)
Notez aussi que si l'animation du bouton nécessite plusieurs fois la même
frame, il faut alors la réimporter, comme si c'était une
loop en gros.
2) Passer par le Global Script :Le secret en faite d'une animation, c'est la succession rapide d'images pour que l'œil ne voit plus qu'un mouvement fluide.
Donc ce que nous allons essayé de faire, c'est de faire défiler chaque image très vite. On a donc ce plan à programmer :
- Dès que l'on pointe sur un bouton, on affiche la frame suivante correspondante.
- On met une tempo pour ne pas avoir une animation trop rapide.
- On affiche alors la frame suivante dès que la tempo est finie.
- On remet la tempo en route.
- On répète l'opération tant qu'il y a de frames...
- Dès que l'on a affiché la dernière frame de l'animation, on remet à la première frame.
Si le
curseur pointe toujours sur le
bouton, l'animation se répète à nouveau et ce jusqu'à ce qu'on s'en aille.
Si on est hors du
bouton, on remet également au
bouton sa première
frame, sinon, quand on repointerait dessus, on reviendrait à la dernière frame affichée...
Direction repeatedly_execute() :Cette fonction s'exécute continuellement, donc il est possible de savoir si le curseur pointe sur "rien" ou sur un "bouton".
On va créer une variable qui nous informera quel bouton est pointé par la souris, si, bien sûr, la souris pointe sur un bouton, sinon la variable serait égal à
nullLa structure d'un bouton est
Button et la structure d'un outil de
GUI est
GUIControl.
Donc notre variable s'appellera
OverGUIControl et :
OverGUIControl = le
GUIControl que pointe la souris.
Pour récupérer le
GUIControl on utilise la fonction
GetAtScreenXY et on indique à quelles coordonnées on veut récupérer l'information, il s'agit bien sûr des coordonnées de la souris
![^^](/users/3313/62/11/77/smiles/697251.png)
, ce qui nous donne :
- Code:
-
Button OverGUIControl = GUIControl.GetAtScreenXY(mouse.x, mouse.y);
Ensuite on doit demander si
OverGUIControl pointe bien un bouton, par exemple le bouton
PointDIntero :
- Code:
-
if(OverGUIControl == PointDIntero)
{
}
Pour écrire l'intérieur de ce bloc de code, il faut d'abord revoir le plan de tout à l'heure :
- Citation :
- Dès que l'on pointe sur un bouton, on affiche la frame suivante correspondante
Pour passer à la frame suivante, on incrémente la variable
MouseOverGraphic du bouton, donc :
- Code:
-
if(OverGUIControl == PointDIntero)
{
PointDIntero.MouseOverGraphic++;
}
Bien sûr il faut que dans les propriétés, on indique la première frame de notre bouton :
![[Tuto] Animer un bouton 210](https://i.servimg.com/u/f83/12/23/92/43/210.png)
C'est loin d'être fini.
Ici notre bouton va dérouler l'animation puis dérouler celles des boutons suivants, à cause de l'incrémentation, il faut donc empêcher l'incrémentation quand on a arrive à la dernière frame de l'animation du notre bouton actuel, qui est la frame 21 dans notre cas :
- Code:
-
if(OverGUIControl == PointDIntero)
{
if(PointDIntero.MouseOverGraphic < 21)
{
PointDIntero.MouseOverGraphic++;
}
}
Cette condition permet d'arrêter l'animation quand il faut, mais elle ne permet pas de la remettre, pour la remettre il faut mettre une condition quand on EST sur la dernière, donc c'est le contraire de la condition
if(OverGUIControl == PointDIntero) ; on a donc juste à mettre un
else :
- Code:
-
if(OverGUIControl == PointDIntero)
{
if(PointDIntero.MouseOverGraphic < 21)
{
PointDIntero.MouseOverGraphic++;
}
else
{
PointDIntero.MouseOverGraphic = 12;
}
}
Et voilà, notre animation s'exécute en boucle jusqu'à ce qu'on s'en aille du bouton.
3) Temporisation :Pour l'instant notre animation va trop vite tellement il y a de cycles dans la fonction
repeatedly_execute(), donc moi j'ai opter pour mettre un timer, mais je sais pas si c'est adéquat.
- Spoiler:
On verra ce qu'en pense Pti Dej :rollingeyes:
Donc après avoir mis la nouvelle frame on active la tempo dès qu'on pointe sur le bouton et quand on affiche une nouvelle frame :
- Code:
-
function repeatedly_execute() {
GUIControl *OverGUIControl = GUIControl.GetAtScreenXY(mouse.x, mouse.y);
SetTimer(1, 10);
if(OverGUIControl == PointDIntero)
{
if(PointDIntero.MouseOverGraphic < 21)
{
PointDIntero.MouseOverGraphic++;
SetTimer(1, 10);
}
else
{
PointDIntero.MouseOverGraphic = 12;
}
}
Et maintenant la nouvelle frame ne peut s'afficher que quand la tempo est finie :
- Code:
-
if(PointDIntero.MouseOverGraphic < 21)
{
if(IsTimerExpired(1))
{
PointDIntero.MouseOverGraphic++;
SetTimer(1, 10);
}
}
Maintenant il va falloir empêcher de réenclencher tout le temps la tempo, sinon, il n'y aura pas d'animation du tout.
Donc on crée une variable de type
bool qui dit si la tempo est utilisée on ne la réinitialise pas sinon on le fait :
- Code:
-
if(utilisee == false)
{
SetTimer(1, 10);
utilisee = true;
}
Ce type de condition permet de n'enclencher qu'une fois le timer quand on pointe sur le bouton. Bien sûr en haut du Global Script, ou dans l'onglet
Global variables vous auriez déclaré la variables utilisee :
- Code:
-
// main global script file
bool utilisee = false;
Maintenant notre animation est temporisée.
4) Réinitialiser les animations quand OverGUIControl ne pointe pas sur un bouttonTout est dans le titre, si le curseur ne pointe pas sur un bouton alors on assigne à chaque bouton (si il y en a plusieurs) leur frame de départ, donc on ajoute un
else à la condition
if(OverGUIControl == PointDIntero) ou alors si on a plusieurs bouttons on met :
- Code:
-
if(OverGUIControl == null)
{
...
}
Pour mettre les frames de départ c'est la même fonction que tout à l'heure, mais au lieu de l'incrémenter on l'assigne carrément
![^^](/users/3313/62/11/77/smiles/697251.png)
:
- Code:
-
if(OverGUIControl == null)
{
PointDIntero.MouseOverGraphic = 12;
AutreBouton.MouseOverGraphic = 22;
...
utilisee = false;
}
Comme vous avez pu le voir utilisee faut maintenant
false car quand on ne pointe pas sur un bouton on n'utilise pas de timer, compris ?
![^^](/users/3313/62/11/77/smiles/697251.png)
Voilà, c'est tout ce qu'il faut faire pour un seul bouton, après pour faire ça dans chaque bouton on met un
else if(OverGUIControl == NouveauBouton) et on modifie les valeurs des nouvelles et dernières frames, par exemple, voilà mon code final avec un bouton
Mains et un bouton
Blague :
- Spoiler:
- Code:
-
function repeatedly_execute() {
// put anything you want to happen every game cycle, even when
// the game is paused, here
if (IsGamePaused() == 1) return;
GUIControl *OverGUIControl = GUIControl.GetAtScreenXY(mouse.x, mouse.y);
if(utilisee == false)
{
if(OverGUIControl == Mains) SetTimer(1, 35);
else SetTimer(1, 10);
utilisee = true;
}
if(OverGUIControl == PointDIntero)
{
if(PointDIntero.MouseOverGraphic < 21)
{
if(IsTimerExpired(1))
{
PointDIntero.MouseOverGraphic++;
SetTimer(1, 10);
}
}
else
{
PointDIntero.MouseOverGraphic = 12;
}
}
else if(OverGUIControl == Blague)
{
if(Blague.MouseOverGraphic < 25)
{
if(IsTimerExpired(1))
{
Blague.MouseOverGraphic++;
SetTimer(1, 10);
}
}
else
{
Blague.MouseOverGraphic = 22;
}
}
else if(OverGUIControl == Mains)
{
if(Mains.MouseOverGraphic < 27)
{
if(IsTimerExpired(1))
{
Mains.MouseOverGraphic++;
SetTimer(1, 35);
}
}
else
{
Mains.MouseOverGraphic = 26;
}
}
else
{
utilisee = false;
PointDIntero.MouseOverGraphic = 12;
Mains.MouseOverGraphic = 26;
Blague.MouseOverGraphic = 22;
}
}
5) En faire une fonction :Maintenant pour aérer un peu le code (il ne faut pas trop écrire dans le repeatedly_execute()) on va copier tout ça dans une autre fonction, la fonction
animerBouton() qui prendra en compte le bouton que l'on pointe, direction
Header du Global Script :
- Code:
-
import function animerBouton(GUIControl);
Ensuite dans le global script :
- Code:
-
function animerBouton(GUIControl)
{
copié/collé de ce qu'on a écrit.
}
Il nous reste plus que ça dans le repeatedly_execute() :
- Spoiler:
- Code:
-
function repeatedly_execute() {
// put anything you want to happen every game cycle, even when
// the game is paused, here
if (IsGamePaused() == 1) return;
GUIControl *OverGUIControl = GUIControl.GetAtScreenXY(mouse.x, mouse.y);
animerBouton(OverGUIControl); // on fait continuellement appel à cette fonction.
}
Voilà j'espère que ça vous a plu et que j'ai été clair, si vous avez des questions ou des suggestions, notamment au niveau de la tempo, je suis preneur, et je vous souhaite une bonne programmation
See you again soon