begin process at 2012 02 11 06:19:30
  Trouver un code source :
 
dans
 
Accueil > Forum > 

C++ & C++ .NET

 > 

Algorithme

 > 

Maths

 > 

Tri des membres d'une classe (std::vector ou std::list)


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Tri des membres d'une classe (std::vector ou std::list)

dimanche 16 septembre 2007 à 07:54:53 | Tri des membres d'une classe (std::vector ou std::list)

WolfSpirit2a

Salut à tous !
je suis actuellement en train de programmer un petit jeu sans prétentions en C++/SDL

Malheureusement je suis confronté à un problème sur lequel je bloque grave ...

J'ai créé un systeme qui charge une carte et l'affiche à l'écran.
Sur cette carte se balladent actuellement quelques personnages controlés
par ordinateur. Jusque là tout va bien, surtout qu'ils tiennent compte
des collisions etc ... ;)

Ces persos sont une instansation de la classe "Npc" que j'ai codé :

 				Npc *m_npc; 		
 				m_npc = new Npc[MAXNPCS]; 		

ainsi je créé un tableau de X Npc et j'accède à chaque Npc grâce à son
indice : m_npc[0] pour le 1er Npc par exemple.

Mon problème intervient lorsque je dessine mes persos à l'écran;
en effet, je les dessine un par un avec une boucle for :

 				for(int i = 0; i < MAXNPCS; i++) m_npc[i].draw(); 		

Ce qui fait que le perso avec le plus haut indice est toujours repeint en dernier.

Ceci pose problème lorsque certains persos repeints ont une coordonnée
Y inférieure aux autres Npcs repeints précédemment.

En fait cela créé un problème de chevauchement (les jambes d'un perso + haut sur l'écran vont
être peintent sur la tête d'un perso qui est plus bas si ce dernier a un indice inférieur dans le tableau m_npc).

Je voudrai donc trier mon tableau m_npc par la valeur de sa propriété "m_inf.m_y"
(m_npc[x].m_inf.m_y donc, qui est un entier qui représente la position Y du npc X. PS : m_inf est une structure)
pour qu'ainsi m_npc[0] ai le m_inf.m_y le plus petit et m_npc[n] ai le m_inf.m_y le plus grand.

Je me doute qu'il serait dangereux de toucher directement à la structure du tableau m_npc, j'ai
donc pensé à utiliser une std::list ou un std::vector qui contiendrai le pointeur de chaque indice
du tableau et à trier cette liste (ou ce vector) grâce à sa fonction sort().
Pour repeindre ensuite, il me suffirait de parcourir la liste (ou le vector), et d'utiliser chaque
pointeur qu'il contient pour repeindre mes persos.

L'autre problème c'est que je n'y connais absolument rien en list ou vector

Pourriez vous m'aider svp ?

dimanche 16 septembre 2007 à 11:48:56 | Re : Tri des membres d'une classe (std::vector ou std::list)

juju12

Y a sûrement sur ce site des dizaines de codes avec des listes chaînées, tu pourrais en récupérer un.
dimanche 16 septembre 2007 à 12:27:23 | Re : Tri des membres d'une classe (std::vector ou std::list)

luhtor

Réponse acceptée !
Je comprend pas pourquoi tu utilises un tableau basique, alors que tu pourrais utiliser systématiquement des std::vector.

std::vector<Npc*> m_npc; // ca me parait bcp plus logique.

Trier des persos revient à trier ce tableau ce qui se fait avec une banale fonction de tri. (artisanale)
dimanche 16 septembre 2007 à 18:19:44 | Re : Tri des membres d'une classe (std::vector ou std::list)

WolfSpirit2a

juju12 > Oui il y en a surement, j'ai même avec moi un bouquin de prog sur le C++ mais franchement j'y comprend rien ... pour utiliser un vector avec des type de style float, int, etc ... c'est sans problème (et encore, en excluant les foncteurs pour les tris, j'ai pas encore bien compris ça non plus...) mais pour faire des vector de classe et pouvoir utiliser chaque objet de mon vector comme si il était dans un tableau j'ai pas encore trouvé :(

luthor > je pensais plutot à conserver mon tableau et à utiliser un vector pour stocker les adresses de chaque pointeur vers les indices du tableau. Ceci dit il est vrai que si utiliser un vector est exactement la même chose qu'utiliser un tableau je pourrais peut être passer directement par un vector pour initialiser et gérer tous mes objets npc ... Mais en fait je me suis basé sur ce topic :
http://www.cppfrance.com/infomsg_TRIER-STD-MAP_552236.aspx
sur lequel j'ai cru comprendre que l'auteur utilisait un tableau + un vector à la fin... maintenant je peux très bien me tromper :/

Comment faire pour allouer dynamiquement un vector ? c'est avec "new" aussi ? style
std::vector<Npc*> m_npc;
m_npc = new std::vector<Npc>[MAXNPCS]
?
Pour ensuite utiliser la fonction init() par exemple d'un npc d'indice N il me suffit de faire

m_npc[n].init()

?

Et enfin, pour trier ce vector par m_inf.m_y croissant, quel foncteur dois-je appliquer ?

PS : Le tri va s'effectuer à chaque déplacement des npc (c'est à dire assez souvent vu qu'il y a 60 frames par seconde et qu'ils bougent quasi tout le temps ...), est-ce une bonne méthode ou ça risque de trop ramer comme ça ?

Merci !!
dimanche 16 septembre 2007 à 19:47:45 | Re : Tri des membres d'une classe (std::vector ou std::list)

luhtor

C'est débile d'allouer un std::vector. J'ai l'impression que tu comprends pas bien ce que c'est :)

std::vector<Npc*> m_npc; // <= la tu as un tableau dynamique, qui prend la taille qu'il faut

Npc * unObject = new Npc();
m_npc.push_back(unObject);

m_npc[0]->init();

Mais un conseil, que je te conseil de suivre: "au lieu de errer dans les entrailles austères de la STL". Prend deux minutes pour lire: ca:http://cpp.developpez.com/cours/stl/ (juste la partie qui t'intéresse, cad III. Les classes conteneur de la STL)

Pour le tri, il y a une méthode efficace, mais seulement si tu tolères quelques bugs de la durée d'une frame. Quand tu affiches tous les objets de ton vecteur a chaque frame, tu regardes si l'objet suivant dans le tableau est devant ou derrière l'objet actuel. Si l'objet suivant doit etre dessiné avant l'objet actuel, tu remplaces inverse les deux pointeurs du tableau. De cette facon, le coup du tri est quasiment nul mais génère quelques anomalies mineurs qui durent une frame.

Comme tu n'as pas l'air habitué à la STL, je vais utiliser des indices pour que tu comprennes. (en pratique, mieux vaut utiliser les std::vector<Npc*>::iterator. Tu comprendras apres avoir lu le site).

for(int k = 0 ; k < m_npc.size() ; ++k)
{
    if ((k < m_npc.size() - 1) && (m_npc[k]->DistanceALaCamera() > m_npc[k+1]->DistanceALaCamera()))
    {
        Npc * ptr = m_npc[k];
        m_npc[k] = m_npc[k+1];
        m_npc[k+1] = ptr;
    }

    m_npc[k]->draw();
}

De cette facon, le tri va se faire progressivement. Par exemple, si tu as 60 objets superposés, il faudra dans le pire des cas, 60 frames (cad 1seconde) pour que tous les objets soient triés.
lundi 17 septembre 2007 à 01:07:28 | Re : Tri des membres d'une classe (std::vector ou std::list)

WolfSpirit2a

Bon ben j'ai, grâce à votre aide, résolu mon problème.
Voilà la solution pour les intéréssés :

Il faut déclarer les Npcs non pas dans un tableau mais dans un vector :

vector<Npc *> m_npc;

Pour initialiser chaque Npc, je fait :

for(int i = 0; i < MAXNPCS; i++)
{
    Npc *npc_m = new Npc();
    m_npc.push_back(npc_m);
    m_npc[i]->initNpc();
}

Ensuite, dans la classe Npc, j'ai ajouté cette fonction membre :

déclaration dans npc.h:

static bool estDerriere(Npc *npc1, Npc *npc2);

dans npc.cpp :

bool Npc::estDerriere(Npc *npc1, Npc *npc2)
{
    return npc1->m_inf.m_y < npc2->m_inf.m_y;
}

Enfin, avant de dessiner les Npc à l'écran, j'appel :

sort(m_npc.begin(), m_npc.end(), Npc::estDerriere);

Ce qui à pour effet de trier mon vecteur !

Par contre j'ai une dernière question. Quand je fait un push_back(npc_m), l'objet pointé par npc_m (donc une instance de Npc) est "recopié" dans le vecteur ou celui-ci contient juste l'adresse du pointeur ? Parce que je voudrais savoir si il faut à un moment ou un autre que je vide npc_m avec un delete.

Voilà, merci à tous :)


Cette discussion est classée dans : problème, tableau, vector, std, npc


Répondre à ce message

Sujets en rapport avec ce message

tableau [ par ToToL ] Bonjour,j'ai un tableau créé de cette maniere :std::vector Pos;et a un moment j'ai besion d'en créé un autre qui doit etre une copie de Pos , quel es Problème avec std::vector et std::pair [ par luhtor ] J'ai une fonction qui compilait très bien sous linux, mais pas moyen de la compiler avec devCpp. Quelqu'un saurait pourquoi il la refuse ? template [C++, flux et fichier]Charger un fichier dans un vector<char> [ par PhilipMorris ] Bonjour à tous![^^happy10] Débutant en c++, je cherche à charger les octets d'un fichier dans un " vector tableau ", de la taille du fichier donc. J problème tableau [ par totoscill ] Bonjour,j'utilise un tableau pour stocker mes données mesurés. Le problème est que les valeurs stocké sont totalement différentes des valeurs données. Declaration de variables [ par wismerhill__ ] Bonjour, je cherche à faire qqch de tres simple : créer un std::vector dans un constructeur de classe.J'ai essayé MaClasse::MaClasse{monvecteur= new s Problème VBO et tableau dynamique [ par NiCoCC ] Bonjour, Alors voilà, quand je créer un tableau de Vertex[24][3] avec une taille déjà défini sa affiche un cube, donc tout va bien. Mais dès que je fa Problème de compréhension tableau. [ par fhoest ] Bonjour, je débute en c++ et j'ai un problème sur le dimensionnement d'un tableau, voilà ce que je ne comprend pas je défini un tableau de 5 (case) en exporter des objects STL et BOOST dans un DLL [ par bbking18 ] Bonjours, actuelement je travaille sur une petite biblioteque en c++, j'utilise des containeurs STL ( std::vector et std::set surtout ) et quelques ob Newbies et problème de pointeur [ par dartal ] Bonjour , J'ai quelque problème de compréhension au niveau de la gestion des pointeurs ... j'ai essayé de me documenter un maximum en lisant des comment instancier dynamiquement un "vector" [ par mohamed_bn ] Bonjour, J'aime construire une fonction qui retourne un vecteur d'entiers std::vector v; Pour pouvoir récupérer correctement ce tableau, normalement i


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 4,290 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales