|
| Anim de perso: vues consécutives en aléatoire. | |
| | Auteur | Message |
---|
Jorkz Cliqueur Emérite
Nombre de messages : 666
Age : 40
Localisation : Montpellier
Date d'inscription : 16/07/2006
| Sujet: Anim de perso: vues consécutives en aléatoire. Lun 30 Mai 2022 - 10:36 | |
| Bonjour ! J'ai repris la création de mon jeu après quelques mois de répit et ma foi, je suis tout rouillé (mais rien de grave ) Je me suis donc attaqué à la création d'un PNJ qui est un peu complexe à animer. Je sais que je dois jouer sur l'aléatoire pour cela, mais je bloque depuis hier. Je vous explique le principe: Rachid le sportif possède 3 views principales : -view où ce perso fait des pompes, en position plus ou moins allongée sur le ventre, donc. -view où il est assis, et cligne simplement des yeux. -view où il est également assis, mais manipule une bouteille pour boire un coup. + Deux views "de transition" où il passe de la position pompe à la position assise et vice versa. Je souhaite que l'anim de base soit celle où il fait une nombre aléatoire de pompes (entre 3 et 8 ) avant de... ...se redresser et se mettre en position assise pour -soit cligner des yeux pendant un laps de temps aléatoire (disons compris entre 4 et 10 secondes) -soit manipuler la bouteille. ( ou les deux à la suite ) ...se dé-redresser pour se mettre en position pompe et ainsi de suite... Voici ce que j'ai commencé pour le moment - Code:
-
{ if ( !cRachid.Speaking && !cRachid.Animating && !cRachid.Moving ) { cRachid.LockView(RACHIDBOUTEILLE); cRachid.Animate(cRachid.Loop, 7, eOnce, eNoBlock); } }
Bien sûr, je lui ai défini une autre vue dont je n'ai pas parlé <= celle où il parle justement !... Celle-ci fonctionne bien, mais il faudrait qu'il passe à cette vue de manière naturelle, en n'interrompant pas n'importe comment ces actions en cours. Par exemple s'il fait ses pompes il doit d'abord passer par la vue "de transition". J'ai cru comprendre que eOnce réglait ce problème, mais je ne suis pas sûr... Enfin, je n'ai aucune idée d'où placer cela dans le script... Pour l'instant c'est dans function repeatedly_execute() et ça fonctionne Quelqu'un aurait une idée de comment animer ce (futur) grand sportif ? En vous remerciant... _________________ L' est si forte à la course qu'elle en sort de la phrase. autruche
Dernière édition par Jorkz le Mar 31 Mai 2022 - 6:16, édité 1 fois |
| | | Jorkz Cliqueur Emérite
Nombre de messages : 666
Age : 40
Localisation : Montpellier
Date d'inscription : 16/07/2006
| Sujet: Re: Anim de perso: vues consécutives en aléatoire. Mar 31 Mai 2022 - 5:53 | |
| En fait mon problème à la base, c'est déjà que pour commencer, je ne sais déjà pas comment lancer des vues différentes d'affilée, à chaque fois que je tente de programmer au moyen de lockview et unlockview (et en en tapant plusieurs à la suite), AGS me met seulement une view parmi toutes celles que je lui dis de jouer. _________________ L' est si forte à la course qu'elle en sort de la phrase. autruche
|
| | | Shai-la Ouvrière en Chef de la Grande Tasse Bleue
Nombre de messages : 6018
Age : 46
Localisation : Montpellier
Date d'inscription : 17/04/2006
| Sujet: Re: Anim de perso: vues consécutives en aléatoire. Mar 31 Mai 2022 - 7:10 | |
| Le seul moyen, je pense, de faire plusieurs views d'affilée est de jouer avec le "eBlock", pour que l'animation soit bloquée jusqu'à ce qu'elle soit terminée. Sinon, elle sera coupée en plein milieu. Ou alors il faut faire plusieurs views, chacune avec le nombre de pompes différent, et se terminant toutes par le mouvement qui se redresse. Ce n'est pas évident mais d'autres auront peut-être de meilleures propositions |
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Anim de perso: vues consécutives en aléatoire. Mar 31 Mai 2022 - 17:06 | |
| - Shai-la a écrit:
- Ou alors il faut faire plusieurs views, chacune avec le nombre de pompes différent, et se terminant toutes par le mouvement qui se redresse.
Oui c'est la meilleure solution, vu que l'animation des pompes est constituée de 2 images, et que l'étendue de l'aléatoire se limite à 5 (5 ~ . Tu passera plus de temps à chercher comment bien le programmer qu'à éditer les 5 vues. Après ça dépend aussi ce que t'entends / attends de l'aléatoire. Parce que si c'est dans le sens "on s'en fiche" (jusque que ça varie) tu peux même réduire à 3 vues : 3 pompes, 6 pompes, 8 pompes. ça ne ferait pas une grande différence du point de vue du joueur, et ce sera bien plus facile à gérer de ton côté. Enfin si l'étendue 3 ~ 8 a des implications particulières dans le jeu, là ça peut être pertinent de le gérer côté script. J'ai pas en tête le module de script d'AGS, mais de ce que je comprend dans le bout de code que tu as indiqué (doc de obj.animate() ) je tenterai un truc de ce genre : - Code:
-
cRachid.LockView(POMPES_DEBUT); cRachid.Animate(cRachid.Loop, 7, eOnce, eNoBlock); cRachid.LockView(POMPES_LOOP); cRachid.Animate(cRachid.Loop, 7, Random( 5 ) + 3, eNoBlock); cRachid.LockView(POMPES_FIN); cRachid.Animate(cRachid.Loop, 7, eOnce, eNoBlock);
cRachid.LockView(NORMAL); cRachid.Animate( ... ) Note: que je ne sais pas à quoi correspond le 1er argument (séquence) POMPES_LOOP serait les 2 images de l'animation de pompes. POMPES_DEBUT et POMPES_FIN serait la même animation, une passée à l'endroit, l'autre à l'envers. NORMAL, c'est le retour à l'animation principale (je sais pas comment tu va le gérer, mais il ne faut pas oublier de relancer) Si je ne dis pas de bêtises, tu pourrais peut-êtes mettre les 3 dans une même vue, mais dans des directions différentes. Par exemple une vue POMPES, dans la direction "left" le début, "forward" les pompes et "right" la fin. Ensuite tu joues avec le dernier argument de la fonction Animate(). - Code:
-
cRachid.LockView(POMPES); cRachid.Animate(cRachid.Loop, 7, eOnce, eNoBlock, eLeft); cRachid.Animate(cRachid.Loop, 7, Random( 5 ) + 3, eNoBlock, eForward); cRachid.Animate(cRachid.Loop, 7, eOnce, eNoBlock, eRight);
cRachid.LockView(NORMAL); cRachid.Animate( ... ) à vérifier, en tout cas, c'est ce que je testerai pour ma part. |
| | | Jorkz Cliqueur Emérite
Nombre de messages : 666
Age : 40
Localisation : Montpellier
Date d'inscription : 16/07/2006
| Sujet: Re: Anim de perso: vues consécutives en aléatoire. Mar 31 Mai 2022 - 19:14 | |
| Hello, merci pour vos réponses... Mais à vous lire je n'ai pas vraiment l'impression que ce soit le résultat que je recherche Après je sais pas, faut tester... D'autant plus que je tiens vraiment à programmer sa vue "bouteille" et une vue où il ne fait rien (ou plutôt où il cligne des yeux), et ça on n'en a pas du tout parlé... Cependant je risque d'être un peu pris cette semaine, je regarde dès que je peux et je vous tiens au courant.. Merci encore PS: la place de ce code est bien dans le repeatedly_execute()?? _________________ L' est si forte à la course qu'elle en sort de la phrase. autruche
|
| | | Jorkz Cliqueur Emérite
Nombre de messages : 666
Age : 40
Localisation : Montpellier
Date d'inscription : 16/07/2006
| Sujet: Re: Anim de perso: vues consécutives en aléatoire. Mer 1 Juin 2022 - 12:42 | |
| Hey ! Bon bah c'est bon, peu à peu je me rapproche du résultat que je souhaitais... C'est un peu laborieux mais ça a le mérite de donner plus de naturel à son cycle. - Code:
-
function room_RepExec() { if ( !cRachid.Speaking && !cRachid.Animating && !cRachid.Moving ) { int pompe=Random (3); { if (pompe==0) { cRachid.LockView(RACHIDPOMPES); cRachid.Animate(cRachid.Loop, 15, eOnce, eBlock); } if (pompe==1) { cRachid.LockView(RACHIDPOMPES); cRachid.Animate(cRachid.Loop, 15, eOnce, eBlock); cRachid.LockView(RACHIDPOMPES); cRachid.Animate(cRachid.Loop, 15, eOnce, eBlock); } if (pompe==2) { cRachid.LockView(RACHIDPOMPES); cRachid.Animate(cRachid.Loop, 15, eOnce, eBlock); cRachid.LockView(RACHIDPOMPES); cRachid.Animate(cRachid.Loop, 15, eOnce, eBlock); cRachid.LockView(RACHIDPOMPES); cRachid.Animate(cRachid.Loop, 15, eOnce, eBlock); } if (pompe==3) { cRachid.LockView(RACHIDPOMPES); cRachid.Animate(cRachid.Loop, 15, eOnce, eBlock); cRachid.LockView(RACHIDPOMPES); cRachid.Animate(cRachid.Loop, 15, eOnce, eBlock); cRachid.LockView(RACHIDPOMPES); cRachid.Animate(cRachid.Loop, 15, eOnce, eBlock); cRachid.LockView(RACHIDPOMPES); cRachid.Animate(cRachid.Loop, 15, eOnce, eBlock); } } cRachid.LockView(RACHIDRELEVE); cRachid.Animate(cRachid.Loop, 7, eOnce, eBlock); int souffle=Random (1); { if (souffle==0) { cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 20, eOnce, eBlock); cRachid.LockView(RACHIDCLIGNE); cRachid.Animate(cRachid.Loop, 7, eOnce, eBlock); cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 40, eOnce, eBlock); cRachid.LockView(RACHIDCLIGNE); cRachid.Animate(cRachid.Loop, 7, eOnce, eBlock); cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 15, eOnce, eBlock); } if (souffle==1) { cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 25, eOnce, eBlock); } } int bouteille=Random (4); { if (bouteille==0) { cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 40, eOnce, eBlock); cRachid.LockView(RACHIDBOUTEILLE); cRachid.Animate(cRachid.Loop, 7, eOnce, eBlock); } if (bouteille==1) { cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 40, eOnce, eBlock); cRachid.LockView(RACHIDCLIGNE); cRachid.Animate(cRachid.Loop, 7, eOnce, eBlock); cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 15, eOnce, eBlock); cRachid.LockView(RACHIDBOUTEILLE); cRachid.Animate(cRachid.Loop, 7, eOnce, eBlock); } if (bouteille==2) { cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 30, eOnce, eBlock); cRachid.LockView(RACHIDBOUTEILLE); cRachid.Animate(cRachid.Loop, 7, eOnce, eBlock); cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 15, eOnce, eBlock); cRachid.LockView(RACHIDCLIGNE); cRachid.Animate(cRachid.Loop, 7, eOnce, eBlock); cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 20, eOnce, eBlock); } if (bouteille==3) { cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 20, eOnce, eBlock); cRachid.LockView(RACHIDCLIGNE); cRachid.Animate(cRachid.Loop, 7, eOnce, eBlock); cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 40, eOnce, eBlock); cRachid.LockView(RACHIDCLIGNE); cRachid.Animate(cRachid.Loop, 7, eOnce, eBlock); cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 40, eOnce, eBlock); } if (bouteille==4) { cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 20, eOnce, eBlock); cRachid.LockView(RACHIDCLIGNE); cRachid.Animate(cRachid.Loop, 7, eOnce, eBlock); cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 20, eOnce, eBlock); cRachid.LockView(RACHIDCLIGNE); cRachid.Animate(cRachid.Loop, 7, eOnce, eBlock); cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 25, eOnce, eBlock); } } int souffleencore=Random (1); { if (souffleencore==0) { cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 20, eOnce, eBlock); cRachid.LockView(RACHIDCLIGNE); cRachid.Animate(cRachid.Loop, 7, eOnce, eBlock); cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 40, eOnce, eBlock); cRachid.LockView(RACHIDCLIGNE); cRachid.Animate(cRachid.Loop, 7, eOnce, eBlock); cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 15, eOnce, eBlock); } if (souffleencore==1) { cRachid.LockView(RACHIDSTAND); cRachid.Animate(cRachid.Loop, 25, eOnce, eBlock); } } cRachid.LockView(RACHIDRELEVE); cRachid.Animate(cRachid.Loop, 7, eOnce, eBlock, eBackwards); } }
Cependant, ça fonctionne ça fonctionne... Mais le jeu est bloqué pendant toute cette phase, à cause que je suis obligé de jouer sur eBlock pour que les views soient jouées consécutivement... Quelqu'un saurait-il comment "débloquer" le truc ? Merci _________________ L' est si forte à la course qu'elle en sort de la phrase. autruche
|
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Anim de perso: vues consécutives en aléatoire. Jeu 2 Juin 2022 - 17:35 | |
| De ce que je comprend, c'est pas le problème de eBlock. Eblock est nécessaire pour que la suite du script ne s’exécute qu'à la fin de la séquence d'animation lancée. Il y aurait d'autres façons de coder ça, mais ça reviens au même. (dans mon post précédent je croyais que eBlock consistait à bloquer le joueur pendant la séquence d'animation...) Tu peux tester le même script mais dans la fonction repeatedly_execute_always. - Citation :
- Vous utiliserez généralement repeatedly_execute pour faire des choses qui affectent le joueur et repeatedly_execute_always pour gérer des tâches d'arrière-plan qui n'affectent pas directement le joueur.
http://admin.no.uchi.free.fr/dokuwiki-2008-05-05/doku.php?id=repexecTu as aussi une autre façon de coder, plus simple et qui te permettrait facilement de modifier le nombre de pompes (sans avoir à tout recopier) - Code:
-
int pompe=Random (3); if (pompe==0) { cRachid.LockView(RACHIDPOMPES); cRachid.Animate(cRachid.Loop, 15, eOnce, eBlock); } else { for (int i = 0; i <= pompe; i++) cRachid.LockView(RACHIDPOMPES); cRachid.Animate(cRachid.Loop, 15, eOnce, eBlock); } } |
| | | Jorkz Cliqueur Emérite
Nombre de messages : 666
Age : 40
Localisation : Montpellier
Date d'inscription : 16/07/2006
| Sujet: Re: Anim de perso: vues consécutives en aléatoire. Ven 3 Juin 2022 - 0:24 | |
| - Clique a écrit:
Tu peux tester le même script mais dans la fonction repeatedly_execute_always.
Et non, j'ai déjà testé, le même script dans cette fonction-là m'affiche ce message d'erreur au cause (justement) de l'eBlock. Le problème c'est que lorsque je change ça en eNoBlock, rien ne semble se passer: le PNJ reste dans la position définie en NormalView, et ne se met même plus en SpeechView lorsqu'il est sensé parler. _________________ L' est si forte à la course qu'elle en sort de la phrase. autruche
|
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Anim de perso: vues consécutives en aléatoire. Ven 3 Juin 2022 - 9:59 | |
| - Jorkz a écrit:
- Le problème c'est que lorsque je change ça en eNoBlock, rien ne semble se passer
En fait tout va se dérouler, le problème c'est qu'il n'attends pas qu'une animation se termine pour passer à la suite. Le script a une cadence bien plus élevée que celle de l'animation, du coups ça n'a même pas le temps d'être affiché. D'où l'impression "rien ne semble se passer". Désolé de partir un peu dans tous les sens. En fait je ne connais pas du tout le script/code d'AGS, mais je profite de ton topic pour m'y mettre. J'ai de bonne connaissances d'autres langages, et je pense cerner le souci. Le besoin que tu as, c'est de faire tourner ce script en tâche de fond, c'est à dire : en parallèle du script principal (celui qui permet au joueur d’interagir). Et le problème avec eBlock c'est qu'il ne permet pas de sortir de cette boucle. Il y a une solution à ça, que j'ai déjà su gérer dans un autre langage (LUA). ça peut passer par de la gestion d' "event" et "queue". Faudrait que je trouve comment ça se pratique dans AGS. D'ici que je trouve (et j'en suis pas sur) la meilleure solution est celle-ci : - Shai-la a écrit:
- Ou alors il faut faire plusieurs views, chacune avec le nombre de pompes différent, et se terminant toutes par le mouvement qui se redresse.
Il s'agirait alors "d'écouter" la propriété "Animating" de l'objet Character. Dans la boucle on vérifie cette condition (if), et ce n'est que quand elle renvoi 0 que tu fais ton tirage au sort et lance l'animation correspondante. En fait c'est déjà ce que tu fais : - Code:
-
if ( !cRachid.Speaking && !cRachid.Animating && !cRachid.Moving ) Donc normalement, ainsi tu pourrais enlever eBlock, il faudrait que chaque animation soit complète (et nom composée d'une succession). Peut être aussi faire un appel à unlockView() à la fin. Pour tout dire, la seule autre solution que je vois, reviendrait à ce même principe, mais par une gestion beaucoup plus fine. Je note ça pour plus tard : https://www.adventuregamestudio.co.uk/manual/ags35.htm#BlockingScripts |
| | | Jorkz Cliqueur Emérite
Nombre de messages : 666
Age : 40
Localisation : Montpellier
Date d'inscription : 16/07/2006
| Sujet: Re: Anim de perso: vues consécutives en aléatoire. Dim 5 Juin 2022 - 19:01 | |
| Bon bah rebonjour tout le monde ! Pour ma part, ça a un peu avancé de mon côté. Finalement j'ai créé une view de mon perso, avec loop 0) des pompes 1) pompes + bouteille 2) pompes+pause sans bouteille. Comme ceci: Dans le script de ma room, j'ai spécifié ceci - Code:
-
function room_AfterFadeIn() { if ( !cRachid.Speaking && !cRachid.Animating && !cRachid.Moving ) cRachid.LockView(RACHIDPOMPES); cRachid.Animate(1, 0, eRepeat, eNoBlock); } Jusque là c'est cool, avec la loop 1 qui tourne en boucle, et pour l'instant comme je teste, je modifie parfois en 0 ou 2 pour les autres loops. C'est là que ça se complique un peu car je souhaiterais: -d'une part jouer sur de l'aléatoire comme ceci (merci @Clique qui m'a mis sur la voie...) - Code:
-
cRachid.Animate(Random (2), 0, eRepeat, eNoBlock); Le problème c'est qu'une fois qu'AGS a choisi sa loop aléatoire, il rejoue toujours la même en repeat... Or je voudrais qu'il répète effectivement cette boucle, toujours en NoBlock, mais en changeant à chaque fois de loop. Est-ce que déjà, cela est possible ? -d'autre part, et c'est là que ça se complique beaucoup plus... Voici ce que j'ai pondu pour gérer les conversations... - Code:
-
function dialog_request(int param) { if(param == 1){ hotspot[2].SetProperty("Condamné", true); }
if(param == 2)
switch (cRachid.View == 9) { case cRachid.frame < 9: cRachid.LockView(RACHIDRELEVE); cRachid.Animate(0, 0, eOnce, eBlock);break; case cRachid.Loop == 1 && (cRachid.frame >= 10 && cRachid.frame <= 15): cRachid.UnlockView(); cRachid.LockView(RACHIDSTAND); cRachid.Animate(0, 0, eOnce, eBlock);
default: cRachid.UnlockView(); cRachid.LockView(RACHIDSTAND); cRachid.Animate(0, 0, eOnce, eBlock); }
if(param == 3){ cRachid.LockView(RACHIDRELEVE); cRachid.Animate(0, 0, eOnce, eBlock, eBackwards); cRachid.LockView(RACHIDPOMPES); cRachid.Animate(Random (2), 0, eRepeat, eNoBlock); }} param1 on s'en tape, c'est sur un autre dialogue... param2 c'est l'entrée dans le dialogue. param3 c'est la fin du dialogue, c'est cool car le perso se "dé-redresse" pour revenir en loop pompes... Cool parce que ça fonctionne. Ce qui fonctionne également, c'est que dans le premier "case" toutes les vignettes/frames en dessous de 9 (les pompes) sont naturellement interrompues par un beau RACHIDRELEVE où, comme son nom l'indique, le perso se relève et entre dans le dialogue et ça fonctionne pas trop mal, le mouvement est fluide et bref, comme je dis ça fonctionne. En revanche, je galère grave car je ne sais pas trop me servir des "break;" et sur le deuxième "case" j'aimerais pouvoir interrompre le truc de manière fluide à une frame précise. de manière à ce que si un dialogue est sensé se lancer entre la frame 10 et 15... le programme attende d'être à la frame 15 pour faire cela. Je sais pas trop si je me suis bien fait comprendre, mais une telle technique, en "segmentant" ma loop de cette manière, l'anim au commencement des dialogues serait vraiment plus naturelle. Des solutions ? Qu'en pensez-vous ? Merci. _________________ L' est si forte à la course qu'elle en sort de la phrase. autruche
|
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Anim de perso: vues consécutives en aléatoire. Lun 6 Juin 2022 - 0:23 | |
| - Jorkz a écrit:
-
- Code:
-
cRachid.Animate(Random (2), 0, eRepeat, eNoBlock); Le problème c'est qu'une fois qu'AGS a choisi sa loop aléatoire, il rejoue toujours la même en repeat... Or je voudrais qu'il répète effectivement cette boucle, toujours en NoBlock, mais en changeant à chaque fois de loop. Est-ce que déjà, cela est possible ? Elle se répète en boucle, parce que tu as mis l'argument eRepeat, au lieu de eOnce. Enfin, comme tu utilise eNoBlock, il faudra éviter de relancer cette fonction tant qu'une animation est en cours. - Code:
-
if (!cRachid.Animating) { cRachid.Animate(Random (2), 0, eOnce, eNoBlock); } Dans le code suivant (function dialog_request ... ) il semble qu'il manque des accolades après "if(param == 2)" et pour refermer le "switch" Par ailleurs, ce serait plus logique si c'était un "else if" (idem pour if(param == 3)" Je pense en effet que tu n'a pas saisi le principe de fonctionnement d'un switch. En général c'est toujours préférable d'utiliser des if() { ... } else if() { ... } else { ... } parce que c'est plus performant et pratique à concevoir. En fait dans un switch tu ne fera qu'une seule évaluation, et executer un code pour chaque cas. ça par exemple : - Code:
-
switch (cRachid.View == 9) { case cRachid.frame < 9: en fait ça reviens à ça : - Code:
-
switch (cRachid.View == 9) { case false: Puisque ton switch évalue (cRachid.View == 9), ça ne produira que 2 cas : true ou false Ce que tu pourrais faire à la rigueur c'est ça : - Code:
-
switch (cRachid.View) { case 9: ... break; case 1: ... break; default: ... } C'est à dire qu'on évalue la propriété cRachid.View Le premier "case" sera exécuté si la valeur est 9, le 2e "case" si la valeur est 1, et "default" si la valeur est tout autre. (Mais c'est pas ce que tu veux faire.) Les "break" servent à casser une boucle (sortir d'une boucle). (Bien que dans un switch ça ne boucle pas... donc comprend par là un bloc "case: truc; break;") Dans le code ci-dessus, si j'enlève le 1er break (du case 9), lorsque la valeur de cRachid.View est 9, le case 9 s’exécute et comme il n'y a pas de "break" ça continue et le "case 1" s’exécute aussi. Lorsque la valeur est 1, le "case 1" s’exécute, et arrivé à "break" ça se termine là pour le switch (le default ne s’exécute pas). - Code:
-
switch (var) { case 9: print(9); case 1: print(1); break; default: print(0); } Ci-dessus, si var == 9 ça écrit "91" Si var == 1 ça écrit "1" Dans tout autre cas ça écrit "0" Un autre usage de "break" pour t'aider à bien saisir le truc : - Code:
-
var = 1; while(true) { if (var > 10) { break; } var = var +1; } while(true) est une boucle qui tourne indéfiniment, à chaque tour j'augmente la variable de 1. Avec "break" je peux la stopper lorsque la variable dépasse la valeur de 10. - Code:
-
while (true) { //1 var = 1; while(true) { //2 if (var > 10) { break; } var = var +1; } } Là c'est la même mais dans une autre boucle infinie (une boucle dans une autre boucle). Lorsque la variable dépasse 10, "break" casse la boucle n°2, ainsi la boucle n°1 tourne et redonne la valeur 1 à la variable et ça repart pour 10 tours de la boucle n°2. L'avantage d'un switch c'est l'éventualité de pouvoir empiler parfois des actions. Mais il y a bien peu de cas où c'est réellement nécessaire ou utile. On peut souvent y parvenir par une succession de "if", "else if", "else", ou bien une succession de "if". On commet moins facilement des erreurs avec des "if" et ça permet davantage de choses. Je sais pas si j'ai bien tout compris, mais tu peux essayer ça : - Code:
-
function dialog_request(int param) { if(param == 1) { hotspot[2].SetProperty("Condamné", true); } else if(param == 2) { if (cRachid.frame < 9) { cRachid.LockView(RACHIDRELEVE); cRachid.Animate(0, 0, eOnce, eBlock); } else if( cRachid.Loop == 1 && (cRachid.frame >= 10 && cRachid.frame <= 15)) { while(cRachid.frame <= 15){ Wait(4); http://0.1 sec } cRachid.UnlockView(); cRachid.LockView(RACHIDSTAND); cRachid.Animate(0, 0, eOnce, eBlock); } else { cRachid.UnlockView(); cRachid.LockView(RACHIDSTAND); cRachid.Animate(0, 0, eOnce, eBlock); } } else if(param == 3) { cRachid.LockView(RACHIDRELEVE); cRachid.Animate(0, 0, eOnce, eBlock, eBackwards); cRachid.LockView(RACHIDPOMPES); cRachid.Animate(Random (2), 0, eRepeat, eNoBlock); } } J'ai ré-arrangé ton code (accolades etc.) comme j'ai pu comprendre le truc. - Jorkz a écrit:
- (..) sur le deuxième "case" j'aimerais pouvoir interrompre le truc de manière fluide à une frame précise. de manière à ce que si un dialogue est sensé se lancer entre la frame 10 et 15... le programme attende d'être à la frame 15 pour faire cela.
Pour faire ça, j'ai gardé tel quel la clause ( cRachid.Loop == 1 && (cRachid.frame >= 10 && cRachid.frame <= 15)) et ajouté une boucle "while" avec un délai de 1/10e de seconde. Elle devra tourner en boucle tant que la valeur de cRachid.frame <= 15 Quand cRachid.frame > 15 cette boucle s'interrompt et la suite continue comme tu l'as prévu. Tu peux changer la valeur de Wait() en fonction de la cadence de ton animation (la durée d'une frame) c'est une valeur en 1/40e de seconde. En tout cas, laisse tomber les "switch", c'est vraiment trop particulier comme truc, et très dispensable 99% du temps. Moi j'aimais beaucoup m'en servir quand je l'ai découvert, mais en vrai ça a plus de défauts que d'avantages pour la lisibilité et l'entretiens de ton code. Tu peux arriver à en coder un qui fonctionne très bien, et puis plus tard quand t'as besoin d'ajouter ou d'améliorer un truc, te rendre compte que ça ne peut plus fonctionner et devoir tour recoder sous la forme if/else. |
| | | Jorkz Cliqueur Emérite
Nombre de messages : 666
Age : 40
Localisation : Montpellier
Date d'inscription : 16/07/2006
| Sujet: Re: Anim de perso: vues consécutives en aléatoire. Lun 6 Juin 2022 - 3:58 | |
| Merci beaucoup pour le temps pris pour toutes ces explications. J'ai plus ou moins cerné le principe du switch et, en effet, je ne pense pas que ce soit très à-propos dans mon cas précis. Pour ce qui est du random, c'est tout de même embêtant cette histoire... Car si je comprends bien, en fait, il n'y a pas la possibilité de mettre en place ce que je souhaitais réellement sans bloquer complétement le jeu. Enfin, j'ai adapté le script que tu m'as montré pour ce qui est des animations de dialogues et c'est tout à fait ce que je souhaitais !! - Code:
-
if(param == 2) { if ( cRachid.frame <= 9 ) { cRachid.UnlockView(); cRachid.LockView(RACHIDRELEVE); cRachid.Animate(0, 0, eOnce, eBlock); } else if( cRachid.Loop == 1 && (cRachid.frame >= 10 && cRachid.frame <= 15)) { while(cRachid.frame <= 15){ Wait(35); http://0.1 sec } cRachid.UnlockView(); cRachid.LockView(RACHIDSTAND); cRachid.Animate(0, 0, eOnce, eBlock); } else if( cRachid.Loop == 1 && (cRachid.frame >= 16 && cRachid.frame <= 45)) { while(cRachid.frame <= 45){ Wait(50); http://0.1 sec } cRachid.UnlockView(); cRachid.LockView(RACHIDSTAND); cRachid.Animate(0, 0, eOnce, eBlock); } else if( cRachid.Loop == 1 && (cRachid.frame >= 46 && cRachid.frame <= 51)) { while(cRachid.frame <= 51){ Wait(15); http://0.1 sec } cRachid.UnlockView(); cRachid.LockView(RACHIDRELEVE); cRachid.Animate(0, 0, eOnce, eBlock); } //etc... etc... ...Même si la gestion du Wait ne permet pas de faire un truc très précis. N'y aurait-il pas un moyen de calculer la durée des frames "restantes" (celles avant la fin du while) un peu de la même manière de ce que j'ai pu faire avec ce son ? (utiliser objet sifflet sur mon perso = sons à durées différentes) - Code:
-
function cGarg_UseInv() { if(cGarg.ActiveInventory == iSifflet) { int alea=Random(5); if (alea==0) Sifflet = aSifflet01.Play(); if (alea==1) Sifflet = aSifflet02.Play(); if (alea==2) Sifflet = aSifflet03.Play(); if (alea==3) Sifflet = aSifflet04.Play(); if (alea==4) Sifflet = aSifflet05.Play(); if (alea==5) Sifflet = aSifflet06.Play(); int DureeClipCycles = Sifflet.LengthMs/(1000/GetGameSpeed()) + 1; Wait(DureeClipCycles); } } Encore merci !!... Car ça commence tout de même à bien prendre forme !! _________________ L' est si forte à la course qu'elle en sort de la phrase. autruche
|
| | | Jorkz Cliqueur Emérite
Nombre de messages : 666
Age : 40
Localisation : Montpellier
Date d'inscription : 16/07/2006
| Sujet: Re: Anim de perso: vues consécutives en aléatoire. Lun 6 Juin 2022 - 4:42 | |
| Ahah ! Oubliez ma demande précédente car... Ça marche nickel chrome avec un for à la place du while ! - Code:
-
else if( cRachid.Loop == 1 && (cRachid.frame >= 16 && cRachid.frame <= 45)) {
for (; cRachid.Frame < 45;) { Wait(1); } cRachid.UnlockView(); cRachid.LockView(RACHIDSTAND); cRachid.Animate(0, 0, eOnce, eBlock); } _________________ L' est si forte à la course qu'elle en sort de la phrase. autruche
|
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Anim de perso: vues consécutives en aléatoire. Lun 6 Juin 2022 - 13:10 | |
| - Citation :
- N'y aurait-il pas un moyen de calculer la durée des frames "restantes" (celles avant la fin du while)
Si, c'est parfaitement possible, mais je ne suppose pas que ce soit intéressant de le faire ici. Le plus précis, c'est comme tu l'as fais en réduisant le délai au minimum : Wait(1) Juste à titre d'exemple : Si tu calcule la durée exacte, tout ce que ça t'apporte c'est de ne pas écrire de boucle : - Code:
-
tick = 5; // la durée d'une frame lastFrame = 45; // n° de la dernière frame Wait( (lastFrame - cRachid.Frame) * tick); Mais ça rapporte rien à priori. La fonction Wait() est très probablement faite d'une boucle avec un compteur faisant tourner le délai minimal. Du style : - Code:
-
function Wait( duration ){ for (i=0; i < duration; i++){ native.wait(1); } } Je ne pense pas que ce soit le remplacement du "while" par un "for" qui ait réglé un problème. ça doit venir d'autre chose que t'as modifié entre-temps. Là t'as écris le "for" d'une drôle de manière, en fait tu l'as transformé en "while". Fais le test en la remplaçant par : - Code:
-
while ( cRachid.Frame < 45 ) { Wait(1); } Tu verras que ça fonctionne pareille, et ça sera plus propre. Enfin, je vois qu'il y a un petit angle mort, et c'est probablement ça qui t'as donné l'impression que c'était "imprécis". - Code:
-
else if( cRachid.Loop == 1 && (cRachid.frame >= 16 && cRachid.frame <= 45)) { for (; cRachid.Frame < 45;) Dans les conditions de "if" il y a que cRachid.frame <= 45 Et dans la condition de sortie de boucle cRachid.Frame < 45 C'est à dire que la boucle sera interrompue à partir du moment où cRachid.Frame == 46 ou +, donc il y aura toujours au moins un délai Wait() d’exécuté. Probablement que cette imprécision n'est plus perceptible depuis que tu a réduit le délai à 1. Mais c'est toujours présent. En fait, si je devais remettre tout ce bloc au propre : - Code:
-
else if( cRachid.Loop == 1 ) { while(cRachid.frame >= 16 && cRachid.frame <= 45){ Wait(1); } cRachid.UnlockView(); cRachid.LockView(RACHIDSTAND); cRachid.Animate(0, 0, eOnce, eBlock); } else { cRachid.UnlockView(); cRachid.LockView(RACHIDSTAND); cRachid.Animate(0, 0, eOnce, eBlock); } ça devrait fonctionner de même (et mieux), avec l'avantage de ne pas avoir plusieurs fois le contrôle de l'intervalle frame >= 16 && frame <= 45 Donc si tu modifie l'animation, tu n'auras qu'une seule ligne de code à rectifier (et donc moins de risque d'erreur/oubli) Sous cette forme la condition de la boucle "while" est vérifiée avantSi elle est fausse (false) elle ne fera aucun tour. C'est la raison pour laquelle je peux me permettre de retirer la vérification de l'intervalle de la condition "if". Il y a une autre forme pour écrire une boucle while, pour que sa condition soit vérifiée après (après chaque tour. par conséquent il y aura toujours au moins un tour de fait). Il s'agit de "do while" : - Code:
-
var = 10; do { var = var +1; Wait(1) } while ( var < 10); Dans l'exemple ci-dessus, var sera passée à 11, parce que la condition (var < 10) n'est vérifié qu'après un tour de boucle. - Code:
-
var = 10; while (var < 10) { var = var +1; Wait(1) } Ici, var restera à 10, puisque la condition est vérifiée avant. La boucle "while" sera interrompue avant d'avoir commencé. J'espère que ça t'aide à y voir plus clair. Je comprend que c'est pas évident les boucles while, parce que la moindre erreur peut vite te faire bugguer à l'infini. Mais c'est pour ça qu'il faut bien apprendre à s'en servir. C'est un des composants les plus utiles en programmation. à la limite, si t'es pas trop sûr, tu peux te bricoler une soupape de sécurité : - Code:
-
soupape = 0; while (true) { if( soupape > 1000) { break; // <- casse la boucle si ça tourne plus que prévu } soupape = soupape +1; Wait(1) } |
| | | Jorkz Cliqueur Emérite
Nombre de messages : 666
Age : 40
Localisation : Montpellier
Date d'inscription : 16/07/2006
| Sujet: Re: Anim de perso: vues consécutives en aléatoire. Mar 7 Juin 2022 - 6:36 | |
| Hé hé, merci encore !!!
Je vais essayer d'optimiser ça alors...
_________________ L' est si forte à la course qu'elle en sort de la phrase. autruche
|
| | | Contenu sponsorisé
| Sujet: Re: Anim de perso: vues consécutives en aléatoire. | |
| |
| | | | Anim de perso: vues consécutives en aléatoire. | |
|
Sujets similaires | |
|
| Permission de ce forum: | Vous ne pouvez pas répondre aux sujets dans ce forum
| |
| |
| |