Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: trier des images avec std::sort et un zOrder  (Lu 2247 fois)

0 Membres et 1 Invité sur ce sujet

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
trier des images avec std::sort et un zOrder
« le: Novembre 10, 2014, 07:09:02 pm »
ReBonjour

Voici mon entité image, dérrivée de sf::Drawable. Je lui donne une texture, un vertexArray/quad, et un zOrder, pour les trier à la fin. J'ai créer une surcharge d'opérateur pour se faire, mais cela ne fonctionne pas...Ai-je fait une erreur?

voici mon Entité :

class EntiteImage : public sf::Drawable
{
public:

    friend bool operator < (const EntiteImage& a,const EntiteImage& b)
    {
    if (a.m_zOrder < b.m_zOrder)
            return true;
        else
            return false;
    }

    void recoiVertexArray(sf::VertexArray vertexArray)
    {
        m_vertexArray = vertexArray;
    }
    void recoiVertexEtTexture( sf::VertexArray vertexArray, sf::Texture *texture)
    {
        m_vertexArray = vertexArray;
        m_texture = texture;
    }

    void recoiZorder(float zOrder)
    {
    m_zOrder = zOrder;
    }


private:

    virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {
        states.texture = m_texture;
        target.draw(m_vertexArray, states);

    }

    float m_zOrder;
    sf::VertexArray m_vertexArray;
    sf::Texture *m_texture;
};

 


voici un exemple d'utilisation:

    m_entiteImage->recoiVertexEtTexture(m_vertexArray, m_texture);
    float zOrder;
    zOrder = m_y + m_tailleImage/2;
    m_entiteImage->recoiZorder(zOrder);
 

Et enfin l'appel depuis le main:

             ...
            while(afficheur.contientImage())
            {
            ptrentiteImageModel = afficheur.renvoiEntiteImage();
            ptrEntiteImage.push_back(ptrentiteImageModel);

            afficheur.imageSuivante();
            }

             sort (ptrEntiteImage.begin(), ptrEntiteImage.end());//////////////////////////utilisation du sort//////


            fenetre.clear(sf::Color::Black);
     

            for ( vector<EntiteImage*>::iterator it = ptrEntiteImage.begin() ; it!= ptrEntiteImage.end() ; it++ )
            {
            fenetre.draw(**it);//////////////////////////images bien affiché, mais non triés///////////////////
            }
            ...


 


Merci si vous pouvez m'aider

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : trier des images avec std::sort et un zOrder
« Réponse #1 le: Novembre 10, 2014, 08:27:22 pm »
Si ton tableau contient des EntiteImage* alors le tri se fera sur les pointeurs (des adresses mémoires), pas sur les instances pointées.

Note que définir un opérateur < juste pour faire un tri personnalisé, c'est à éviter (car cet opérateur n'a de sens que pour le tri, il ne définit pas réellement une relation "inférieur" entre deux entités). Il vaut mieux utiliser un foncteur que tu passeras en 3ème paramètre de std::sort.

struct TriEntite
{
    bool operator ()(const EntiteImage& a,const EntiteImage& b) const
    {
        return a.m_zOrder < b.m_zOrder;
    }
};

std::sort(ptrEntiteImage.begin(), ptrEntiteImage.end(), TriEntite());

Ou avec une expression lambda, si ton compilateur n'est pas préhistorique :

std::sort(ptrEntiteImage.begin(), ptrEntiteImage.end(),
          [](const EntiteImage& a,const EntiteImage& b) {return a.m_zOrder < b.m_zOrder;});

Note que si ton problème est bien que tu stockes des pointeurs, il suffit de remplacer "const EntiteImage&" par "const EntiteImage*" dans les deux solutions que je te donne.

PS : "recoi" c'est juste... pas possible. Utilise l'anglais, ton code ne s'en portera que mieux.
Laurent Gomila - SFML developer

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : trier des images avec std::sort et un zOrder
« Réponse #2 le: Novembre 11, 2014, 12:13:46 am »
Merci pour votre réponse.

J'ai utilisé cette solution, cependant il donne une erreur si je fais ainsi, en me disant "without in context" à propos de la struct, et error: "float EntiteImage::m_zOrder is private". (même chose si j'utilise un queconque attribut du private).
Si je met m_zOrder en public, en effet, ca ne plante plus, mais cela n'opère pas non plus, et parrait un peu illogique il me semble...
 voici le code:

class EntiteImage : public sf::Drawable
{
public:

    virtual void recoiVertexArray(sf::VertexArray vertexArray)
    {
        m_vertexArray = vertexArray;
    }
    void recoiVertexEtTexture( sf::VertexArray vertexArray, sf::Texture *texture)
    {
        m_vertexArray = vertexArray;
        m_texture = texture;
    }

    void recoiZorder(float zOrder)
    {
    m_zOrder = zOrder;
    }


private:

    virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {
        states.texture = m_texture;
        target.draw(m_vertexArray, states);

    }

    float m_zOrder;
    sf::VertexArray m_vertexArray;
    sf::Texture *m_texture;
};

struct TriEntite
{
        bool operator ()(const EntiteImage* a,const EntiteImage* b) const
    {
        return a->m_zOrder < b->m_zOrder;
    }

};

 
« Modifié: Novembre 11, 2014, 12:23:46 am par mazertys17 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : trier des images avec std::sort et un zOrder
« Réponse #3 le: Novembre 11, 2014, 09:31:38 am »
Ce serait bien d'avoir les messages d'erreur exacts plutôt que des bribes, et les lignes de code qui leur correspondent.

Sinon effectivement si l'attribut Z des entités n'est aucunement accessible publiquement, il faudra déclarer la structure TriEntite comme amie de la classe EntiteImage.
Laurent Gomila - SFML developer

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : trier des images avec std::sort et un zOrder
« Réponse #4 le: Novembre 11, 2014, 10:57:51 am »
Merci pour votre réponse.

Oui, j'ai rajouté ceci:

    friend struct TrieEntite;

qui me permet d'utiliser l'attribut private m_zOrder.
Cependant, cela ne fonctionne toujours pas.
Peut être cela vient de mes pointeurs...Je suis encore un peu embrouillé à ce propos, et me pose quelques quesitons:

Quelle différence y a-t-il, fondamentalement, entre:

     vector<EntiteImage*> ptrEntiteImage;

et

     vector<EntiteImage> *ptrEntiteImage;  



une autre question, peut on utiliser ceci, sans que cela pose des problèmes de mémoire ?

private:
       EntiteMachi *m_entiteMachin[4];
 


         m_entiteMachin[nombreQuelquonque] = new EntiteMachin;
         m_entiteMachin[nombreQuelquonque]->recoiQuelquechose(bidule, &pointeurTruck);

 


Merci encore pour votre aide  :)
« Modifié: Novembre 11, 2014, 11:50:29 am par mazertys17 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : trier des images avec std::sort et un zOrder
« Réponse #5 le: Novembre 11, 2014, 02:59:51 pm »
Citer
Cependant, cela ne fonctionne toujours pas.
Au lieu d'essayer des choses "au pif" et d'attendre que ça marche, essaye de cerner le problème. Teste chaque élément concerné séparément, utilise ton debugger, etc. Bref, comprend ton code ;)

Citer
Quelle différence y a-t-il, fondamentalement, entre:

     
vector<EntiteImage*> ptrEntiteImage;

et

     
vector<EntiteImage> *ptrEntiteImage;
 
Le premier est un vecteur de pointeurs, le second est un pointeur vers un vecteur d'objets.

J'ai déjà dû te le dire, mais je préfère me répéter : s'aventurer dans des jeux avec SFML sans savoir faire un minimum de C++, ça ne sert à rien sinon à foncer dans le mur et à squatter les forums...

Citer
une autre question, peut on utiliser ceci, sans que cela pose des problèmes de mémoire ?
Je préfère te laisser comprendre ce que fait ce code, et en déduire par toi-même la réponse ;)
Laurent Gomila - SFML developer