|
| Script d'utilisation automatisée d'objets | |
| | |
Auteur | Message |
---|
Gob Adepte de la Grande Tasse Bleue
Nombre de messages : 123
Date d'inscription : 08/10/2021
| Sujet: Re: Script d'utilisation automatisée d'objets Dim 21 Jan 2024 - 17:53 | |
| En fait le jeu est déjà avancé, j'ai pas mal d'anims d'objets de faites et elles sont toujours composées de plusieurs loops, faisant appel à plusieurs views. Je ne reviens pas là dessus. Je ne comprend toujours pas ni l'utilisation ni l'utilité de ta fonction JSP. Comment est elle utilisée dans le cas des utilisations non prévues d'objets sur les zones où il y a des utilisations d'autres objets prévues ? Est ce que tu dois rajouter une ligne de code ?
Pour l'instant je n'ai pas le courage de t'envoyer un bout du jeu. Quand je supprime les rooms sauf une, le jeu ne part plus.
J'utilise la 3.6.0 aussi, je ne sais plus si j'ai mis le patch.
|
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Script d'utilisation automatisée d'objets Lun 22 Jan 2024 - 20:14 | |
| Désolé si j'arrive pas à faire comprendre. C'est pas grave pour le modèle. Je demandais si t'avais un prototype sous le coude. Si t'en a pas et que tu peux pas en fagoter un facilement laisse tomber. Je pourrai me débrouiller avec un template, ça sera plus clair. Une dernière explication pour la route !
La fonction JSP doit être ajoutée dans unhandled_event à la condition des combinaisons de what/type. Elle doit être ajouté aussi à la fin de chaque script d’interactions d'objets que t'as programmé sur des objets, des zones, des personnages, après le if, à la condition autre (else). Parce que si t'as programmé une interaction, que ça produise quelque chose à l'écran ou non (parce que c'est pas l'objet attendu), c'est pas considéré comme un unhandled_event par le moteur du jeu. Lui il a exécuté la fonction, mais si ça ne produit rien, de son point de vue le job est fait. unhandled_event ne s'éxécute que si la fonction d'interraction n'existe pas. Par exemple, t'as programmé qu'on peut donner le lézard à un personnage : après le - Code:
-
if(eEgo.ActiveInventory == iLezard) { de ce script il faut que tu ajoutes cette ligne : - Code:
-
} else { JSP(eEgo.ActiveInventory); } C'est à dire : - Soit l'objet est le bon : il se produit ce que tu a prévu. - Sinon il lance la fonction JSP Je dis pas de mettre toutes tes animations dans une même view : uniquement la partie spécifique à l'objet. Sans ça, il te faudra tout le truc pour chaque objets. Par exemple pour 60 objets, ça serait un truc du genre : - Code:
-
function JSP(int iObjet) { if(iObjet == iLezard) { cEgo.Animate(10, 1, 0, eBlock); cEgo.LockView(2); cEgo.Animate(5, 1, 0, eBlock); cEgo.UnlockView(); cEgo.Animate(11, 1, 0, eBlock); } else if(iObjet == iCup) { cEgo.Animate(10, 1, 0, eBlock); cEgo.LockView(3); cEgo.Animate(8, 1, 0, eBlock); cEgo.UnlockView(); cEgo.Animate(11, 1, 0, eBlock); } else if(iObjet == iKey) { cEgo.Animate(10, 1, 0, eBlock); cEgo.LockView(4); cEgo.Animate(7, 1, 0, eBlock); cEgo.UnlockView(); cEgo.Animate(11, 1, 0, eBlock); } } Note que là j'en ai fait que 3, il en faudrait 60 au total. Si t'as déjà fait d'une autre manière pour un certain nombre d'objets, c'est pas grave. C'est possible de mixer les 2 solutions. 1 pour les objets que t'as déjà animé et dont tu veux pas déplacer les loops, et l'autre façon pour les prochains (si tu changes d'avis). Après je veux bien réfléchir à un autre moyen. Là dans l’abstrait je peux pas trouver, j'ai juste proposé la solution la plus simple. Tu me dis que tu as déjà ta façon de trier tes view et les loops. Si c'est une façon méthodique et régulière, alors c'est peut-être possible de le traduire dans le code. Je t'explique le problème : au moment où ça se déclenche, la seule info dont on dispose c'est ne n° de l'objet utilisé. Il faudrait que ce n° suffise pour deviner le ou les n° de la view et des loop à utiliser. |
| | | Gob Adepte de la Grande Tasse Bleue
Nombre de messages : 123
Date d'inscription : 08/10/2021
| Sujet: Re: Script d'utilisation automatisée d'objets Mar 23 Jan 2024 - 8:35 | |
| Hello, merci pour toutes ces explications. Je ne le ferais qu'avec une partie des objets. J'ai (au moins) 3 persos qui ont leurs propres anims, donc difficile de mutualiser des bouts d'anims. Si tu veux tester avant que je m'y remette, je t'ai bricolé un fichier AGS de base, avec 3 objets, 3 hotspots et 3 characters. Je te l'envoie.
Dernière édition par Gob le Mar 23 Jan 2024 - 10:03, édité 1 fois |
| | | Gob Adepte de la Grande Tasse Bleue
Nombre de messages : 123
Date d'inscription : 08/10/2021
| Sujet: Re: Script d'utilisation automatisée d'objets Mar 23 Jan 2024 - 9:59 | |
| |
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Script d'utilisation automatisée d'objets Mar 23 Jan 2024 - 19:57 | |
| Oui je comprends bien que c'est difficile de mutualiser les parties d'animations. C'est ce que j'entendais par "trouver une astuce", "une animation générique" en fait standardiser dans la mesure du possible ce type d'animation.
Parce que si le but est de simplifier la tâche, c'est une nécessité. Le code ne peut pas simplifier ça à lui tout seul, ce serait magique.
Après faut voir aussi rationaliser que signifie la suggestion du joueur que tu as reçue. Ce qu'il demande c'est qu'il y ait un feedback visuel, lorsqu'il tente une interaction qui ne sert à rien. Il y a plein de jeux notables qui se sont contenté de renvoyer un dialogue du genre "Je ne crois pas que ça puisse fonctionner", ou quelques variantes de phrases, et ça fait le taf.
T'as pas choisi la facilité, et c'est clair que c'est stylé, mais c'est audacieux.
Côté script, une série de 60, 120 ou + de if /else if ça risque d'être lourdingue. L'alternative (que j'ai vaguement expliqué : sommaire) c'est probablement plus rapide, mais plus coûteux en mémoire. Pour les deux, il n'y a qu'en essayant qu'on peut voir si c'est supportable ou trop lourd.
Je me creuse a tête pour trouver une alternative. Il y en a peut-être une, mais faut voir. quand tu ouvre un objet d'inventaire dans AGS, dans le volet "Properties" (bas droite) à la dernière ligne tu as "Properties" et possibilité d'en ajouter. Cela permettrait peut-être de passer des informations autres que seul le n°ID.
Je me dis qu'il serait possible d'encoder des références de vues/loop là dedans sous la forme d'une ligne de texte. Par exemple, en y écrivant un truc du genre : V10_L5_V12_L4_V9_L2 ça pourrait être réinterprété comme une série d'instructions : changeView(10) animate(5) changeView(12) animate(4) changeView(9) animate(2) ça serait fastidieux à écrire, mais on peut envisager de faire un petit programme de conversion. Par contre faudrait programmer un interpréteur, et plus il sera limité, mieux ce sera.
Dis moi tout de suite si ça te semble pas mal, ou si c'est trop. Parce que ça serait laborieux à étudier. (Là c'est qu'une idée) |
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Script d'utilisation automatisée d'objets Mar 23 Jan 2024 - 20:23 | |
| (J'ai téléchargé, tu peux suppr le fichier si tu veux) |
| | | Gob Adepte de la Grande Tasse Bleue
Nombre de messages : 123
Date d'inscription : 08/10/2021
| Sujet: Re: Script d'utilisation automatisée d'objets Mer 24 Jan 2024 - 15:28 | |
| Non, je vais essayer comme ça. Donc j'ai mis: - Code:
-
else { JSP(player.ActiveInventory); }
... sur un perso après une utilisation d'objet, et dans le globalScript: - Code:
-
function JSP(int iObjet) { if (cGob1.ActiveInventory == iLezard) { cGob1.FaceDirection(eDirectionDown); cGob1.ChangeView (122); cGob1.Animate (16, 3,eOnce, eBlock); cGob1.ChangeView (54); cGob1.Animate (4, 3, eOnce, eBlock); cGob1.ChangeView (122); cGob1.Animate (16, 3,eOnce, eBlock); cGob1.ChangeView (128); cGob1.FaceDirection(eDirectionDown); } }
Mais il doit manquer quelque chose, il me dit: GlobalScript.asc(9775): Error (line 9775): Type mismatch: cannot convert 'InventoryItem*' to 'int' |
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Script d'utilisation automatisée d'objets Sam 27 Jan 2024 - 9:40 | |
| OK, je vois où je me suis planté (d'où l'aspect théorique / pas testé) La lettre "i" au début des noms de variables comme iLezard, iCup, iKey... Signifie un type 'InventoryItem*' et pas 'int' (comme je l'ai cru) Corrige juste la 1ere ligne, mais aussi la ligne 3 - Code:
-
function JSP(InventoryItem* iObjet) //< correction: (type) InventoryItem* { if (iObjet == iLezard) // < à corriger aussi { cGob1.FaceDirection(eDirectionDown); cGob1.ChangeView (122); cGob1.Animate (16, 3,eOnce, eBlock); cGob1.ChangeView (54); cGob1.Animate (4, 3, eOnce, eBlock); cGob1.ChangeView (122); cGob1.Animate (16, 3,eOnce, eBlock); cGob1.ChangeView (128); cGob1.FaceDirection(eDirectionDown); } } Pour la fonction unhandled_event, comme c'est la fonction JSP qui va gérer les animations, tu devras la simplifier comme ceci : (elle va juste relayer) - Code:
-
function unhandled_event(int what, int type) { if ((what == 1 && type == 3) || (what == 2 && type == 3) || (what == 3 && type == 3)) { JSP(cGob1.ActiveInventory); } }
Même si tu l'utilises pas : Ci-dessous, la correction pour que le système de regrouper les loops dans une vue fonctionne. - Code:
-
function JSP(InventoryItem* iObjet) { //< correction: (type) InventoryItem* int iVue = 1; // < ici le n°ID de la View où sont les animations d'objets // Utiliser un objet d'inventaire sur n'importe quoi d'imprévu if(iObjet.ID <= Game.GetLoopCountForView(iVue)) { // execute l'animation cEgo.LockView(iVue); cEgo.Animate(iObjet.ID, 1, 0, eBlock); //< correction: iObjet.ID cEgo.UnlockView(); } else { // En fait l'animation correspondante n'existe pas cEgo.say("Je sais pas le faire..."); } } Questions :En repassant rapidement le fil, je remarque que tu as publié 2 noms de variables différents pour le personnage jouable : cGob1 et cGob2Est-ce que ton jeu comprends différents personnages jouables ?Si c'est oui (ou autre raison pour laquelle tu changes de variable) il va falloir faire quelques rectifications, sinon ça va pas fonctionner tout le long du jeu. Il y a différentes façon de procéder, mais je sais pas laquelle serait approprié à ton jeu. Est-ce que c'est juste le fait de changer de perso, comme une progression au cours du jeu ? Par exemple: cGob1, puis cGob2, etc. L'un remplace l'autre au fur et à mesure, mais pas nécessairement de retour en arrière. Est-ce que c'est un principe comme dans Day of the tentacle, où on joue 3 personnages en même temps, et donc le joueur peut changer de l'un à l'autre +/- n'importe quand ? |
| | | Gob Adepte de la Grande Tasse Bleue
Nombre de messages : 123
Date d'inscription : 08/10/2021
| Sujet: Re: Script d'utilisation automatisée d'objets Sam 27 Jan 2024 - 10:43 | |
| Hello, oui ça marche maintenant. J'ai testé avec 1 objet et un perso, je vais généraliser ça et voir ce qui se passe. Je ne sais pas encore, pour les objets secondaires, comment j'automatiserais le fait de mettre une anim générique sans rajouter trop de lignes de code, je verrais plus tard. Oui, j'ai plusieurs persos jouables, parfois un tout seul, en général 2 en même temps, voire 3. Ca ne devrait pas poser de problème, ils ont chacun leurs propres objets. Je te tiens au courant rapidement. Bon week ! |
| | | Gob Adepte de la Grande Tasse Bleue
Nombre de messages : 123
Date d'inscription : 08/10/2021
| Sujet: Re: Script d'utilisation automatisée d'objets Sam 27 Jan 2024 - 11:03 | |
| Hello, en fait, le code else {JSP(player.ActiveInventory);} marche bien sur les persos, mais pas sur les objets ni les hotspots. C'est un peu dommage, car j'appelle certains persos par un objet ou un hotspot. |
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Script d'utilisation automatisée d'objets Sam 27 Jan 2024 - 16:11 | |
| Pour player, il me semblait bien qu'il y avait cette référence de disponible dans AGS (de mémoire de mon tout 1er projet sur AGS). Mais depuis j'avais pas réussi à le retrouver dans la doc... Je viens juste de le retrouver ici : https://adventuregamestudio.github.io/ags-manual/ScriptingTutorialPart1.html#instances - Scripting Tutorial - Part 1 : instances a écrit:
- As well as all the individual character instances such as cEgo, there is a special instance called player. This always corresponds to the current player character, so if you just want to perform a command on the player character (especially useful in games where the player can control different characters) then you can use the player instance to do so.
Trad/résumé : Dans le script on peut créer plusieurs instances de personnage jouable. C'est ce qu'on voit dans les différents exemples sous des noms de variables cEgo, cChar etc. Donc on peut en créer plusieurs, mais un seul est jouable à un instant T. Comprenez "Character" est un modèle type, une instance c'est une copie qu'on va employer. (Allez voir l'introduction de n'importe quel langage POO : Programation Orientée Objet, pour plus de détail d'explication) L'instance spéciale player référera toujours au personnage actuellement jouable. L'inventaire d'objet est propre à une instance de Character. Donc dans ce projet, et comme les fonctions JSP et unhandled_event sont globales, faut être rigoureux avec ça. Bref, dans ce cas, dans les fonctions JSP et unhandled_event, remplace également toutes les instances cChar1, cChar2 etc. par player
- Gob a écrit:
- le code else {JSP(player.ActiveInventory);} marche bien sur les persos, mais pas sur les objets ni les hotspots.
Je sais pas pourquoi... Si t'as rien scripté pour ces objets et Hotspot, c'est à (re)voir dans la fonction unhandled_event, si tu as bien déterminé les bonnes combinaisons de what/type. Il en manque peut-être. Sinon, revois le script d’interaction sur l'objet/hotspot. Le code : - Code:
-
else {JSP(player.ActiveInventory);} doit faire suite à une clause if. Ou bien en dernier d'une série if, else if, else if ...Pour ça je te conseille de bien mettre en ordre ton code au niveau des accolades { } et avec l'indentation. C'est à dire, dès que tu en ouvre une, tu ajoute une tabulation en début de ligne. Et quand tu en ferme une, tu réduit l'indentation. Comme ça tu verrais mieux si cette clause else est placée au bon endroit ou non. (C'est pas du tout obligé pour que ça fonctionne, mais c'est très recommandé) Si je reprends un de tes codes précédents : (Porte frigo ?) - Code:
-
function o7PorteFrig_UseInv() { if (cGob2.ActiveInventory == iLime) { player.Walk(646, 291, eBlock,eWalkableAreas); player.FaceDirection(eDirectionLeft); cGob2.ChangeView (94); cGob2.Animate (10, 3,eOnce, eBlock);
cGob2.ChangeView (78); cGob2.Animate (2, 3, eOnce, eBlock); aLime.Play(eAudioPriorityHigh, eRepeat); cGob2.Animate (3, 1, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); aLime.Stop(); cGob2.Animate (4, 3, eOnce, eBlock); cGob2.ChangeView (94); cGob2.Animate (10, 3,eOnce, eBlock); cGob2.ChangeView (124); cGob2.FaceDirection(eDirectionLeft); Wait(25); o7PorteFrig.SetView(58); aChaine.Play(eAudioPriorityHigh, eOnce); o7PorteFrig.Animate(16, 3, eOnce); Wait(20); aGrincementPorte.Play(eAudioPriorityHigh, eOnce); o7PorteFrig.Animate(5, 5, eOnce);
o7PorteFrig.Clickable=false; } else { JSP(player.ActiveInventory); } } Normalement, il n'y a pas de raison que ça ne fonctionne pas. Pour vérifier où est le problème, tu peux tester ça : - Code:
-
function o7PorteFrig_UseInv() { if (cGob2.ActiveInventory == iLime) { // etc. } else { //TEST Display("Pas le bon objet"); // < voir si le message s'affiche : le script est bon Display("Active inventory: %s", player.ActiveInventory.Name); // < voir si l'objet d'inventaire est bien identifié JSP(player.ActiveInventory); } } |
| | | Gob Adepte de la Grande Tasse Bleue
Nombre de messages : 123
Date d'inscription : 08/10/2021
| Sujet: Re: Script d'utilisation automatisée d'objets Sam 27 Jan 2024 - 17:03 | |
| ... Non, il ne prend pas le code "else {JSP(player.ActiveInventory);}" suite à des utilisations d'objets sur hotspots ou objets. Il dit undefined token "JSP"... J'ai fait le test, c'est bien ce code qu'il ne prend pas. |
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Script d'utilisation automatisée d'objets Sam 27 Jan 2024 - 17:35 | |
| - Citation :
- undefined token "JSP"
Si la fonction JSP est bien définie dans le script global, normalement il n'y a pas de raison qu'il soit indéfini ou inaccessible... |
| | | Gob Adepte de la Grande Tasse Bleue
Nombre de messages : 123
Date d'inscription : 08/10/2021
| Sujet: Re: Script d'utilisation automatisée d'objets Sam 27 Jan 2024 - 17:43 | |
| Elle doit être bien définie puisque ça marche avec les persos. |
| | | Gob Adepte de la Grande Tasse Bleue
Nombre de messages : 123
Date d'inscription : 08/10/2021
| Sujet: Re: Script d'utilisation automatisée d'objets Sam 27 Jan 2024 - 18:10 | |
| Pour récapituler, on a ça dans GlobalScript: [code=ags] function JSP(InventoryItem* iObjet) { if (iObjet == iLezard){ cGob1.FaceDirection(eDirectionDown); cGob1.ChangeView (122); cGob1.Animate (16, 3,eOnce, eBlock); cGob1.ChangeView (54); cGob1.Animate (4, 3, eOnce, eBlock); cGob1.ChangeView (122); cGob1.Animate (16, 3,eOnce, eBlock); cGob1.ChangeView (128);cGob1.FaceDirection(eDirectionDown);} if (iObjet == iEcu){ cGob1.FaceDirection(eDirectionDown); cGob1.ChangeView (122); cGob1.Animate (16, 3,eOnce, eBlock); cGob1.ChangeView (54); cGob1.Animate (0, 3, eOnce, eBlock); aPieceLance.Play(eAudioPriorityHigh, eOnce); cGob1.Animate (1, 3, eOnce, eBlock); cGob1.Animate (2, 2, eOnce, eBlock); cGob1.Animate (3, 3, eOnce, eBlock); cGob1.ChangeView (122); cGob1.Animate (16, 3,eOnce, eBlock); cGob1.ChangeView (128);cGob1.FaceDirection(eDirectionDown); int ran=Random(1); if (ran==0) { aGob1Talk13.Play(eAudioPriorityHigh, eRepeat); cGob1.Say ("Face !"); aGob1Talk13.Stop();} else if (ran==1) { aGob1Talk15.Play(eAudioPriorityHigh, eRepeat); cGob1.Say ("Pile !"); aGob1Talk15.Stop();}} }
// called when processclick wasn't handled anywhere else function unhandled_event (int what, int type) { if ((what==1&&type==3)||(what==2&&type== 3)||(what==3&&type==3)||(what==4&&type==3)||(what==5&&type==3)) { JSP(player.ActiveInventory); } [/code]
Ca sur un perso, ça marche nickel: [code=ags] function cBinocle_UseInv() { if (cGob1.ActiveInventory == iGravure) { if (D05InfoGravure==false) { cGob1.FaceDirection(eDirectionDown); aGob1Talk08.Play(eAudioPriorityHigh, eRepeat); cGob1.Say ("Mmh... Je ne vais pas lui[rendre tout de suite."); aGob1Talk08.Stop(); } if (D05InfoGravure==true) { player.Walk(840, 238, eBlock,eWalkableAreas); player.FaceDirection(eDirectionLeft); aGob1Talk09.Play(eAudioPriorityHigh, eRepeat); cGob1.Say ("Mon ami, je vous rends votre gravure."); aGob1Talk09.Stop();
player.Walk(808, 242, eBlock,eWalkableAreas); cGob1.ChangeView (122); cGob1.Animate (10, 3,eOnce); cGob1.Animate (20, 2,eOnce); cBinocle.ChangeView(5); cBinocle.Animate(6, 3, eOnce); aWoosh01.Play(eAudioPriorityHigh, eOnce); cGob1.Animate (22, 3,eOnce, eBlock); cGob1.ChangeView (128); player.FaceDirection(eDirectionLeft); player.Walk(840, 238, eBlock,eWalkableAreas); player.FaceDirection(eDirectionLeft); cBinocle.Animate(7, 3, eOnce); cBinocle.FaceDirection(eDirectionDown); Wait(20); aGob1Talk10.Play(eAudioPriorityHigh, eRepeat); cGob1.Say ("J'ai consulté le miroir[du temps... Et je peux[vous affirmer..."); aGob1Talk10.Stop(); Wait(20); aGob1Talk11.Play(eAudioPriorityHigh, eRepeat); cGob1.Say ("... Que vous allez revenir[de la guerre et avoir[plusieurs enfants !"); aGob1Talk11.Stop(); cBinocle.FaceDirection(eDirectionLeft); Wait(25); aBinocle03.Play(eAudioPriorityHigh, eRepeat); cBinocle.Say("Vous avez l'air honnête...[Je vous crois !"); aBinocle03.Stop(); Wait(25); aBinocle03.Play(eAudioPriorityHigh, eRepeat); cBinocle.Say("Je reprends espoir."); aBinocle03.Stop();
player.LoseInventory(iGravure); SetTimer(10, 0); cBinocle.Clickable=false; D05ConditionsSortie=D05ConditionsSortie+1; } } else {JSP(player.ActiveInventory);} } [/code]
Et ça, sur un objet, qu'il ne prend pas: [code=ags] function o7PorteFrig_UseInv() { if (cGob2.ActiveInventory == iLime) { player.Walk(646, 291, eBlock,eWalkableAreas);player.FaceDirection(eDirectionLeft); cGob2.ChangeView (94); cGob2.Animate (10, 3,eOnce, eBlock);
cGob2.ChangeView (78); cGob2.Animate (2, 3, eOnce, eBlock); aLime.Play(eAudioPriorityHigh, eRepeat); cGob2.Animate (3, 3, eOnce, eBlock); cGob2.Animate (3, 3, eOnce, eBlock); cGob2.Animate (3, 3, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 1, eOnce, eBlock); cGob2.Animate (3, 1, eOnce, eBlock); cGob2.Animate (3, 1, eOnce, eBlock); cGob2.Animate (3, 1, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 3, eOnce, eBlock); cGob2.Animate (3, 3, eOnce, eBlock); cGob2.Animate (3, 3, eOnce, eBlock); aLime.Stop(); cGob2.Animate (4, 3, eOnce, eBlock); cGob2.ChangeView (94); cGob2.Animate (10, 3,eOnce, eBlock); cGob2.ChangeView (124); cGob2.FaceDirection(eDirectionLeft); Wait(25); o7PorteFrig.SetView(58); aChaine.Play(eAudioPriorityHigh, eOnce); o7PorteFrig.Animate(16, 3, eOnce); Wait(20); aGrincementPorte.Play(eAudioPriorityHigh, eOnce); o7PorteFrig.Animate(5, 5, eOnce);
o7PorteFrig.Clickable=false; } if (cGob2.ActiveInventory == iGantBoxe) { player.Walk(647, 290, eBlock,eWalkableAreas); player.FaceDirection(eDirectionLeft); cGob2.ChangeView (94); cGob2.Animate (10, 3,eOnce, eBlock);
cGob2.ChangeView (78); cGob2.Animate (0, 3, eOnce, eBlock); aGob2Coup3.Play(eAudioPriorityHigh, eOnce); cGob2.Animate (1, 2, eOnce, eBlock); cGob2.ChangeView (94); cGob2.Animate (10, 3,eOnce, eBlock); cGob2.ChangeView (124); cGob2.FaceDirection(eDirectionLeft); } else {JSP(player.ActiveInventory);} } [/code]
Pareil pour les hotspots... Enfin, c'est déjà pas mal du tout ! Merci pour tes efforts. Je peux garder ce système pour les persos (et les objets et hotspots qui n'ont aucune utilisation d'objets). Pour les persos qui sont appelés par un objet ou un hotspot, je peux rajouter à la main. C'est déjà bien comme automatisation. |
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Script d'utilisation automatisée d'objets Dim 28 Jan 2024 - 8:54 | |
| Il faut que tu vérifies tes blocs de code, accolades, ça peut se faire en prenant l'habitude d'intenter les lignes code. ça aide à la lisibilité et parfois permet de cerner un problème. Un problème est pas nécessairement un bug, ça peut être que le script n'est pas écrit de manière à ce que tu veux produire se produise. Ici je formate ton code de la porte de frigo : - Code:
-
function o7PorteFrig_UseInv() { if (cGob2.ActiveInventory == iLime) { player.Walk(646, 291, eBlock,eWalkableAreas); player.FaceDirection(eDirectionLeft); cGob2.ChangeView (94); cGob2.Animate (10, 3,eOnce, eBlock);
cGob2.ChangeView (78); cGob2.Animate (2, 3, eOnce, eBlock); aLime.Play(eAudioPriorityHigh, eRepeat); cGob2.Animate (3, 3, eOnce, eBlock); cGob2.Animate (3, 3, eOnce, eBlock); cGob2.Animate (3, 3, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 1, eOnce, eBlock); cGob2.Animate (3, 1, eOnce, eBlock); cGob2.Animate (3, 1, eOnce, eBlock); cGob2.Animate (3, 1, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 3, eOnce, eBlock); cGob2.Animate (3, 3, eOnce, eBlock); cGob2.Animate (3, 3, eOnce, eBlock); aLime.Stop(); cGob2.Animate (4, 3, eOnce, eBlock); cGob2.ChangeView (94); cGob2.Animate (10, 3,eOnce, eBlock); cGob2.ChangeView (124); cGob2.FaceDirection(eDirectionLeft); Wait(25); o7PorteFrig.SetView(58); aChaine.Play(eAudioPriorityHigh, eOnce); o7PorteFrig.Animate(16, 3, eOnce); Wait(20); aGrincementPorte.Play(eAudioPriorityHigh, eOnce); o7PorteFrig.Animate(5, 5, eOnce);
o7PorteFrig.Clickable=false; } if (cGob2.ActiveInventory == iGantBoxe) { player.Walk(647, 290, eBlock,eWalkableAreas); player.FaceDirection(eDirectionLeft); cGob2.ChangeView (94); cGob2.Animate (10, 3,eOnce, eBlock);
cGob2.ChangeView (78); cGob2.Animate (0, 3, eOnce, eBlock); aGob2Coup3.Play(eAudioPriorityHigh, eOnce); cGob2.Animate (1, 2, eOnce, eBlock); cGob2.ChangeView (94); cGob2.Animate (10, 3,eOnce, eBlock); cGob2.ChangeView (124); cGob2.FaceDirection(eDirectionLeft); } else { JSP(player.ActiveInventory); } } À la ligne 46, ça ne devrait pas être un if mais un else if, pour que le script soit consécutif : - (if) si c'est l'objet iLezard - (else if) ou si c'est l'objet iGantBoxe - (else) sinon exécute la fonction JSP. Je suis pas certain que ça règle le problème de la fonction JSP, mais c'est un autre problème. Tel que tu l'as écrit, ce n'est pas un "si/ou si/sinon" mais un "si. si/sinon". C'est à dire que si t’interagis avec l'objet iLezard, le 1er bloc s’exécute (l'effet voulu), le 2e bloc ne s’exécute pas (iGantBoxe), et à la fin la fonction JSP s’exécute. Ici la fonction JSP n'est exécutée que si l'objet actif n'est pas iGantBoxe. Alors qu'il faudrait que ça n'arrive qu'à l’exception de tous les autres (ici iLezard et iGantBoxe). Donc il faut que tes blocs soient consécutif. (De plus ça optimise ton script) Même remarque pour la fonction JSP : - Code:
-
function JSP(InventoryItem* iObjet) { if (iObjet == iLezard){ cGob1.FaceDirection(eDirectionDown); cGob1.ChangeView (122); cGob1.Animate (16, 3,eOnce, eBlock); cGob1.ChangeView (54); cGob1.Animate (4, 3, eOnce, eBlock); cGob1.ChangeView (122); cGob1.Animate (16, 3,eOnce, eBlock); cGob1.ChangeView (128);cGob1.FaceDirection(eDirectionDown); } if (iObjet == iEcu){ cGob1.FaceDirection(eDirectionDown); cGob1.ChangeView (122); cGob1.Animate (16, 3,eOnce, eBlock); cGob1.ChangeView (54); cGob1.Animate (0, 3, eOnce, eBlock); aPieceLance.Play(eAudioPriorityHigh, eOnce); cGob1.Animate (1, 3, eOnce, eBlock); cGob1.Animate (2, 2, eOnce, eBlock); cGob1.Animate (3, 3, eOnce, eBlock); cGob1.ChangeView (122); cGob1.Animate (16, 3,eOnce, eBlock); cGob1.ChangeView (128); cGob1.FaceDirection(eDirectionDown); int ran=Random(1); if (ran==0) { aGob1Talk13.Play(eAudioPriorityHigh, eRepeat); cGob1.Say ("Face !"); aGob1Talk13.Stop(); } else if (ran==1) { aGob1Talk15.Play(eAudioPriorityHigh, eRepeat); cGob1.Say ("Pile !"); aGob1Talk15.Stop(); } } } Rends les blocs de chaque objets consécutifs. Le souci (optimisation) si tu fais une succession de "if", c'est que le script va devoir tous les parcourir. C'est pas nécessaire ici puisque qu'un bloc est sensé s’exécuter à l'exclusion de tous les autres. Autrement dit, lorsque qu'un test d'objet correspond (est vérifié comme vrai / true) il n'est pas nécessaire de vérifier que ça correspond avec les objets suivants. Dit en passant, à la fin de ton bloc iEcu, tu tires à pile ou face. Ton 1er test vérifie si c'est face, donc c'est pas nécessaire de vérifier si dans l'autre cas si c'est pile, puisque c'est soit l'un soit l'autre. Même si le résultat est +/- le même, un "if / else" c'est mieux. De même dans la fonction cBinocle_UseInv() où tu test une valeur vrai/faux : - Code:
-
if (D05InfoGravure==false) { cGob1.FaceDirection(eDirectionDown); aGob1Talk08.Play(eAudioPriorityHigh, eRepeat); cGob1.Say ("Mmh... Je ne vais pas lui[rendre tout de suite."); aGob1Talk08.Stop(); } if (D05InfoGravure==true) { //etc. Pas besoin de vérifier 2 fois si c'est vrai ou faux. - Code:
-
if (D05InfoGravure==false) { cGob1.FaceDirection(eDirectionDown); aGob1Talk08.Play(eAudioPriorityHigh, eRepeat); cGob1.Say ("Mmh... Je ne vais pas lui[rendre tout de suite."); aGob1Talk08.Stop(); } else { //etc. C'est une remarque qui paraîtra pointilleuse, du zèle ou enc* des mouches... Mais en fait ça a un intérêt d'être rigoureux sur ce genre de chose, dans le discernement / traitement cas par cas, pour retrouver / deviner quand on a fait une erreur (sans être un bug) sur une partie du script. Je propose de reformater la fonction JSP ainsi : - Code:
-
function JSP(InventoryItem* iObjet) { if (iObjet == iLezard){ cGob1.FaceDirection(eDirectionDown); cGob1.ChangeView (122); cGob1.Animate (16, 3,eOnce, eBlock); cGob1.ChangeView (54); cGob1.Animate (4, 3, eOnce, eBlock); cGob1.ChangeView (122); cGob1.Animate (16, 3,eOnce, eBlock); cGob1.ChangeView (128);cGob1.FaceDirection(eDirectionDown); } else if (iObjet == iEcu){ cGob1.FaceDirection(eDirectionDown); cGob1.ChangeView (122); cGob1.Animate (16, 3,eOnce, eBlock); cGob1.ChangeView (54); cGob1.Animate (0, 3, eOnce, eBlock); aPieceLance.Play(eAudioPriorityHigh, eOnce); cGob1.Animate (1, 3, eOnce, eBlock); cGob1.Animate (2, 2, eOnce, eBlock); cGob1.Animate (3, 3, eOnce, eBlock); cGob1.ChangeView (122); cGob1.Animate (16, 3,eOnce, eBlock); cGob1.ChangeView (128); cGob1.FaceDirection(eDirectionDown); int ran=Random(1); if (ran==0) { aGob1Talk13.Play(eAudioPriorityHigh, eRepeat); cGob1.Say ("Face !"); aGob1Talk13.Stop(); } else { // < ici aussi, pas nécessaire de retester aGob1Talk15.Play(eAudioPriorityHigh, eRepeat); cGob1.Say ("Pile !"); aGob1Talk15.Stop(); } } // TEMP else if(activeItem != null) { Display("JSP: %s", activeItem.ScriptName); // < Objet à ajouter } else { Display("JSP: null (Pas d'objet actif..)"); } } Et à la fin de la succession de tests "if / else if", j'ai ajouté un "else" pour afficher un message (moche). Je te suggères de conserver cette ligne pendant le développement du jeu, et tu pourras la supprimer à la toute fin. Ce sera un moyen pour toi quand tu test le jeu, pour savoir si la fonction s'est bien exécutée mais que l'objet actif n'est pas encore intégré. En gros, quand tu verrais ce message tu peux te noter sur un post-it : tel objet à animer/rajouter. Et sait-on jamais : un message "JSP: null (Pas d'objet actif..)", pour voir si parfois la fonction pourrait se lancer alors qu'aucun objet d'inventaire n'est actif. ça permettrait de voir si le problème ne viendrait pas d'autre chose.
Vérifie aussi la fonction unhandled_event. C'est peut être qu'une erreur de copier/coller, mais dans le code fourni il manque une accolade de fin. - Code:
-
// called when processclick wasn't handled anywhere else function unhandled_event (int what, int type) { if ((what==1&&type==3)||(what==2&&type== 3)||(what==3&&type==3)||(what==4&&type==3)||(what==5&&type==3)) { JSP(player.ActiveInventory); } Si c'était aussi le cas dans ton script global, alors ça foutrait en l'air toute la suite.
Même si tu peux te débrouiller avec, je pense que tu devrais continuer d'investiguer sur le cas du message "undefined token JSP". Vois sur quel objet / perso / hotspot ce message se produit en particulier. ça doit probablement être une erreur de syntaxe avant l'appel de JSP. ça peut être une parenthèse que tu as oublié de fermer, ou un point virgule manquant à la fin d'une ligne, un guillemet manquant... Sur le fond, je suis pas convaincu qu'il y ait une différence entre les personnage et les objets/hotspot.. Ou bien il y a quelque chose qui m'échappe. Faut que je mette en pratique pour m'en rendre compte. |
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Script d'utilisation automatisée d'objets Dim 28 Jan 2024 - 9:04 | |
| ça viens de me sauter aux yeux, la fonction unhandled_event est foiré : - Code:
-
// called when processclick wasn't handled anywhere else function unhandled_event (int what, int type) { if ((what==&&1type==3)||(what==&&2type== 3)||(what==&&3type==3)||(what==&&4type==3)||(what==&&5type==3)) { JSP(player.ActiveInventory); } Pour un info, les opérateurs logiques : - && signifie "ET" - || signifie "OU" Si tu veux tester 2 variables : - Code:
-
if (what==1 && type==3) signifie si what == 1 ET type == 3 - Code:
-
if (what==1 || type==3) signifie si what == 1 OU type == 3 Les parenthèses tu les ajoutes pour grouper ces tests. C'est un peu comme une équation de maths, dont le résultat est uniquement vrai sinon faux. Bref, j'espère que c'est assez clair, sinon je te conseille de trouver un tuto qui le détaillera davantage (le principe est commun à tous les langages) Je corrige : (vois la différence) - Code:
-
// called when processclick wasn't handled anywhere else function unhandled_event (int what, int type) { if ((what==1 && type==3) || (what==2 && type==3) || (what==3 && type==3) || (what==4 && type==3)||(what== 5 && type==3)) { JSP(player.ActiveInventory); } } En bref, tu peux pas écrire ça : - Code:
-
(what==&&1type==3) C'est ça : - Code:
-
(what == 1 && type == 3) Normalement tu aurais du avoir un gros message d'erreur pour ça !?
Et STP, va dans tes préférences du forum activer les BBcodes : https://adventuregamestudio.1fr1.net/profile?mode=editprofile&page_profil=preferences |
| | | Gob Adepte de la Grande Tasse Bleue
Nombre de messages : 123
Date d'inscription : 08/10/2021
| Sujet: Re: Script d'utilisation automatisée d'objets Dim 28 Jan 2024 - 11:17 | |
| Hello, les questions if ou else if dans les utilisations d'objets ne sont pas cruciales dans ce problèmes. Tes explications sont intéressantes pour ma compréhension simplifier un peu le code, il faut que je me penche là dessus.
Le problème actuel vient qu'il refuse ce code :else {JSP(player.ActiveInventory);} quand on le met dans un objet ou un hotspot. Ca ne change rien si on rajoute des else if.
A priori pas de problème dans le GlobalSript, de toute façon, il bloque dès qu'il manque des accolades, points virgule, parenthèses ou guillemets. L'accolade qui avait l'air de manquer, c'est parce qu'il y a d'autres trucs après, que j'ai viré d'ailleurs pour vérifier si ça interfère.
Si il y avait ça: (what==&&1type==3), je ne pense pas qu'il aurait supporté.
|
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Script d'utilisation automatisée d'objets Dim 28 Jan 2024 - 13:26 | |
| Faut que je test. C'est pas que je doute de ce que tu dis, c'est que je comprends pas la logique de la chose (la logique d'AGS, pourquoi ça serait différent entre un Character, un hotspot etc.) Dit en passant dans le template que tu m'as passé, il y a un exemple très intéressant de contenu pour la fonction unhandled_event : - Code:
-
// called when processclick wasn't handled anywhere else function unhandled_event (int what, int type) { if (cRoger.ActiveInventory == iCup) { cRoger.ChangeView(4); cRoger.Animate(0, 3, eOnce); cRoger.ChangeView(5); cRoger.Animate(0, 3, eOnce); cRoger.ChangeView(4); cRoger.Animate(1, 3, eOnce); cRoger.ChangeView(1); } if (cRoger.ActiveInventory == iKey) { cRoger.ChangeView(4); cRoger.Animate(0, 3, eOnce); cRoger.ChangeView(5); cRoger.Animate(1, 3, eOnce); cRoger.ChangeView(4); cRoger.Animate(1, 3, eOnce); cRoger.ChangeView(1); } if (cRoger.ActiveInventory == iEau) { cRoger.ChangeView(4); cRoger.Animate(0, 3, eOnce); cRoger.ChangeView(5); cRoger.Animate(2, 3, eOnce); cRoger.ChangeView(4); cRoger.Animate(1, 3, eOnce); cRoger.ChangeView(1); } if (cRoger.ActiveInventory == iCanard) { cRoger.ChangeView(4); cRoger.Animate(0, 3, eOnce); cRoger.ChangeView(5); cRoger.Animate(3, 3, eOnce); cRoger.ChangeView(4); cRoger.Animate(1, 3, eOnce); cRoger.ChangeView(1); } if (what == 1) // Unhandled events for HOTSPOTS { if (type == 1) // look { player.Say("I see nothing special about it."); } else if (type == 2) // interact { player.Say("I can't do anything with it."); } else if (type == 3) // use inv on { player.Say("That won't do anything."); } } else if (what == 2) // Unhandled events for OBJECTS { if (type == 0) // look { player.Say("Looks alright."); } else if (type == 1) // interact { player.Say("I don't want to have it."); } else if (type == 3) // use inv on { player.Say("That's a funny idea."); } } else if (what == 3) // Unhandled events for CHARACTERS { if (type == 0) // look { player.Say("Hm."); } else if (type == 1) // interact { player.Say("Got nothing to say."); } else if (type == 3) // use inv on { player.Say("I don't think I should give that away."); } } else if (what == 5) // Unhandled events for INVENTORY ITEMS { if (type == 0) // look { player.Say("It's just some junk in my inventory."); } else if (type == 1) // interact { player.Say("Er, no?"); } else if (type == 3) // use inv on { player.Say("That's ridiculous."); } } } Après je maintiens ma remarque précédente (if, else if, else...) Donc que la reformulerai comme ceci : - Code:
-
// called when processclick wasn't handled anywhere else function unhandled_event (int what, int type) { if (cRoger.ActiveInventory == iCup) { // ... } else if (cRoger.ActiveInventory == iKey) { // ... } else if (cRoger.ActiveInventory == iEau) { // ... } else if (cRoger.ActiveInventory == iCanard) { // etc.
Dans le bloc suivant il décompose les cas entre what et type. C'est peut-être plus clair à suivre. C'est surtout mieux si à un moment donné tu veux complémenter cette fonction, pour couvrir différents genres d'évènements.[/code] |
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Script d'utilisation automatisée d'objets Dim 28 Jan 2024 - 14:13 | |
| J'ai trouvé. (J'ai bien eu tout ce que tu disais : unexpected token etc.) En fait le script "GlobalScript" c'est pas Global dans le sens que je croyais. (Enfin bref, je vais pas m'étendre là-dessus, on a assez divagué) Moi ce que je veux, c'est que la fonction JSP soit globale, c'est à dire disponible et appelable dans tous les scripts de room. Or apparemment, les fonctions dans GlobalScript y fonctionnent mais n'y sont pas appelables... (??? ok) La bonne manière de faire est expliquée ici : https://adventuregamestudio.github.io/ags-manual/ImportingFunctionsAndVariables.htmlDonc j'ai créé un script à part pour définir la fonction JSP (ce qui est pas plus mal, ce sera + accessible et + clair), et cette fonction est ensuite importée dans tous les scripts de room. Donc j'ai fait Edit Script et copié/collé la fonction JSP (et corrigé plusieurs détails) - Code:
-
function JSP(InventoryItem* iObjet) { if (iObjet == iCup) { player.ChangeView(4); player.Animate(0, 3, eOnce); player.ChangeView(5); player.Animate(0, 3, eOnce); player.ChangeView(4); player.Animate(1, 3, eOnce); player.ChangeView(1); player.Say("Dont know how Cup!"); } else if (iObjet == iKey) { player.ChangeView(4); player.Animate(0, 3, eOnce); player.ChangeView(5); player.Animate(1, 3, eOnce); player.ChangeView(4); player.Animate(1, 3, eOnce); player.ChangeView(1); player.Say("Dont know how Key!"); } else if (iObjet == iEau) { player.ChangeView(4); player.Animate(0, 3, eOnce); player.ChangeView(5); player.Animate(2, 3, eOnce); player.ChangeView(4); player.Animate(1, 3, eOnce); player.ChangeView(1); player.Say("Dont know how Eau!"); } else if (iObjet == iCanard) { player.ChangeView(4); player.Animate(0, 3, eOnce); player.ChangeView(5); player.Animate(3, 3, eOnce); player.ChangeView(4); player.Animate(1, 3, eOnce); player.ChangeView(1); player.Say("Dont know how Canard!"); } // TEMP else if(iObjet != null && iObjet.Name != null) { Display("JSP: %s", iObjet.Name); // < Objet à ajouter } else { Display("JSP: null (Pas d'objet actif..)"); } } Puis pour que soit automatiqument importé où il faut : Edit Header - Code:
-
import function JSP(InventoryItem* iObjet); Dans la Room1, j'ai ajouté l'intéraction sur le Hotspot "Pierres" : - Code:
-
function hPierres_UseInv() { if (cRoger.ActiveInventory == iKey) { cRoger.Walk(99, 135, eBlock, eWalkableAreas); cRoger.ChangeView(5); cRoger.Animate(1, 3, eOnce); cRoger.ChangeView(1); cRoger.Say("Oui, la clé sur la pierre, c'est une interraction convenable"); } else { JSP(cRoger.ActiveInventory); } } Donc, si j’emploie la clé sur les pierres, j'ai l'animation prévue et le message "Oui, la cl?? sur la pierre, c'est une interraction convenable"Si j'essaie n'importe quoi d'autre, j'ai l'animation et le message prévu dans la fonction JSP. En fin de compte, je m'explique pas pourquoi ça fonctionnait quand même sur les personnage ?? J'essaie de te packer l'exemple à télécharger. |
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Script d'utilisation automatisée d'objets Dim 28 Jan 2024 - 14:19 | |
| |
| | | Gob Adepte de la Grande Tasse Bleue
Nombre de messages : 123
Date d'inscription : 08/10/2021
| Sujet: Re: Script d'utilisation automatisée d'objets Dim 28 Jan 2024 - 16:48 | |
| Hello, oui, super, on dirait que ça marche bien ! Je vais essayer de mettre tout ça au point la semaine prochaine si j'ai le temps. Pour les anims génériques, elles seront liées à l'objet utilisé. Je ne vais pas regrouper les loops. Je te dirais quand j'aurais intégré toutes les utilisations d'objets, sur tous les persos et dans toutes les rooms déjà programmées, si je n'ai pas eu de souci. Encore merci ! |
| | | Gob Adepte de la Grande Tasse Bleue
Nombre de messages : 123
Date d'inscription : 08/10/2021
| Sujet: Re: Script d'utilisation automatisée d'objets Ven 2 Fév 2024 - 11:26 | |
| Hello ! Je continue de programmer mes utilisations d'objets, mais j'ai des cas que je ne comprend pas. Il fait la réaction prévue, puis il fait la réaction automatique anim objet, alors qu'il ne devrait faire que l'un des deux. Voici un des cas: [code=ags] function o7PorteFrig_UseInv() { if (cGob1.ActiveInventory == iTenailles) { player.Walk(671, 292, eBlock,eWalkableAreas);cGob1.FaceDirection(eDirectionLeft); aGob1Talk15.Play(eAudioPriorityHigh, eRepeat); cGob1.Say ("Mmh... Je doute que ça suffise..."); aGob1Talk15.Stop(); } if (cGob2.ActiveInventory == iLime) { player.Walk(646, 291, eBlock,eWalkableAreas);player.FaceDirection(eDirectionLeft); cGob2.ChangeView (94); cGob2.Animate (10, 3,eOnce, eBlock); cGob2.ChangeView (78); cGob2.Animate (2, 3, eOnce, eBlock); aLime.Play(eAudioPriorityHigh, eRepeat); cGob2.Animate (3, 3, eOnce, eBlock); cGob2.Animate (3, 3, eOnce, eBlock); cGob2.Animate (3, 3, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 1, eOnce, eBlock); cGob2.Animate (3, 1, eOnce, eBlock); cGob2.Animate (3, 1, eOnce, eBlock); cGob2.Animate (3, 1, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 2, eOnce, eBlock); cGob2.Animate (3, 3, eOnce, eBlock); cGob2.Animate (3, 3, eOnce, eBlock); cGob2.Animate (3, 3, eOnce, eBlock); aLime.Stop(); cGob2.Animate (4, 3, eOnce, eBlock); cGob2.ChangeView (94); cGob2.Animate (10, 3,eOnce, eBlock); cGob2.ChangeView (124); cGob2.FaceDirection(eDirectionLeft); Wait(25); o7PorteFrig.SetView(58); aChaine.Play(eAudioPriorityHigh, eOnce); o7PorteFrig.Animate(16, 3, eOnce); Wait(20); aGrincementPorte.Play(eAudioPriorityHigh, eOnce); o7PorteFrig.Animate(5, 5, eOnce);
o7PorteFrig.Clickable=false; } if (cGob2.ActiveInventory == iGantBoxe) { player.Walk(647, 290, eBlock,eWalkableAreas);player.FaceDirection(eDirectionLeft); cGob2.ChangeView (94); cGob2.Animate (10, 3,eOnce, eBlock); cGob2.ChangeView (78); cGob2.Animate (0, 3, eOnce, eBlock); aGob2Coup3.Play(eAudioPriorityHigh, eOnce); cGob2.Animate (1, 2, eOnce, eBlock); cGob2.ChangeView (94); cGob2.Animate (10, 3,eOnce, eBlock); cGob2.ChangeView (124); cGob2.FaceDirection(eDirectionLeft); } else {JSP(player.ActiveInventory);} } [/code]
Le problème est avec cGob1 et iTenailles. Il fait sa réplique. Après il fait son utilisation d'objet à vide. Je ne sais pas pourquoi. J'ai un autre cas, plus complexe parce qu'il y a plein de variables, mais déjà si on comprenait celui là, ce serait pas mal. |
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Script d'utilisation automatisée d'objets Sam 3 Fév 2024 - 7:43 | |
| Tout d'abord, va dans tes préférences du forum activer les BBcodes : https://adventuregamestudio.1fr1.net/profile?mode=editprofile&page_profil=preferencesC'est ce qui permettrait d'afficher correctement les blocs de code.
- Gob a écrit:
- Il fait la réaction prévue, puis il fait la réaction automatique anim objet, alors qu'il ne devrait faire que l'un des deux.
Non, non, non. C'est pas lui qui devrait faire qu'un des 2, c'est toi !En résumé t'as fait ça : - if iTenailles - if iLime - if iGantBoxe else JSP() Si tu pprocède comme ça, JSP() s'éxécutera à chaque fois que l'objet n'est pas iGantBoxe. Et donc logique que JSP() s’exécute après iTenailles ou iLime Même en théorie les 3 animations pourraient se produire à la suite : iTenailles, iLime, et iGantBoxe ou JSP() La seule chose qui l'en empêche, c'est le fait qu'il n'y ait qu'un objet d’inventaire actif à la fois. Voici le plan que tu dois suivre : - if iTenailles - else if iLime - else if iGantBoxe - else JSP() Faut vraiment que t'intègre cette notion de base. Si tu met plusieurs blocs "if" à la suite les un des autres, tous seront exécuté, et leur contenu si la conditions est vraie. (ils sont parfaitement indépendants les uns des autres). Mais quand tu fais if, else if, else if, else.. C'est comme si ces blocs sont reliés les uns aux autres, c'est seulement le 1er bloc dont la condition est vraie qui sera exécutée, et toutes les suivantes seront ignorées. Et c'est ce qu'on voudrait ici. Parce que JSP ne doit s’exécuter que si aucune des conditions précédentes n'est vraie. Je ne sais pas précisément pourquoi tu emploies différentes instances de personnage cGob1, cGob2... Dans l'abstraction, je crois que ce serait mieux pour ce cas de toutes les remplacer par player pour être sûr. Là par exemple, si le joueur est en train d'utiliser l'instance cGob2 et qu'il essaie l'objet iTenailles sur la porte, le 1er bloc de ton script ne se vérifierai pas : - Code:
-
if (cGob1.ActiveInventory == iTenailles) // FALSE if (cGob2.ActiveInventory == iTenailles) // TRUE Dans le script tu mélange les deux (player, cGob1...) - Code:
-
player.Walk(671, 292, eBlock,eWalkableAreas); // player cGob1.FaceDirection(eDirectionLeft); // cGob1 aGob1Talk15.Play(eAudioPriorityHigh, eRepeat); cGob1.Say ("Mmh... Je doute que ça suffise..."); // cGob1 aGob1Talk15.Stop(); Tu devrais remettre tout ça en cohérence, être plus rigoureux/régulier. ça peut parfois résoudre des petits problèmes, ou aider à déboguer. Même si dans ton scénario c'est cohérent : Que dans le scénario, cGob2 n'aurait jamais l'objet Tenaille dans son inventaire. Fais confiance à ton scénario pour gérer ça, et côté script fournis un contrôle le plus robuste. Après je dis ça, mais dans l'abstrait. C'est peut-être cohérent sur ce cas : prévu que cGob1 sache utiliser la tenaille sur la porte, mais cGob2 ne saurait pas le faire... Donc à toi de voir la chose. (Je peux pas deviner ce qu'il conviendrait de faire) |
| | | Gob Adepte de la Grande Tasse Bleue
Nombre de messages : 123
Date d'inscription : 08/10/2021
| Sujet: Re: Script d'utilisation automatisée d'objets Sam 3 Fév 2024 - 17:47 | |
| Hello, c'est bizarre, les BBCodes étaient activés, il devait manquer une accolade...
Oui, merci pour l'histoire du else, je ne voyais pas l’intérêt dans le cas des objets, puisqu'il utilise un objet à la fois. C'est très utile par contre dans les successions de dialogues. Dans ce cas du JSP, ça manque effectivement, j'essaye ça rapidement.
Je pourrais certes améliorer la cohérence de certaines lignes de code mais je ne peux pas tout retoucher pour le moment, la question du mix cGob et player n'a jamais posé de problème puisque je sais qui est player. Et je sais aussi qui utilise quel objet.
Ce que je vais essayer de retoucher, au moins par endroit, cs sont dans les cas comme ça: [code=ags]
if (machin==false) { cGob1.Animate(3,3,eBlock); } if (machin==true) { cGob1.Animate(4,3,eBlock); }
[/code]
... Et donc remplacer la deuxième variable par else, si tu penses que ça allège le travail du processeur. |
| | | Gob Adepte de la Grande Tasse Bleue
Nombre de messages : 123
Date d'inscription : 08/10/2021
| Sujet: Re: Script d'utilisation automatisée d'objets Sam 3 Fév 2024 - 17:49 | |
| ... Pourquoi ça ne marche jamais mes codes dans le forum ?? |
| | | Clique Adepte de la Grande Tasse Bleue
Nombre de messages : 106
Date d'inscription : 11/05/2022
| Sujet: Re: Script d'utilisation automatisée d'objets Sam 3 Fév 2024 - 19:33 | |
| Je viens de comprendre, c'est [code =ags] qui ne fonctionne pas. Utilise simplement la balise [code ][ /code] - Citation :
- pour l'histoire du else, je ne voyais pas l’intérêt dans le cas des objets, puisqu'il utilise un objet à la fois.
En fait c'est l'inverse, pour ce cas là t'as pas intérêt à faire succéder des blocs "if", même si logiquement ça fonctionnerait quand même. Coder ça se fait vite. Ce qui bouffe 80% du temps et de l'énergie, c'est de déboguer résoudre ou chercher des solutions. Donc prendre les bonnes habitudes / bonnes pratiques dès le départ, c'est un moyen de rationaliser cette 2e étape. ça t'obliges pas à passer en revue chacune des lignes du script. ça évite pas mal de soucis obscures, et t'as plus de chances de trouver des solutions/réponses à un problème en cherchant sur internet. En tout cas, pour que la fonction JSP fonctionne comme attendue, c'est absolument nécessaire. Elle est sensé s'exécuter quand toutes les autres éventualités sont exclues. Donc toutes ces éventualités se doivent d'être dans une même structure de contrôle. |
| | | Contenu sponsorisé
| Sujet: Re: Script d'utilisation automatisée d'objets | |
| |
| | | | Script d'utilisation automatisée d'objets | |
|
Sujets similaires | |
|
| Permission de ce forum: | Vous ne pouvez pas répondre aux sujets dans ce forum
| |
| |
| |