Forum d'entraide à la création de jeux d'aventure
 
PortailPortail  AccueilAccueil  RechercherRechercher  S'enregistrerS'enregistrer  Connexion  

 

 [Tuto] Animer un bouton

Aller en bas 
4 participants
AuteurMessage
Crazy Legs
Grand Cliqueur Royal
Grand Cliqueur Royal
Crazy Legs


Nombre de messages : 1513

Age : 31

Localisation : La Rochelle

Date d'inscription : 09/01/2008


[Tuto] Animer un bouton Empty
MessageSujet: [Tuto] Animer un bouton   [Tuto] Animer un bouton EmptyMer 1 Juil 2009 - 23:03

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 ^^
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

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 ^^

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 à null

La 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 ^^ , 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

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:

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 boutton

Tout 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 ^^ :

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 ? ^^

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:

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:

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 grand sourire

See you again soon
Revenir en haut Aller en bas
Shai-la
Ouvrière en Chef de la Grande Tasse Bleue
Ouvrière en Chef de la Grande Tasse Bleue
Shai-la


Nombre de messages : 6018

Age : 46

Localisation : Montpellier

Date d'inscription : 17/04/2006


[Tuto] Animer un bouton Empty
MessageSujet: Re: [Tuto] Animer un bouton   [Tuto] Animer un bouton EmptyJeu 2 Juil 2009 - 6:18

Faut vraiment vouloir animer son bouton ! :ihih:
Mais c'est intéressant ! ^^
Revenir en haut Aller en bas
http://marionpoinsot.fr/video
Crazy Legs
Grand Cliqueur Royal
Grand Cliqueur Royal
Crazy Legs


Nombre de messages : 1513

Age : 31

Localisation : La Rochelle

Date d'inscription : 09/01/2008


[Tuto] Animer un bouton Empty
MessageSujet: Re: [Tuto] Animer un bouton   [Tuto] Animer un bouton EmptyJeu 2 Juil 2009 - 14:41

Merci, je vais essayer d'en faire un module si j'y arrive et si ça marche bien.
Ça sera plus simple :P
Revenir en haut Aller en bas
Asraroth
Disciple de la Grande Tasse Bleue
Disciple de la Grande Tasse Bleue
Asraroth


Nombre de messages : 1451

Age : 49

Date d'inscription : 20/10/2006


[Tuto] Animer un bouton Empty
MessageSujet: Re: [Tuto] Animer un bouton   [Tuto] Animer un bouton EmptyJeu 2 Juil 2009 - 21:26

ah oui ! çà serait + sympa en forme de module (si c'est possible). Parce que là, c'est vrai que c'est un peu compliqué à mettre en œuvre ^^

j'ai 2 suggestions à te soumettre p our améliorer et simplifier :

1°/ pour éviter d'utiliser un timer AGS, tu peux prendre une variable "Int chrono;" et faire une "chrono++;" dans le "repeatdly_exevute"... Quand ce chrono est arrivé à X (+ ou - pour régler la vitesse), tu changes l'image et tu remets "chrono" à 0.
par exemple :
Code:
chrono++;
if (chrono == 10) {
  chrono = 0;
  // image suivante sur le bouton
}

2°/ Encore + fort... pour ne pas avoir à mettre obligatoirement les sprites les uns à coté des autres (et surtout, si t'as besoin d'en ajouter par la suite), je te propose d'utiliser un tableau (array). Chaque "case" du tableau peut contenir un numéro de sprite. Par exemple :
Code:
int animbouton[10];
int i = 0;
animbouton[0] = 5;
animbouton[1] = 8;
animbouton[2] = 3;
animbouton[3] = 9;
animbouton[4] = 1;
etc...

function repeatdly()
  chrono++;
  if (chrono==10){
    i++;
    if (i == 5) i = 0;
    monbouton.graphic = animbouton[i];
  }
}

3°/ Bonus : tu peux ajouter un autre tableau en parallèle qui donne la durée d'affichage du sprite...
Code:
int animtimer[10];
animtimer[0] = 10;
animtimer[1] = 10;
animtimer[2] = 15;
animtimer[3] = 20;
animtimer[4] = 10;
function repeatdly()
  chrono++;
  if (chrono>=animtimer[i]){
  etc...
}

Enfin, bonne idée que t'as eu, d'animer les boutons d'un GUI.. au boulot pour faire un module ! [Tuto] Animer un bouton 114419
Revenir en haut Aller en bas
Crazy Legs
Grand Cliqueur Royal
Grand Cliqueur Royal
Crazy Legs


Nombre de messages : 1513

Age : 31

Localisation : La Rochelle

Date d'inscription : 09/01/2008


[Tuto] Animer un bouton Empty
MessageSujet: Re: [Tuto] Animer un bouton   [Tuto] Animer un bouton EmptyJeu 2 Juil 2009 - 21:54

Alors déjà merci pour ce commentaire et oui je vais essayer d'en faire un module :

Alors premièrement l'idée d'une variable m'est bien sûr venu en premier, mais le problème c'est qu'il faudrait utilisé un long et la condition ressemblerait plus à ça :

Code:
chrono++;
if (chrono == 1500000) {
  chrono = 0;
  // image suivante sur le bouton
}

mais sinon c'est vrai que c'est une meilleure solution car ça empêcherait de priver à l'utilisateur un timer, donc je vais opter pour ça oui...

Pour ce qui est des tableaux je sais pô trop...
Déjà si je le faisait je mettrais un tableau dynamique, ça serait plus juste parce qu'on ne pourrait pas savoir combien de frames contiendraient la loop virtuelle si je puis dire.
On peut toujours le mettre au cas où l'utilisateur aurait fait une erreur, bon je pense que oui alors clin d'oeil

Pour ce qui est du animTimer j'ai plutôt pensé à le mettre en argument dans une des fonctions du modules.

Merci, beaucoup, maintenant comme tu le dit => :travaille:
Revenir en haut Aller en bas
Asraroth
Disciple de la Grande Tasse Bleue
Disciple de la Grande Tasse Bleue
Asraroth


Nombre de messages : 1451

Age : 49

Date d'inscription : 20/10/2006


[Tuto] Animer un bouton Empty
MessageSujet: Re: [Tuto] Animer un bouton   [Tuto] Animer un bouton EmptyJeu 2 Juil 2009 - 22:07

un Int suffira... la fonction "reapitidly" est exécutée environ 40 fois par secondes... si tu mets 1.500.000, tu vas attendre 37.500 secondes entre chaque changement de sprite... pas vraiment fluide ! XD
Revenir en haut Aller en bas
Crazy Legs
Grand Cliqueur Royal
Grand Cliqueur Royal
Crazy Legs


Nombre de messages : 1513

Age : 31

Localisation : La Rochelle

Date d'inscription : 09/01/2008


[Tuto] Animer un bouton Empty
MessageSujet: Re: [Tuto] Animer un bouton   [Tuto] Animer un bouton EmptyVen 3 Juil 2009 - 2:53

Ah ba oui exact, je viens de tester et ça marche effectivement, ben alors je sais pas ce que j'avais tester l'autre fois mais je devais être fatiguer, arf c'est le métier qui rentre :travaille:

Je pourrais mettre une tempo dans la fonction Dire dans Dieu malgré moi (faudrait ptete qu'on s'y remette tiens O_O ).
Donc, merci, et je suis en train de le faire ce sacré module langue !

Ça sera soit une fonction à mettre dans le repeteadly_execute, soit dans le game_start, parce que dans les modules il est possible de mettre la fonction repeteadly_execute donc ça éviterait d'écrire du code dans la fonction (moi perso j'aime pas trop la charger >_<) d'AGS.

Elle ressemblera à ça :

Code:
function animateButton(this Button*, int view, int loop, int speed);
Revenir en haut Aller en bas
Asraroth
Disciple de la Grande Tasse Bleue
Disciple de la Grande Tasse Bleue
Asraroth


Nombre de messages : 1451

Age : 49

Date d'inscription : 20/10/2006


[Tuto] Animer un bouton Empty
MessageSujet: Re: [Tuto] Animer un bouton   [Tuto] Animer un bouton EmptyVen 3 Juil 2009 - 17:04

Crazy Legs a écrit:
Code:
function animateButton(this Button*, int view, int loop, int speed);

ben oui ! Autant utiliser une view à la place d'un array ! Bonne idée ! [Tuto] Animer un bouton 114419
Revenir en haut Aller en bas
zazette
C'est quoi la Tasse Bleue ?
C'est quoi la Tasse Bleue ?
avatar


Nombre de messages : 9

Date d'inscription : 20/04/2011


[Tuto] Animer un bouton Empty
MessageSujet: Re: [Tuto] Animer un bouton   [Tuto] Animer un bouton EmptyVen 29 Avr 2011 - 13:02

Merci beaucoup pour cette explication !
J'avais justement le même problème et je me demandais comment le résoudre.
Revenir en haut Aller en bas
Contenu sponsorisé





[Tuto] Animer un bouton Empty
MessageSujet: Re: [Tuto] Animer un bouton   [Tuto] Animer un bouton Empty

Revenir en haut Aller en bas
 
[Tuto] Animer un bouton
Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» Animer un bouton
» module animer bouton
» Animer un bouton au survol, comment ?
» tuto créer un module pour un bouton de gui
» nouveau script

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
Adventure Games Studio fr :: CREATION DE JEUX :: Trucs & Astuces, Tutoriaux-
Sauter vers: