Salut 4ian,
Je voudrais savoir si Game Develop gère maintenant automatiquement la sélection des objets dans les conditions, particulièrement si la condition utilise deux objets (l’objet normal et et un deuxième objet de type quelconque) ?
Salut 4ian,
Je voudrais savoir si Game Develop gère maintenant automatiquement la sélection des objets dans les conditions, particulièrement si la condition utilise deux objets (l’objet normal et et un deuxième objet de type quelconque) ?
Les conditions qui utilisent plusieurs objets et/ou gèrent eux même la sélection des objets sont toujours un peu plus compliquées à écrire ( parce que cette complexité est prise en charge par GD dans le cas des actions/conditions “normales” ). Notamment, comme la gestion des objets dans le code compilé des évènements est fait à partir de composants les plus légers et simples possibles ( question de rapidité à la compilation et à l’utilisation ), c’est à dire en utilisant des conteneurs de la STL et des pointeurs bruts vers des objets ( Pas de boost par exemple ).
Le principe est de déclarer l’action avec ces paramètres ( Note que tous les paramètres disponibles sont listés dans la documentation de EventsCodeGenerator::GenerateParametersCodes ) :
instrInfo.AddParameter("object", _("Objet"), "", false); //Ce paramètre classique va demander à l'utilisateur l'objet qu'il souhaite utiliser.
instrInfo.AddCodeOnlyParameter("mapOfObjectListsOfParameter", "0"); //Ce paramètre caché va envoyer à la fonction une std::map contenant les objets qui proviennent du paramètre n°0. Ce numéro correspond donc ici aux objets du premier paramètre juste au dessus.
//..Déclaration des autres paramètres
La fonction va être appelée avec cette signature :
TaFonction( std::string , std::map <std::string, std::vector<Object*> *> objectsLists )
Le premier paramètre classique est ici le nom de l’objet. Le second contiendra une map, contenant (pointeurs vers) les listes d’objets qui correspondent à ce que demande l’utilisateur. ( Pourquoi pas une simple liste ? Car si l’objet que veux l’utilisateur est un groupe, il y aura plusieurs listes d’objets. Et pourquoi GD ne les fusionne pas de lui même ? Car ta condition va peut être vouloir modifier directement ces listes, d’où l’utilisation d’un pointeur ).
La plupart du temps, on fusionnera les liste des objets en une seule :
[code]double GD_API TaFonction( std::string , std::map <std::string, std::vector<Object*> > objectsLists )
{
//Partie où l’on récupère les objets
vector<Object> pickedObjects;
for (std::map <std::string, std::vector<Object*> *>::const_iterator it = objectsLists.begin();it!=objectsLists.end();++it)
{
if ( it->second == NULL ) continue;
std::vector<Object*> & list = *(it->second);
for (unsigned int i = 0;i<list.size();++i) pickedObjects.push_back(list[i]);
}
//On pourrait maintenant appliquer un traitement à chaque objet...
return pickedObjects.size(); //Ici, on renvoie le nombre d'objets concernés.
}[/code]
Pour une condition dans laquelle on veut récupérer deux listes d’objets :
[code]
bool GD_API HitBoxesCollision( string, string, std::map <std::string, std::vector<Object*> > objectsLists1, std::map <std::string, std::vector<Object> > objectsLists2, bool conditionInverted )
{
vector<Object> objects1;
for (std::map <std::string, std::vector<Object*> *>::const_iterator it = objectsLists1.begin();it!=objectsLists1.end();++it)
{
if ( it->second != NULL )
{
objects1.reserve(objects1.size()+it->second->size());
std::copy(it->second->begin(), it->second->end(), std::back_inserter(objects1));
it->second->clear();
}
}
vector<Object*> objects2;
for (std::map <std::string, std::vector<Object*> *>::const_iterator it = objectsLists2.begin();it!=objectsLists2.end();++it)
{
if ( it->second != NULL )
{
objects2.reserve(objects2.size()+it->second->size());
std::copy(it->second->begin(), it->second->end(), std::back_inserter(objects2));
it->second->clear();
}
}
//Test each object against each other objects
for(unsigned int i = 0;i<objects1.size();++i)
{
for(unsigned int j = 0;j<objects2.size();++j)
{
//...
}
}
}[/code]
C’était plus simple avant… Autant créer une fonction qui revoie la liste des objets demandés par l’utilisateur à la place de la faire au début de chaque action ? C’est bien ça le but d’une fonction, non ? Cette fonction serait membre de la classe Event et renverrait tous les pointeurs sur objets demandés ?
Merci 4ian pour toutes ces informations.
@sototo, rassure-toi, cela ne concerne que les actions/conditions qui utilisent deux objets (ou plus) en même temps. Et d’ailleurs, ce n’était pas plus simple avant.
Je dis que c’était plus simple avant parce qu’il y a eu beaucoup de changements depuis le SDK GDL2. C’est assez déroutant au premier abord.
Oui, certes, mais ici on parle de la gestion des objets qui n’a pas de changements particulier pour ceux qui utilisent le SDK, sauf pour cas des actions utilisant deux objets en même temps.
Pas d’inquiétude. Les actions de ce type sont relativement rares. Si le codage de telle action/condition est peu moins simple quand on connait pas la technique, je rappelle que les autres actions et conditions s’écrivent maintenant normalement plus simplement.
Une telle fonction ne serait pas une mauvaise idée ( encore une fois, le fait que ce genre de chose soit rare a fait que je n’ai même pas pensé à en inclure une. D’ailleurs, les bouts de code que j’ai donné ne font que fusionner des listes ), mais en tout cas elle ne sera surement pas dans la classe Event :
Question : Comment je renvois ensuite la liste des objets depuis ma condition ? (pour que GD sache que seuls les objets que j’ai choisis devront être “concernés” par les conditions / actions suivantes)
La map contient des pointeurs vers des listes d’objets : Tu peux donc directement les modifier dans ta fonction.
Donc, je peux pas fusionner les listes d’objets si je dois gérer les objets concernés ?