|
| Lancer son premier jeu | |
| | |
Auteur | Message |
---|
valoulef Délégué de la tasse bleue
Nombre de messages : 1791
Date d'inscription : 01/08/2011
| Sujet: Re: Lancer son premier jeu Ven 5 Juin 2020 - 20:01 | |
| La v-sync permet normalement d'éviter les problèmes d'affichage lié au fait que le débit du jeu est supérieur à celui de l'écran (ce qui peut engendrer un décalage où le haut de l'écran affiche l'image 0 tandis que le bas de l'écran affiche l'image 1, créant des sortes de lignes désagréables, par exemple lors d'un scrolling). Dans ton cas, où le jeu est peu ou pas animé, je ne pense pas que ça change grand chose. À noter que je ne suis pas sûr que ça fixe automatiquement à la fréquence d'affichage de l'écran, il me semble que généralement ça fixe la fréquence à 60, mais je peux me tromper. Je pense qu'il faut pas trop te tracasser avec ce genre de détails tant que le résultat te convient. |
| | | Arlann Cliqueur Amateur
Nombre de messages : 286
Date d'inscription : 06/04/2016
| Sujet: Re: Lancer son premier jeu Sam 6 Juin 2020 - 12:03 | |
| Oui il y a 2 sujets qui ce sont superposés c'est un peu embêtant, désolé d'en ajouter une couche mais comme j'étais lancé autant que je partage la suite ! Je sais que tu comptes utiliser les views des characters pour afficher tes états de personnages, c'est une solution tout à fait viable donc ne te focalises pas si je suis un peu têtu avec mes sprites dynamiques Je voulais simplement te montrer qu'avec cette struct de personnages tu peux automatiser beaucoup de choses afin gérer les nombreuses combinaisons d'état et de personnages. Cela dit, si tu comprends comment cela fonctionne tu pourras appliquer le même principe avec des Views. J'ai donc ajouté une fonction dans la struct pour composer une image d'avatar, tu la vois à la fin du header : - Code:
-
// Struc_Personnage.ash
#define TOTAL_PERSONNAGES 50 // Une constante pour définir le nombre max de perso du jeu
struct Personnage { String Nom; // Pour avoir le nom sous forme de string bool bonus1, bonus2, bonus3; // des variables simples int CHAR_SPRITE_SLOT; // Le slot qui contient le sprite original du personnage
DynamicSprite* spriteDynamic; // Pour composer l'image des avatars
// un exemple de variables gérées par la struct grâce à des Get/Set import attribute int Blessure, Maladie; // L'usage de ces variables est protégé par la struct protected int blessure, maladie; writeprotected bool Mort; // EDIT : J'ai changé cette variable en "protégée en écriture" car elle ne peut être modifiée que par la struct elle même // les fonctions suivantes sont internes à la struct, elles ne peuvent pas être appelées directement import int get_Blessure(); // $AUTOCOMPLETESTATICONLY$ import void set_Blessure(int _blessure); // $AUTOCOMPLETESTATICONLY$ import int get_Maladie(); // $AUTOCOMPLETESTATICONLY$ import void set_Maladie(int _maladie); // $AUTOCOMPLETESTATICONLY$
// des exemples de fonctions personnalisées import void GagneUnBonus(); import void ResetVariables();
import void UpdateSprite(); // La nouvelle fonction pour mettre à jour les images des avatars };
import Personnage personnage[TOTAL_PERSONNAGES]; La fonction est détaillée dans le corps du script , tu peux voir que je l'appelle depuis les autres fonctions de la struct et depuis les "Setters" des variables Blessure et Maladie - Code:
-
// Struct_Personnage.asc
// Instanciation d'un tableau de tous les personnages Personnage personnage[TOTAL_PERSONNAGES];
// La nouvelle fonction pour mettre à jour les images des avatars void Personnage::UpdateSprite() { // Copie l'image originale du perso dans son sprite dynamique this.spriteDynamic = DynamicSprite.CreateFromExistingSprite(this.CHAR_SPRITE_SLOT); // ouvre une surface de dessin pour ajouter des logos par dessus l'image de base DrawingSurface *surface = this.spriteDynamic.GetDrawingSurface(); // Si le joueur est mort on affiche un logo pour le signifier if (this.Mort) { surface.DrawImage(POS_X, POS_Y, IMAGE_MORT); // Les positions et le slot du sprite sont à définir } else // s'il n'est pas mort on dessine un logo par état { // Ajoute un logo de blessure // Les positions et le slot du sprite sont à définir if ( this.blessure==1 ) surface.DrawImage(POS_X, POS_Y, IMAGE_BLESSURE1); else if ( this.blessure==2 ) surface.DrawImage(POS_X, POS_Y, IMAGE_BLESSURE2); else if ( this.blessure==3 ) surface.DrawImage(POS_X, POS_Y, IMAGE_BLESSURE3); // Ajoute un logo de maladie // Les positions et le slot du sprite sont à définir if ( this.maladie==1 ) surface.DrawImage(POS_X, POS_Y, IMAGE_MALADIE1); else if ( this.maladie==2 ) surface.DrawImage(POS_X, POS_Y, IMAGE_MALADIE2); else if ( this.maladie==3 ) surface.DrawImage(POS_X, POS_Y, IMAGE_MALADIE3); // Ajoute les logos de bonus // Les positions et le slot du sprite sont à définir if ( this.bonus1 ) surface.DrawImage(POS_X, POS_Y, IMAGE_BONUS1); if ( this.bonus2 ) surface.DrawImage(POS_X, POS_Y, IMAGE_BONUS2); if ( this.bonus3 ) surface.DrawImage(POS_X, POS_Y, IMAGE_BONUS3); } // On peut ajouter le nom du perso sur l'image // Les positions, la couleur et la police sont à définir surface.DrawingColor = COULEUR_DE_TEXTE; surface.DrawString(POS_X, POS_Y, Game.NormalFont, this.Nom );
// ferme la surface de dessin surface.Release(); }
// retourne simplement la valeur de blessure int Personnage::get_Blessure() { return this.blessure ; }
// modifie la valeur de blessure selon tes propres règles void Personnage::set_Blessure(int _blessure) { this.blessure = _blessure; if ( this.blessure < 0 ) this.blessure = 0; // empêche la variable de passer en négatif if ( this.blessure >= 3 ) { this.blessure = 3; // Limite la variable à 3 maximum this.Mort = true ; // déclenche la mort à ce nombre de blessure } else this.Mort = false ; // S'assure que le perso n'est pas mort en dessous de 3 blessures this.UpdateSprite(); // Met à jour l'avatar à chaque fois que la variable est modifiée }
// idem pour les maladies int Personnage::get_Maladie() { return this.maladie ; }
void Personnage::set_Maladie(int _maladie) { this.maladie = _maladie; if ( this.maladie <0 ) this.maladie = 0; if ( this.maladie >=3 ) this.maladie = 3; this.UpdateSprite(); // Met à jour l'avatar à chaque fois que la variable est modifiée }
// exemple d'une fonction à appeler d'un script pour gagner un bonus void Personnage::GagneUnBonus() { if (!this.bonus1) this.bonus1=true; else if (!this.bonus2) this.bonus2=true; else if (!this.bonus3) this.bonus3=true;
this.UpdateSprite(); // Met à jour l'avatar à chaque utilisation de cette fonction }
// exemple d'une fonction à appeler d'un script pour faire un reset void Personnage::ResetVariables() { this.maladie = 0; this.blessure = 0; this.Mort= false; this.bonus1 = false; this.bonus2 = false; this.bonus3 = false; if ( this.Nom==null ) this.Nom = "UNKNOW"; this.UpdateSprite(); // Met à jour le sprite dynamique }
// permet d’accéder au tableau "personnage" depuis les autres scripts export personnage; J'ai également besoin de l'appeler une première fois au début du jeu quand les personnages sont créés. - Code:
-
// Fiche_Personnages.asc
void CreationPersonnages(int ID) { // J'initialise toutes les variables une première fois personnage[ID].ResetVariables(); // Je donne ensuite les valeurs de tous les personnages if (ID==0){ personnage[ID].Nom = "Wanda"; personnage[ID].CHAR_SPRITE_SLOT = 1 ; // Le slot du sprite importé // toutes les autres caractéristiques du personnage sont à ajouter ici. } else if (ID==1){ personnage[ID].Nom = "Amy"; personnage[ID].CHAR_SPRITE_SLOT = 2 ; // Le slot du sprite importé } else if (ID==2){ personnage[ID].Nom = "Phil"; personnage[ID].CHAR_SPRITE_SLOT = 3 ; // Le slot du sprite importé } //....jusqu'à if (ID==49)
personnage[ID].UpdateSprite(); // J'appelle la fonction une première fois pour créer les sprites dynamiques des avatars }
//La fonction suivante est automatiquement lancée par AGS au lancement du jeu function game_start() { // Je parcours une boucle au départ du jeu pour initialiser tous les personnages for ( int i=0 ; i < TOTAL_PERSONNAGES ; i++) CreationPersonnages(i); } Désormais il faut utiliser le sprite dynamique comme image du bouton qui permet d'afficher l'avatar du personnage joué. - Code:
-
int playerID ; // l'ID du perso à afficher
// called on every game cycle, even when the game is blocked function late_repeatedly_execute_always() { Button1.NormalGraphic = personnage[playerID].spriteDynamic.Graphic; } L’intérêt de tout ça est dans un premier de temps de gagner du temps car tu n'as plus besoin de composer plusieurs sprites d'état multipliés par le nombre de personnages. C'est également de ne plus te soucier de chercher l'image qui correspond à ton état de joueur car il suffit de faire : - Code:
-
personnage[playerID].Blessure++; ou - Code:
-
personnage[playerID].Maladie--; pour que l'image de l'avatar change automatiquement et cela va te simplifier le reste de ton code. A noter que pour bien faire dans mon exemple il faudrait passer les variables de bonus en Attribute comme Blessure et Maladie, car actuellement l'image est mise à jour seulement par la fonction GagneUnBonus() mais pas si tu fais : - Code:
-
personnage[playerID].bonus1=true; Tu peux bien entendu utiliser la fonction UpdateSprite(); à la suite mais ce n'est pas vraiment le but... J'espère que tu comprends la différence et l’intérêt que cela apporte, si c'est le cas tu vas aussi pouvoir automatiser l'usage de tes views assez facilement. Bon courage avec tout ça !
Dernière édition par Arlann le Sam 6 Juin 2020 - 18:43, édité 1 fois |
| | | Baguettator Cliqueur Amateur
Nombre de messages : 232
Date d'inscription : 21/05/2020
| Sujet: Re: Lancer son premier jeu Sam 6 Juin 2020 - 12:20 | |
| Cool merci ! Je venais de me connecter pour faire mon rapport Du coup, j'ai bien prévu d'utiliser des views car ça semble plus léger à mettre en place. J'ai donc créé des groupes de 5 persos par view, et chaque perso a une loop. En fonction de son état, je lui donnerai la frame 1, 2, 3 etc... Mais j'ai pensé que l'état "visuel" ne concernerait que les blessures. Pour la maladie, elle s'affichera à côté. Du coup j'ai pensé qu'il faudra des boutons pour contrôler la maladie et les blessures pour chaque joueur. Pour cela, j'ai pensé faire un GUI par perso (donc 50 GUi !!), avec à chaque fois les boutons blessure/soin, maladie/guérison qui font évoluer les variables blessure et maladie. Ces GUI seront affichés uniquement si le perso concerné est présent, et seront placés sans cesse autour du personnage (character). J'imagine faire ça dans la fonction repeatedly execute, où leurs coordonnées seront égales à celles du character, + ou - en fonction de si c'est en-dessous ou à côté. Mais la sprite dynamique peut peut-être m'être utile pour la maladie : je vais faire un bouton qui de base est invisible, et lorsque le perso est malade, le bouton s'affiche avec la sprite X (qui représente maladie - stade 1. Il y aura aussi le sprite maladie stade 2 et stade 3. Donc à chaque changement d'état, je demanderai au bouton de changer de sprite entre les stades de maladie ou l'image transparente si aucune maladie. ça doit être jouable avec ce que tu m'as déjà montré ? |
| | | Arlann Cliqueur Amateur
Nombre de messages : 286
Date d'inscription : 06/04/2016
| Sujet: Re: Lancer son premier jeu Sam 6 Juin 2020 - 12:35 | |
| - Baguettator a écrit:
- Pour cela, j'ai pensé faire un GUI par perso (donc 50 GUi !!), avec à chaque fois les boutons blessure/soin, maladie/guérison qui font évoluer les variables blessure et maladie. Ces GUI seront affichés uniquement si le perso concerné est présent, et seront placés sans cesse autour du personnage (character). J'imagine faire ça dans la fonction repeatedly execute, où leurs coordonnées seront égales à celles du character, + ou - en fonction de si c'est en-dessous ou à côté.
Tu devrais faire autant de gui que de personnages jouables simultanément, et non pas pour les 50 personnages. Tu devrais ensuite assigner chaque gui ou bouton de gui à un personnage pour que les contrôles agissent sur ses propres variables. EDIT : J'ajoute une précision, la position des characters et des objects sont relatifs aux coordonnées des rooms. Les positions des GUIs sont relatifs aux coordonnées de l'écran. Donc si ta surface de jeu (room) a une taille supérieure ou inférieure à la résolution de ton jeu il faudra compenser les positions entre eux. Je ne sais pas exactement ce que tu comptes faire, si tu as un grand plateau de jeu en scrolling avec des personnages qui se déplacent dessus ou s'ils sont censés se fixer dans une interface de jeu précise sur ton écran. Bref cela peut avoir une importance pour la suite. - Baguettator a écrit:
- Mais la sprite dynamique peut peut-être m'être utile pour la maladie : je vais faire un bouton qui de base est invisible, et lorsque le perso est malade, le bouton s'affiche avec la sprite X (qui représente maladie - stade 1. Il y aura aussi le sprite maladie stade 2 et stade 3. Donc à chaque changement d'état, je demanderai au bouton de changer de sprite entre les stades de maladie ou l'image transparente si aucune maladie.
C'est inutile d'utiliser une sprite dynamique dans ce cas, si tu n'as que 3 états à afficher dans un bouton, tu dois juste changer l'image du bouton en conséquence avec 3 sprites déjà fait. |
| | | Baguettator Cliqueur Amateur
Nombre de messages : 232
Date d'inscription : 21/05/2020
| Sujet: Re: Lancer son premier jeu Sam 6 Juin 2020 - 12:48 | |
| - Arlann a écrit:
Tu devrais faire autant de gui que de personnages jouables simultanément, et non pas pour les 50 personnages. Tu devrais ensuite assigner chaque gui ou bouton de gui à un personnage pour que les contrôles agissent sur ses propres variables.
En fait c'est possible qu'il y en ait beaucoup, sans doute pas les 50, mais comme c'est dur de l'estimer (car ça dépend de pas mal de paramètres), je vais faire les 50, et puis tant pis Par contre ça veut dire que j'attribue un GUI à un perso, ou alors l'attribution des GUI va pouvoir se faire via une fonction "générique" avec des variables ? |
| | | Arlann Cliqueur Amateur
Nombre de messages : 286
Date d'inscription : 06/04/2016
| Sujet: Re: Lancer son premier jeu Sam 6 Juin 2020 - 13:25 | |
| L'idéal serait d'avoir quelque chose de modulable pour t'éviter de multiplier les mêmes fonctions en permanence. Un même Gui ou un contrôle de Gui peut tout à fait agir sur des perso différents en utilisant par exemple le principe des index de tableau comme on t'a montré. Dans mon exemple : - Code:
-
personnage[playerID].Blessure++; mais tu peux faire cela sur des characters, des items des objets... - Code:
-
character[ID].View=VMALADE; object[ID].View=VMALADE; inventory[ID].Graphic=1; |
| | | Baguettator Cliqueur Amateur
Nombre de messages : 232
Date d'inscription : 21/05/2020
| Sujet: Re: Lancer son premier jeu Sam 6 Juin 2020 - 13:39 | |
| Oui, effectivement, mais le problème c'est qu'il faut alors lui faire comprendre à quel personnage il a affaire ? Et ça ça risque d'être compliqué ou moins "ergonomique" pour le joueur ? |
| | | Arlann Cliqueur Amateur
Nombre de messages : 286
Date d'inscription : 06/04/2016
| Sujet: Re: Lancer son premier jeu Sam 6 Juin 2020 - 13:57 | |
| Je ne suis pas certain de te comprendre… Si tu as besoin d’afficher 50 GUIs à l’écran pour contrôler 50 personnages, il te faut effectivement un GUI par perso. Si tu veux avoir 10 personnages à contrôler que tu as sélectionnés parmi les 50 disponibles, il te faut juste 10 GUIs pour contrôler les perso sélectionnés en fonction de leurs index (ou par une autre méthode). Pour le joueur c’est transparent, il a bien un GUI pour chaque personnage contrôlable, mais pour toi en interne cela t’évite de multiplier les même fonctions 50 fois. Bien sur si tu es plus à l’aise en faisant un GUI pour chaque perso c’est faisable. |
| | | Baguettator Cliqueur Amateur
Nombre de messages : 232
Date d'inscription : 21/05/2020
| Sujet: Re: Lancer son premier jeu Sam 6 Juin 2020 - 14:45 | |
| Bon alors j'ai réfléchi à une autre solution qui peut-être sera économe tant pour l'affichage que pour la réalisation :
- les persos à contrôler (ceux qui sont joués par le joueur) s'affichent donc en bas à gauche de l'écran.
- lorsqu'on clique sur l'un d'eux, ça fait apparaître en bas à droite une fenêtre qui montre l'image du perso sélectionné, ainsi que les fameux boutons qui vont changer son état.
- cela va permettre de ne créer qu'un seul GUI, avec un seul groupe de boutons qui vont affecter seulement le personnage sélectionné.
De cette manière, ça évite une multitude de boutons à l'écran pour un affichage plus léger !
ça devrait pouvoir se faire ? Le personnage sélectionné serait identifiable par quelque chose du genre de ce que tu m'as écrit plus tôt : personnage[ID] |
| | | Baguettator Cliqueur Amateur
Nombre de messages : 232
Date d'inscription : 21/05/2020
| Sujet: Re: Lancer son premier jeu Sam 6 Juin 2020 - 18:33 | |
| Et j'ai commencé à bien mettre les mains dans le camboui, bon j'espère que ce que je fais tiens la route... Effectivement je vais utiliser les views plutôt qu'un sprite dynamique. Comme il y a plusieurs jeux et extensions (je rappelle que le jeu que je crée est une sorte de "mode de jeu" à un jeu de société de plateau), il y a des personnages qui proviennent de plusieurs boîtes différentes. Je les ai regroupés ainsi, par "boite de jeu". Les persos de la boite 1 dans la View1, les persos de la boite 2 dans la View 2 etc... Et chaque perso a une loops attribuée. Dans la view 1, il y a 6 persos, donc 6 loops. Et chaque loops a le même nombre d'image pour représenter les différents états, pour tous les persos. Je me demande : cela va-t-il être possible de faire varier leur visuel grâce à ta fonction UpdateSprite ? J'essaye de l'adapter à ma situation, et j'ai l'impression qu'il va falloir plusieurs variables (une pour désigner la view, une pour désigner la loop, puis une pour désigner l'état du perso). Toi dans ton cas des Sprite Dynamiques, tu n'as utilisé qu'une variable CHAR_SPRITE_SLOT. Bon j'essaye de mettre ça en place, mais je galère bien... Mais j'apprends plein de choses EDIT : j'ai l'impression que la fonction "LockViewFrame" existe pas, ni "LockView" car quand je les écris dans le script elles n'apparaissent pas... |
| | | Arlann Cliqueur Amateur
Nombre de messages : 286
Date d'inscription : 06/04/2016
| Sujet: Re: Lancer son premier jeu Sam 6 Juin 2020 - 19:06 | |
| - Baguettator a écrit:
- Je me demande : cela va-t-il être possible de faire varier leur visuel grâce à ta fonction UpdateSprite ? J'essaye de l'adapter à ma situation, et j'ai l'impression qu'il va falloir plusieurs variables (une pour désigner la view, une pour désigner la loop, puis une pour désigner l'état du perso). Toi dans ton cas des Sprite Dynamiques, tu n'as utilisé qu'une variable CHAR_SPRITE_SLOT.
Si j'ai bien suivi, tu as juste besoin d'ajouter des variables de type int à la struct pour la View la Loop et la Frame et les définir à la création du personnage (à la place du CHAR_SPRITE_SLOT de mon exemple ) puis faire varier la variable Frame du personnage selon les conditions de son état dans ta fonction Update si tu veux garder la même logique. - Baguettator a écrit:
- EDIT : j'ai l'impression que la fonction "LockViewFrame" existe pas, ni "LockView" car quand je les écris dans le script elles n'apparaissent pas...
Si tu cherches à l'utiliser sur un personnage c'est normal ! C'est une fonction interne propre aux Characters. Donc si tu utilises un Character pour afficher ta View tu dois pouvoir faire : - Code:
-
character.LockViewFrame(personnage[ID].View, personnage.[ID].Loop, personnage[ID].Frame); |
| | | Baguettator Cliqueur Amateur
Nombre de messages : 232
Date d'inscription : 21/05/2020
| Sujet: Re: Lancer son premier jeu Sam 6 Juin 2020 - 20:33 | |
| OK, donc j'avais vu juste pour les variables de View, Loop et Frame ! Je suis fier Ah et pour le LockViewFrame, je comprends mon erreur : j'avais fait Character.LockViewFrame, alors que c'est character.LockViewFrame... Bon mais du coup, je crois que j'ai compris la chose ! En gros, tout résidera ensuite à appeller les bonnes fonctions au bon moment, et grâce à la structure, cela s'adaptera au personnage concerné le cas échéant ! Je retourne au travail, et je fais signe au prochain bloquage Vraiment merci pour l'aide, c'est incroyable ! EDIT : j'oubliais : lorsque je clique sur un perso, ça fera donc apparaître un GUI avec les boutons pour gérer les blessures/maladies. Il y aura aussi des ListBox que je pensais utiliser pour "lister" les différents bonus que le perso aura eu (au lieu d'afficher des icones, je trouve ça plus classe). J'imagine qu'on peut aussi relier le contenu d'une listBox à un personnage spécifique ? Exemple : Wanda a le bonus hache, Phil a le bonus pistolet. Si je clique sur Wanda, le GUI apparaît avec les boutons pour infliger une blessure, en retirer une, faire évoluer la maladie etc... Et dans la listeBox apparaît : "BONUS HACHE". Si je clique sur Phil, les mêmes boutons apparaîtront, mais dans la ListBox il y aura : "BONUS PISTOLET". J'imagine que ce genre de choses vont ressembler à : "ListeBonus.Text = personnage[ID].bonustous" Je maîtrise pas la syntaxe des ListBox (pas encore utilisées)... |
| | | Arlann Cliqueur Amateur
Nombre de messages : 286
Date d'inscription : 06/04/2016
| Sujet: Re: Lancer son premier jeu Dim 7 Juin 2020 - 7:10 | |
| - Baguettator a écrit:
- Vraiment merci pour l'aide, c'est incroyable !
De rien, les aléas font que j'avais du temps ces 2 derniers jours pour me rendre utile, je vais moins en avoir par la suite... - Baguettator a écrit:
- Bon mais du coup, je crois que j'ai compris la chose ! En gros, tout résidera ensuite à appeller les bonnes fonctions au bon moment, et grâce à la structure, cela s'adaptera au personnage concerné le cas échéant !
Oui cette structure permet de définir des variables et des fonctions qui sont propres à chaque personnage issu de cette struct. Tu les appelles donc directement depuis le personnage que tu manipules. Autre chose, car on est passé d’utiliser des items pour afficher des avatars à des Characters (ce qui est logique dans un jeu!). Tu as la possibilité d’ajouter un pointeur Character à chaque membre de la struct Personnage. Ma logique est que tu as 50 perso, mais peut être besoin que de 10 characters pour les utiliser pendant une partie. Donc un personnage aurait besoin d’un acteur pour l’incarner. - Code:
-
struct Personnage { Character *Acteur; //.... }; Grace au pointeur, quand tu utilises un personnage tu peux lui designer le character qui va l’incarner en faisant : - Code:
-
personnage[ID].Acteur = cChar1 ; // cChar1 un nom automatiquement donné par AGS pour l’exemple mais tu peux lui donner un nom de script par l’éditeur de Characters Ensuite tu peux appeler toutes les fonctions du character directement depuis le personnage: - Code:
-
personnage[ID].Acteur.LockViewFrame(//…); // cela va agir sur cChar1 comme tu l’as défini. Tu pourrais aussi décider d’avoir un character assigné par personnage et ne jamais en changer si cela te parait plus logique (pour 50 personnages ça reste jouable...) Bon je sais que ça doit être un peu abstrait expliqué comme ça, mais il y a un réel intérêt à utiliser ce genre de choses quand on manipule de nombreux éléments de jeu. Pour compléter tout ça je précise qu’il y a une méthode alternative pour se passer complètement des struct sur AGS. Tu pourrais simplement décider des créer 50 characters par l’éditeur avec chacun un nom et une view, puis de créer des propriétés personnalisées de Characters (onglet Properties dans le même éditeur) pour toutes les variables nécessaires. Tous les characters auraient leurs propres variables de propriétés, elles se manipuleraient ainsi : - Code:
-
if ( cChar1.GetProperty("Blessure") ==1 ) //Fait quelque chose cChar1.SetProperty("Maladie", 2 ); // Modifie la valeur En fabriquant des fonctions personnalisées pour automatiser les comportements tu peux arriver à faire la même chose qu'avec la struct Personnage C’est juste une histoire de goûts. Pour répondre rapidement à propos des ListBox, je pense que si tu en utilises une commune à tous les personnages il faudra effacer le contenu et la remplir à nouveau à chaque fois que tu changes de personnage. Il faut ensuite vérifier la string de l’item sélectionné pour déclencher une action spécifique, ce n'est pas forcement très facile à utiliser... Exemple : - Code:
-
if (lstBonus.Items[lstBonus.SelectedIndex] == "Bonus Pistolet" ) personnage[ID].Bonus1 = true;
Dernière édition par Arlann le Dim 7 Juin 2020 - 14:21, édité 1 fois |
| | | Baguettator Cliqueur Amateur
Nombre de messages : 232
Date d'inscription : 21/05/2020
| Sujet: Re: Lancer son premier jeu Dim 7 Juin 2020 - 13:41 | |
| Cool merci pour ce nouvel arrivage d'aide ! Cependant j'ai l'impression que la structure va aider et simplifier le code, car elle sera applicable à tous les personnages, tandis que les propriétés personnalisées des characters, faut les rentrer une par une... |
| | | Arlann Cliqueur Amateur
Nombre de messages : 286
Date d'inscription : 06/04/2016
| Sujet: Re: Lancer son premier jeu Dim 7 Juin 2020 - 14:33 | |
| Non, quand tu crées une propriété personnalisée avec le schéma que te propose l'éditeur de propriétés, tu dois choisir si cette propriété va s’appliquer aux Characters, Hotspots, Items, Objects ou Rooms. Tous les Characters du jeu, hériteront automatiquement des propriétés que tu as définies de façon générique avec une valeur par défaut. Tu peux ensuite les modifier au cas par cas dans l'éditeur. Tu peux aussi les manipuler par le script avec des fonctions personnalisées et reproduire les mêmes automatismes que pour l'exemple de la struct. - Code:
-
void Blessure(this Character*, int _blessure) { this.SetProperty("Blessure", this.GetProperty("Blessure") + _blessure ); if ( this.GetProperty("Blessure") > 3 ) this.SetProperty("Blessure", 3 ); else if ( this.GetProperty("Blessure") < 0 ) this.SetProperty("Blessure", 0 ); if ( this.GetProperty("Blessure") == 3 ) this.SetProperty("Mort", true); else this.SetProperty("Mort", false ); }
// Et appeler la fonction pour chaque perso. cChar1.Blessure(1); cChar2.Blessure(-1);
Dernière édition par Arlann le Lun 8 Juin 2020 - 13:35, édité 2 fois |
| | | Baguettator Cliqueur Amateur
Nombre de messages : 232
Date d'inscription : 21/05/2020
| Sujet: Re: Lancer son premier jeu Dim 7 Juin 2020 - 15:24 | |
| Ah ,intéressant ! En gros, les propriétés personnalisées sont des structures déjà prévues par AGS ? Du coup, ça me donne une idée ! Le jeu doit faire apparaître des cartes tirées au hasard. Y en aura beaucoup, en fonction des jeux/extensions que le joueur possède. Sur ces cartes, il y aura des objectifs qui seront disposés. Comme les cartes n'ont pas la même forme ni la même organisation interne, ces objectifs seront disposés manuellement au tirage de la carte (je veux dire : j'aurai scripté toutes les cartes pour que lorsqu'elles sont tirées, les objectifs sont placés au bon endroit pour chaque carte). Ces objectifs sont comme des pions (qui ne bougent pas), et permettent de trouver des ressources. Seulement, il y a 9 ressources, et les objectifs donnent une de ces ressources au hasard, selon des probabilités. Selon si l'objectif est dans un salon, il donnera plus souvent de la nourriture que du carburant, même s'il y a une petite possibilité d'en trouver. Et ainsi de suite pour les 9 ressources. Leurs probas sont différentes suivant les 9 types de salle où l'objectif se trouve (salon, garage, bureau etc...). Pour l'instant, j'ai créé 9 objectifs pour chaque type de salle (donc 81 objectifs !) car il peut y avoir maxi 9 objectifs par carte. Comme ça, je scripte la carte pour que les objectifs apparaissent de manière aléatoire dans les salles des bâtiments, et si par exemple l'objectif 1 attérit dans un salon, je place l'objectif salon1 dans cette salle. Si c'est dans un garage, je place l'objectif garage1. Et ainsi de suite. C'est pourquoi : 9 objectifs PAR type de salle, au cas où il y ait 9 salons Mais du coup, je pourrais peut-être faire une structure "Objectifs", où je définis les "règles" de chaque objectif en fonction du type de salle (les probas, en gros), puis je fais seulement 9 objectifs (via des boutons de GUI) et suivant là où ils se trouvent, je leur donne l'attribut "salon", ou "garage". Cela éviterait sans doute plein de lignes de code j'imagine ? Et peut-être plus de clareté. A savoir que la disposition des salles sur la carte n'est pas gérable, elle est sur la sprite de la carte, donc je scripte manuellement toutes les cartes pour faire apparaître les objectifs au bon endroit. Je me suis déjà fait une raison pour ce travail titanesque, mais avec les copier-coller, ça va |
| | | Arlann Cliqueur Amateur
Nombre de messages : 286
Date d'inscription : 06/04/2016
| Sujet: Re: Lancer son premier jeu Dim 7 Juin 2020 - 18:34 | |
| - Baguettator a écrit:
- Ah ,intéressant ! En gros, les propriétés personnalisées sont des structures déjà prévues par AGS ?
Non ce n’est pas vraiment la même chose. Je voulais juste te montrer une autre méthode fonctionnelle qui est peut être plus simple à utiliser. J’ai du mal à tout visualiser en ce qui concerne ton game design donc je n’ai pas trop d’avis sur la meilleure approche. Sache juste qu’il y a des options dans l’éditeur de Rooms qui peuvent peut être t’aider en dessinant des hotspots et des régions afin de définir les types de salles sur tes cartes. - Baguettator a écrit:
- Je me suis déjà fait une raison pour ce travail titanesque, mais avec les copier-coller, ça va
Il faut souvent se poser la question de comment factoriser un script avant de choisir le copier-coller, cela peut éviter les erreurs et les pertes de temps, mais parfois c'est nécessaire. Bon courage ! |
| | | Baguettator Cliqueur Amateur
Nombre de messages : 232
Date d'inscription : 21/05/2020
| Sujet: Re: Lancer son premier jeu Dim 7 Juin 2020 - 18:40 | |
| Bonsoir,
Alors j'ai passé pas mal de temps à préparer le terrain et à écrire les scripts, j'ai l'impression d'avoir déjà bien avancé !
Je me pose juste une question (qui est peut-être bête) :
- j'ai créé 50 characters, 1 pour chaque perso (par précaution, peu probable que les 50 soient utilisés en même temps, mais on sait jamais).
- j'ai bien créé la structure et la fiche personnage, avec les différents attributs pour chaque perso (définition de son image de base grâce aux variables CHAR_VIEW, CHAR_LOOP et CHAR_FRAME).
Le lien entre les personnages créés par la Fiche personnage (personnage[ID] avec ID=0 : Amy, ID=1 : Wanda, ID=2 : Phil) et les personnages "characters" (cAmy, cWanda, cPhil etc...) se fait par l'ID ? C'est à dire : il faut que cAmy ait l'ID 0 pour correspondre à "Amy" le personnage créé avec l'ID 0 dans la Fiche Personnage ?
Parce que là j'en suis au moment où je voudrais que lorsque je clique sur le character Amy, le jeu sait que cAmy c'est Amy (personnage[0]), cela ouvre l'interface (un GUI) avec les différents boutons qui vont pouvoir faire appel aux fonctions pour gérer les blessures/maladies sur le personnage Amy.
Et du coup, j'ai l'impression d'être un peu perdu... :S
EDIT : pardon, j'ai posté en même temps que toi...!
EDIT 2 : a priori, pas d'erreur de syntaxe à part un ";" oublié de mettre juste après avoir déclaré la structure. Le jeu démarre bien comme il faut, reste à faire fonctionner le tout. |
| | | Arlann Cliqueur Amateur
Nombre de messages : 286
Date d'inscription : 06/04/2016
| Sujet: Re: Lancer son premier jeu Lun 8 Juin 2020 - 7:35 | |
| C’est sur qu’avec 50 characters d’un côté et 50 personnages de l’autre cela peut devenir compliqué à manipuler. Peut être que les propriétés personnalisées aux characters seraient plus adaptées à ton cas. Je t’ai montré une méthode avec pointeur pour manipuler un character depuis un personnage, pour des raisons techniques on ne peut pas faire l’inverse. Par contre tu peux assigner l’ID des personnages aux characters qui les incarnent, en utilisant justement les propriétés personnalisées des characters et les définir à la création des personnages. Exemple dans création personnages : - Code:
-
if (ID==0) { personnage[ID].Nom = "Wanda"; cWanda.SetProperty("PersonnageID", ID ); // L'ID du personnage personnage[ID].Acteur = cWanda; // Le pointeur si besoin // toutes les autres caractéristiques du personnage sont à ajouter ici. } Ou utiliser, comme tu le dis, les ID internes des characters, mais il faudrait qu’elles correspondent parfaitement avec celles des personnages (dans le même ordre et de 0 à 49), ce ne serait pas très modulable si tu veux changer d'ordre par la suite. Pour afficher le résultat dans un GUI, tu dois utiliser une variable simple en local pour stocker l’ID désirée et l’utiliser dans ton GUI. Dans mon exemple elle s’appelait playerID. Donc quand tu cliques sur cWanda tu récupères son index de personnage: playerID = cWanda.GetProperty("PersonnageID");Et ton GUI affichera : personnage[playerID].Nom; |
| | | Baguettator Cliqueur Amateur
Nombre de messages : 232
Date d'inscription : 21/05/2020
| Sujet: Re: Lancer son premier jeu Lun 8 Juin 2020 - 8:15 | |
| OK, merci ! Alorsp our l'instant j'en suis là : - j'ai "altéré" la boucle de création de personnage pour que les ID correspondent aux ID des characters (par pure formalité, pour que ce soit plus clair, même si visiblement je ne vais pas me servir de ce "lien", c'ets juste plus rassurant !) : for (p=1, p < TOTALPERSONNAGE+1, p++) CreationPersonnage(); - puis dans "struct-personnage", le corps de script, j'ai fait ainsi : - Code:
-
if (ID==1) { personnage[ID].Nom = "Amy"; // le nom du perso cAmy.SetProperty("PersonnageID", ID); // la correspondance de l'ID du personnage avec le character personnage[ID].Acteur = cAmy; // le pointeur du personnage vers le character personnage[ID].CHAR_VIEW = 3; // la variable view que le character utilise (elle ne changera pas pour lui) personnage[ID].CHAR_LOOP = 0; // la variable loop que le character utilise (elle ne changera pas non plus pour lui) personnage[ID].CHAR_FRAME = 0; // la variable frame que le character utilise (elle, elle changera, il y a 21 frame qui montrent chacune un état particulier. Oui, 21 combinaisons, c'est encore gérable !) } else if (ID==2) // ainsi de suite... { personnage[ID].Nom = "Doug"; cDoug.SetProperty("PersonnageID", ID); personnage[ID].Acteur = cDoug; personnage[ID].CHAR_VIEW = 3; personnage[ID].CHAR_LOOP = 1; personnage[ID].CHAR_FRAME = 0; // etc... jusqu'à ID == 50 } Du coup, pour afficher l'interface qui va agir sur les variables blessure/maladie etc..., je devrai faire quelque chose du genre : - Code:
-
function cAmy_OnClick { playerID = cAmy.GetProperty("PersonnageID"); // on fait comprendre au jeu que c'est Amy qui nous intéresse gInterfacepersonnage.Visible=true; // le GUI de l'interface avec les boutons apparaît Interfacefond.Graphic=12 // Bon je sais pas encore comment syntaxer ça, mais en gros, on sait de quel perso il s'agit, donc le "fond" de l'inventaire personnage va changer pour représenter le personnage concerné, ici ce sera Amy. Ce sera juste un bouton (Interfacefond) qui va changer d'apparence pour prendre celle d'une sprite qui représente Amy (donc faudra donner son ID de Sprite, je regarderai comment formuler ça, mais ça doit être possible)
Ainsi, on aura fait le lien entre nos personnages et nos characters ? Reste plus qu'à appliquer ça aux boutons de "Interfacepersonnages" qui vont faire varier les variables blessure/maladie du personnage "pointé" et le tour est joué ! EDIT : ah, il faut définir SetProperty("PersonnageID", ID). => PersonnageID à définir. J'imagine que ça se fait dans le header de Struct_Personnages ? EDIT 2 : pardon, j'ai sûrement dit une grosse bêtise : en fait j'ai l'impression qu'il faut créer la Propriété "PersonnageID" dans le Schema des propriétés personnalisées, dire qu'elle s'applique aux characters. C'est bien ça ? EDIT 3 : effectivement, c'était ça. Donc je commence à comprendre des choses, merci !! J'ai d'ailleurs réussi à faire le lien : j'ai ajouté une ligne dans la struc personnage : - Code:
-
if (ID==1) { personnage[ID].Nom = "Amy"; cAmy.SetProperty("PersonnageID", ID); personnage[ID].Acteur = cAmy; personnage[ID].CHAR_VIEW = 3; personnage[ID].CHAR_LOOP = 0; personnage[ID].CHAR_FRAME = 0; cAmy.LockViewFrame(personnage[ID].CHAR_VIEW, personnage[ID].CHAR_LOOP, personnage[ID].CHAR_FRAME);// grâce à cette ligne, quand le personnage Amy apparaît, elle a le bon visage qui lui correspond. J'ai fait ça sur trois persos, et les visuels correspondaient bien !!! Je vais réutiliser cette ligne pour chaque bouton de l'interface. Lorsque on appuie sur le bouton Blessure, ça va faire +1 à la variable blessure de la structure. Ensuite la structure va définir quelle est la nouvelle valeur de CHAR_FRAME. Reste juste à appeller cette fameuse ligne pour mettre à jour le visuel du Personnage. Je sens que je touche au but !!! |
| | | Arlann Cliqueur Amateur
Nombre de messages : 286
Date d'inscription : 06/04/2016
| Sujet: Re: Lancer son premier jeu Lun 8 Juin 2020 - 9:56 | |
| J’ai un gros doute sur ton: - Baguettator a écrit:
- for (p=1, p < TOTALPERSONNAGE+1, p++) CreationPersonnage();
Le but de la boucle est d’instancier tous les éléments du tableau personnage, qui contient 50 valeurs, ils se trouvent forcement entre 0 et 49, donc tu ne peux pas lui demander des parcourir les index de 1 à 50 il va forcement crasher. De plus si tu ne précises pas l’itération de la boucle dans l’argument de la fonction CreationPersonnage( p ); cela ne va pas faire grand chose. - Baguettator a écrit:
- Je vais réutiliser cette ligne pour chaque bouton de l'interface. Lorsque on appuie sur le bouton Blessure, ça va faire +1 à la variable blessure de la structure. Ensuite la structure va définir quelle est la nouvelle valeur de CHAR_FRAME. Reste juste à appeller cette fameuse ligne pour mettre à jour le visuel du Personnage.
Il n’y a pas vraiment d’intérêt à utiliser LockViewFrame pour chaque personnage, ta fonction update d’images devrait plutôt prendre une forme générique un peu barbare comme: - Code:
-
personnage[ID].Acteur.LockViewFrame(personnage[ID].CHAR_VIEW, personnage[ID].CHAR_LOOP, personnage[ID].CHAR_FRAME); pour qu’elle puisse fonctionner sur tous les personnages quand tu vas modifier leur variables et se lancer automatiquement. Regarde comment j’avais utilisé la fonction UpdateSprite() de l’exemple. |
| | | Baguettator Cliqueur Amateur
Nombre de messages : 232
Date d'inscription : 21/05/2020
| Sujet: Re: Lancer son premier jeu Lun 8 Juin 2020 - 10:05 | |
| Pour la boucle, du coup j'avais réglé TOTAL PERSONNAGE sur 51 (et enlevé le +1), et ça marche bien ! Et pardon, c'est ma faute : j'ai bien écris CreationPersonnage (p) dans le script, j'ai juste oublié de le mettre dans mon post La première fois ça avait bien crashé, mais plus maintenant, et Amy est bien modifiée par Blessure et Maladie comme prévu. Donc j'imagine qu'il n'y a pas d'erreur ? Pour le LockViewFrame, j'avais oublié cette fonction ! En fait je l'avais supprimée car je n'utilisais pas le Sprite Dynamique, mais en effet ça peut "alléger" le code. Du coup au lieu de cette ligne gigantesque, y aura juste UpdateSprite(), mais dans tous les cas ça marche, et c'est déjà énorme pour moi ! |
| | | Baguettator Cliqueur Amateur
Nombre de messages : 232
Date d'inscription : 21/05/2020
| Sujet: Re: Lancer son premier jeu Lun 8 Juin 2020 - 14:37 | |
| Alors je reviens aux nouvelles ! Je pense que du côté de la structure tout fonctionne, j'ai pu adapter à ce que je voulais et tout fonctionne comme prévu, donc je considère ce problème comme résolu ! Par contre, vient maintenant l'étape fatale du positionnement... @valoulef (et tous ceux qui pourront m'aider là-dessus ) : J'ai réfléchi à ce que tu m'as expliqué. J'en ai déduit : 1- il faut définir où seront placés chaque perso, dans l'ordre (ça c'est fait, pas de souci) 2- il faut créer un tableau de personnages qui doit être dynamique (car le nombre de personnages du joueur va varier, c'est certain). Ce tableau permettra de définir que (par exemple) le character "wanda" sera positionné en premier, puis le character "amy" sera à côté, "phil" en 3ème etc... DONC attribuer des coordonnées à chaque ligne du tableau (position1, position2 etc...). 3- faire le lien entre "Wanda" et "Wanda est la deuxième du groupe, elle va en position2", "Phil" et "Phil est le premier du groupe, il va en position 1" etc... Alors je vais tenter de trouver un moyen de représenter ça, et si je trouve quelque chose qui semble fonctionner, je vous le mentionnerai par des EDITS, mais vraiment, vous gênez pas si vous vous voulez m'aider un peu, parce que je ne sais pas si je manipule encore bien les formules et la syntaxe pour ces choses assez complexes EDIT : déjà je me suis concentré sur les 6 premiers personnages que le joueur choisit lorsqu'il lance une nouvelle partie. Lorsqu'il valide le choix d'un personnage, une variable qui porte le nom de ce personnage prend la valeur 2. Donc il y aura 6 variables qui auront la valeur 2 à l'issue de ses choix. Lorsqu'il aura donc fini de choisir j'ai pensé faire quelque chose comme : - Code:
-
Character* persoscolonie[nbpersocolonie];
if (wanda==2) { nbpersocolonie=nbpersocolonie+1; cWanda.ChangeRoom(6, persoscolonie[nbpersocolonie].CoordX, persoscolonie[nbpersocolonie].CoordY); // Comment définir ces coordonnées CoordX et CoordY ? Je manque de pratique dans le code et la syntaxe... } if (amy==2) // et ainsi de suite pour tous les personnages. Jusqu'à nbpersocolonie=6. Déjà, cela permettra de faire apparaître les 6 persos choisis. Ensuite peut-être que ce tableau persoscolonie[nbpersocolonie] peut être utilisé pour mettre à jour les personnages du joueur en cours de partie ? Des événements, des morts, bref il y aura plein de raisons pour faire augmenter ou diminuer le nombre de personnages dont il disposera... |
| | | Arlann Cliqueur Amateur
Nombre de messages : 286
Date d'inscription : 06/04/2016
| Sujet: Re: Lancer son premier jeu Lun 8 Juin 2020 - 19:30 | |
| Si je comprends bien, tu utilises un tableau de characters persoscolonie pour contenir l'ordre des joueurs sélectionnés à afficher dans ta room de jeu. Donc il doit se composer un peu comme ça quelque part dans ton script : - Code:
-
int nbpersocolonie = 6 ; persoscolonie = new Character[nbpersocolonie]; persoscolonie[0] = cWanda; persoscolonie[1] = cAmy; //... Ensuite tu as besoin d'envoyer tous ces characters dans ta room de jeu et les afficher horizontalement dans l'ordre du tableau. Si l'un d'entre eux meurt, il doit sortir de la room de jeu et tous les autres se repositionnent en horizontal. Donc tu pourrais avoir une fonction dans ce style (je n'ai pas testé le code) : - Code:
-
void UpdatePositionsJoueurs() { for (int i=0 ; i< nbpersocolonie ; i++) { // Je regarde si le personnage associé est vivant pour le placer dans la room de jeu if ( personnage[persoscolonie[i].GetProperty("PersonnageID")].Mort == false ) persoscolonie[i].ChangeRoom( ROOM_DE_JEU ) ; else persoscolonie[i].ChangeRoom( -1 ) ; // ou l'enlever de la room s'il est mort } int PosX = ? ; // Position X de base à définir int PosY = ? ; // Position Y de base à définir for (int i=0 ; i < nbpersocolonie ; i++) { if (persoscolonie[i].Room == ROOM_DE_JEU) // si le character est présent dans la room je le positionne { persoscolonie[i].x = PosX; persoscolonie[i].y = PosY; PosX += ? ; // Décalage horizontal en pixels pour le prochain } } } Attention à une chose, dans AGS c'est le character que tu as défini en SetAsPlayer qui mène la danse. Si tu l'éjectes d'une room tu le suivras. |
| | | Baguettator Cliqueur Amateur
Nombre de messages : 232
Date d'inscription : 21/05/2020
| Sujet: Re: Lancer son premier jeu Lun 8 Juin 2020 - 19:52 | |
| Alors, pour ce qui est du player character, c'est un personnage invisible, donc il sera jamais éjecté puisque c'est grâce à lui qu'on passe d'une room à l'autre sans qu'il nous gêne Pour le tableau, j'y vois plus clair, j'avais commencé à faire quelque chose de similaire. Je m'étais lancé dans une structure avec 40 positions de personnages possibles (je croise les doigts, mais ça semble vraiment improbable qu'on ait à afficher les 50 persos côte à côte...!), ces 40 emplacements sont sur deux lignes (20 et 20). Du coup dans ma structure j'ai mis les Positions de chaque emplacement de cette manière : - Code:
-
Character* persoscolonie[40]; void PlacementPersonnages(int Position) { if (Position==1) { persoscolonie[1].x=13; persoscolonie[1].y=840; } if (Position==2) { persoscolonie[2].x=108; persoscolonie[2].y=840; } if (Position==3) { persoscolonie[3].x=203; persoscolonie[3].y=840; } if (Position==4) { persoscolonie[4].x=298; persoscolonie[4].y=840; } if (Position==5) { persoscolonie[5].x=393; persoscolonie[5].y=840; } if (Position==6) { persoscolonie[6].x=488; persoscolonie[6].y=840; } if (Position==7) { persoscolonie[7].x=583; persoscolonie[7].y=840; } if (Position== { persoscolonie[8].x=678; persoscolonie[8].y=840; } if (Position==9) { persoscolonie[9].x=773; persoscolonie[9].y=840; } if (Position==10) { persoscolonie[10].x=868; persoscolonie[10].y=840; } if (Position==11) { persoscolonie[11].x=963; persoscolonie[11].y=840; } if (Position==12) { persoscolonie[12].x=1058; persoscolonie[12].y=840; } if (Position==13) { persoscolonie[13].x=1153; persoscolonie[13].y=840; } if (Position==14) { persoscolonie[14].x=1248; persoscolonie[14].y=840; } if (Position==15) { persoscolonie[15].x=1343; persoscolonie[15].y=840; } if (Position==16) { persoscolonie[16].x=1438; persoscolonie[16].y=840; } if (Position==17) { persoscolonie[17].x=1533; persoscolonie[17].y=840; } if (Position==18) { persoscolonie[18].x=1628; persoscolonie[18].y=840; } if (Position==19) { persoscolonie[19].x=1723; persoscolonie[19].y=840; } if (Position==20) { persoscolonie[20].x=1818; persoscolonie[20].y=840; } if (Position==21) { persoscolonie[21].x=13; persoscolonie[21].y=960; } if (Position==22) { persoscolonie[22].x=108; persoscolonie[22].y=960; } if (Position==23) { persoscolonie[23].x=203; persoscolonie[23].y=960; } if (Position==24) { persoscolonie[24].x=298; persoscolonie[24].y=960; } if (Position==25) { persoscolonie[25].x=393; persoscolonie[25].y=960; } if (Position==26) { persoscolonie[26].x=488; persoscolonie[26].y=960; } if (Position==27) { persoscolonie[27].x=583; persoscolonie[27].y=960; } if (Position==28) { persoscolonie[28].x=678; persoscolonie[28].y=960; } if (Position==29) { persoscolonie[29].x=773; persoscolonie[29].y=960; } if (Position==30) { persoscolonie[30].x=868; persoscolonie[30].y=960; } if (Position==31) { persoscolonie[31].x=963; persoscolonie[31].y=960; } if (Position==32) { persoscolonie[32].x=1058; persoscolonie[32].y=960; } if (Position==33) { persoscolonie[33].x=1153; persoscolonie[33].y=960; } if (Position==34) { persoscolonie[34].x=1248; persoscolonie[34].y=960; } if (Position==35) { persoscolonie[35].x=1343; persoscolonie[35].y=960; } if (Position==36) { persoscolonie[36].x=1438; persoscolonie[36].y=960; } if (Position==37) { persoscolonie[37].x=1533; persoscolonie[37].y=960; } if (Position==38) { persoscolonie[38].x=1628; persoscolonie[38].y=960; } if (Position==39) { persoscolonie[39].x=1723; persoscolonie[39].y=960; } if (Position==40) { persoscolonie[40].x=1818; persoscolonie[40].y=960; } } function game_start() { for (int s=1 ; s<41 ; s++) PlacementPersonnages(s); } Ensuite j'espérais pouvoir faire le lien entre ce tableau des Positions et les personnages sélectionnés. Il va donc falloir fusionner ce que tu m'as montré là et ce que j'ai commencé donc ? EDIT : et aussi, si je me trompe pas, les tableaux sont à déclarer en haut du global script, et la fonction que tu as écrite (Updateposition) doit être mise en-dessous avec les autres fonctions ? |
| | | Baguettator Cliqueur Amateur
Nombre de messages : 232
Date d'inscription : 21/05/2020
| Sujet: Re: Lancer son premier jeu Lun 8 Juin 2020 - 20:54 | |
| Bon alors j'avance, j'ai essayé d'appliquer ce que tu as proposé en oubliant mon idée de structure !
Mais le tableau de characters, je n'arrive pas à le faire fonctionner...
En haut du global script, j'ai déclaré mes variables : int nbpersoscolonie; // la variable qui compte les personnages qui seront affichés Character* persoscolonie[]; // le tableau de characters
Dans la fonction game_start, je déclare le tableau dynamique : persoscolonie = new Character[nbpersoscolonie];
Je choisis les 6 persos, puis lorsque je valide, il y a quelque chose du genre : si [amy a été sélectionnée] { cAmy.ChangeRoom(6); persoscolonie[nbpersoscolonie]=cAmy; nbpersoscolonie++; }
Ainsi de suite pour chaque perso, on aura donc nbpersoscolonie=6 au bout du compte vu qu'on en aura sélectionné 6. Ils iront tous en room 6 (là où ils s'afficheront).
Puis j'ai créé la fonction que tu as montré, en la modifiant à ma situation :
void UpdatePositionsJoueurs() { int PosX = 13; // Position X de base à définir for (int s=0 ; s < nbpersoscolonie ; s++) { if (persoscolonie[s].Room == 6) // si le character est présent dans la room je le positionne { if (s<20) { persoscolonie[s].x = PosX; persoscolonie[s].y = 840; PosX += 95 ; // Décalage horizontal en pixels pour le prochain } if (s>=20) { persoscolonie[s].x = PosX; persoscolonie[s].y = 960; } } } }
Comme je l'ai dit le tableau de characters ne fonctionne pas, le jeu crasse sans cesse au lancement, en me disant que je suis "out of bounds". Mais je ne vois pas où est l'erreur...! J'ai encore des choses à apprendre... |
| | | Arlann Cliqueur Amateur
Nombre de messages : 286
Date d'inscription : 06/04/2016
| Sujet: Re: Lancer son premier jeu Mar 9 Juin 2020 - 7:17 | |
| Il y a en effet un peu de confusion avec l’usage des tableaux dynamiques. La taille du tableau est à définir en amont, tu peux ensuite lire et écrire seulement dans les limites de cette taille, sinon c’est le fameux « Out of bounds ». Il est important de comprendre que si la taille est 6, les index du tableau seront 0,1,2,3,4 et 5. C'est ainsi dans la plupart des langages informatiques, il faut faire attention pour éviter les crashs. Pour ton exemple: - Code:
-
Character* persoscolonie[]; // déclare le tableau de characters int nbpersoscolonie = 6; // la taille du tableau int indexpersoscolonie = 0; // la variable qui compte les personnages qui seront affichés
// Pour construire le tableau avant de l'utiliser persoscolonie = new Character[nbpersoscolonie];// il a donc une taille de 6 avec des index de 0 à 5 Encore une fois il serait utile de faire une fonction dédiée à la sélection: - Code:
-
void AjouteDansColonie(this Character*) { if ( indexpersoscolonie < nbpersoscolonie) { persoscolonie[indexpersoscolonie] = this; // ajoute le character dans le tableau indexpersoscolonie++; // passe à l'index suivant } if ( indexpersoscolonie == nbpersoscolonie ) // Lance le jeu si le tableau est rempli } Avec ça tu peux ajouter tes characters très facilement: - Code:
-
cWanda.AjouteDansColonie(); cAmy.AjouteDansColonie(); //... |
| | | Contenu sponsorisé
| Sujet: Re: Lancer son premier jeu | |
| |
| | | | Lancer son premier jeu | |
|
Sujets similaires | |
|
| Permission de ce forum: | Vous ne pouvez pas répondre aux sujets dans ce forum
| |
| |
| |