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

Auteur Sujet: Maps et fonctions constantes  (Lu 4204 fois)

0 Membres et 1 Invité sur ce sujet

Daymo

  • Newbie
  • *
  • Messages: 19
    • Voir le profil
Maps et fonctions constantes
« le: Avril 07, 2012, 12:14:02 pm »
Bonjour à tous !
Je tente actuellement de mettre en place un système de tile mapping, mais le "const" lors de la surcharge de la fonction "draw" me pose quelques problèmes, je m’explique :
J'ai créé une map qui fais correspondre chaque élément d'un tableau de pixel (une image) à un tile, et la surcharge de la fonction "draw" doit se charger d'afficher les tiles correspondants à chaque pixels, seulement, les fonctions constantes n'ont pas l'air d'aimer les maps, surtout que je suis obliger d'implémenter moi-même un objet se chargeant de classer les pixels dans la map, les objets "sf::Color" ne possédants pas leur propre opérateur "<" :
void TileMap::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    for(unsigned int x = 0; x < mPixelMap.getSize().x; x++)
        for(unsigned int y = 0; y < mPixelMap.getSize().y; y++) // Je parcours le tableau de pixel
        {
            std::map <sf::Color, sf::Sprite, Compare>::const_iterator Iterator = mPixelToTile.find(mPixelMap.getPixel(x, y)); // J'utilise un "const_iterator" et "find", l'opérateur [] n'étant apparement pas constant-correct
            target.draw(Iterator->second);
        }
}

Sauf qu'une erreur provient, je pense, de l'utilisation de "Compare" (désolé, c'est un peu long) :
Citation de: Build complet
-------------- Build: Debug in KirbySFML ---------------

Compiling: TileMap.cpp
In file included from c:\users\léo\desktop\programmation\librairies\mingw\bin\../lib/gcc/mingw32/4.5.2/include/c++/map:60:0,
                 from c:\users\léo\desktop\programmation\librairies\mingw\bin\../lib/gcc/mingw32/4.5.2/../../../../include/SFML/Graphics/Font.hpp:37,
                 from c:\users\léo\desktop\programmation\librairies\mingw\bin\../lib/gcc/mingw32/4.5.2/../../../../include/SFML/Graphics.hpp:35,
                 from C:\Users\léo\Desktop\Programmation\Projets\KirbySFML\/TileMap.h:4,
                 from C:\Users\léo\Desktop\Programmation\Projets\KirbySFML\TileMap.cpp:1:

c:\users\léo\desktop\programmation\librairies\mingw\bin\../lib/gcc/mingw32/4.5.2/include/c++/bits/stl_tree.h: In member function 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::find(const _Key&) const [with _Key = sf::Color, _Val = std::pair<const sf::Color, sf::Sprite>, _KeyOfValue = std::_Select1st<std::pair<const sf::Color, sf::Sprite> >, _Compare = Compare, _Alloc = std::allocator<std::pair<const sf::Color, sf::Sprite> >, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const sf::Color, sf::Sprite> >]':
c:\users\léo\desktop\programmation\librairies\mingw\bin\../lib/gcc/mingw32/4.5.2/include/c++/bits/stl_map.h:712:29:   instantiated from 'std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator std::map<_Key, _Tp, _Compare, _Alloc>::find(const key_type&) const [with _Key = sf::Color, _Tp = sf::Sprite, _Compare = Compare, _Alloc = std::allocator<std::pair<const sf::Color, sf::Sprite> >, std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const sf::Color, sf::Sprite> >, key_type = sf::Color]'
C:\Users\léo\Desktop\Programmation\Projets\KirbySFML\TileMap.cpp:26:124:   instantiated from here
c:\users\léo\desktop\programmation\librairies\mingw\bin\../lib/gcc/mingw32/4.5.2/include/c++/bits/stl_tree.h:1535:38: error: passing 'const Compare' as 'this' argument of 'bool Compare::operator()(const sf::Color&, const sf::Color&)' discards qualifiers

c:\users\léo\desktop\programmation\librairies\mingw\bin\../lib/gcc/mingw32/4.5.2/include/c++/bits/stl_tree.h: In member function 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_lower_bound(const std::_Rb_tree_node<_Val>*, const std::_Rb_tree_node<_Val>*, const _Key&) const [with _Key = sf::Color, _Val = std::pair<const sf::Color, sf::Sprite>, _KeyOfValue = std::_Select1st<std::pair<const sf::Color, sf::Sprite> >, _Compare = Compare, _Alloc = std::allocator<std::pair<const sf::Color, sf::Sprite> >, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const sf::Color, sf::Sprite> >, const std::_Rb_tree_node<_Val>* = const std::_Rb_tree_node<std::pair<const sf::Color, sf::Sprite> >*]':
c:\users\léo\desktop\programmation\librairies\mingw\bin\../lib/gcc/mingw32/4.5.2/include/c++/bits/stl_tree.h:1532:68:   instantiated from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::find(const _Key&) const [with _Key = sf::Color, _Val = std::pair<const sf::Color, sf::Sprite>, _KeyOfValue = std::_Select1st<std::pair<const sf::Color, sf::Sprite> >, _Compare = Compare, _Alloc = std::allocator<std::pair<const sf::Color, sf::Sprite> >, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const sf::Color, sf::Sprite> >]'
c:\users\léo\desktop\programmation\librairies\mingw\bin\../lib/gcc/mingw32/4.5.2/include/c++/bits/stl_map.h:712:29:   instantiated from 'std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator std::map<_Key, _Tp, _Compare, _Alloc>::find(const key_type&) const [with _Key = sf::Color, _Tp = sf::Sprite, _Compare = Compare, _Alloc = std::allocator<std::pair<const sf::Color, sf::Sprite> >, std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const sf::Color, sf::Sprite> >, key_type = sf::Color]'
C:\Users\léo\Desktop\Programmation\Projets\KirbySFML\TileMap.cpp:26:124:   instantiated from here
c:\users\léo\desktop\programmation\librairies\mingw\bin\../lib/gcc/mingw32/4.5.2/include/c++/bits/stl_tree.h:1020:2: error: passing 'const Compare' as 'this' argument of 'bool Compare::operator()(const sf::Color&, const sf::Color&)' discards qualifiers

Process terminated with status 1 (0 minutes, 1 seconds)
2 errors, 0 warnings

Y a t-il un moyen de contourner le "const" de la fonction "draw" ?
Je ne vois pas vraiment comment faire...  :-\

(EDIT : Est-il autorisé de traduire son post et d'en faire un doublon sur le forum anglais ?)
« Modifié: Avril 07, 2012, 04:46:19 pm par Daymo »
"C'est en forgeant qu'on devient musicien" - Les Shadocks

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Maps et fonctions constantes
« Réponse #1 le: Avril 07, 2012, 05:18:31 pm »
L'opérateur () de ton foncteur Compare doit être const.

Et je suis curieux : pourquoi avoir un sf::Color comme clé ? Ca marche comment ton truc ? :P

Citer
Est-il autorisé de traduire son post et d'en faire un doublon sur le forum anglais ?
Quand c'est un truc basique comme ça, non, ça fait plus de spam qu'autre chose. Si c'était pour demander des conseils de design, ou un débat qui nécessite d'avoir plusieurs avis, à la limite oui.
Laurent Gomila - SFML developer

Koryushin

  • Jr. Member
  • **
  • Messages: 93
    • Voir le profil
Re : Maps et fonctions constantes
« Réponse #2 le: Avril 07, 2012, 05:29:24 pm »
Je pense que le sf::Color en clef c'est pour le système de tilemap du Site du Zero.
Il utilise une feinte pour identifier les tiles à utiliser et du coup l'éditeur de niveau peut être paint ou tout autre logiciel de création d'image.

mPixelToTile[mPixelMap.getPixel(x, y)] ne fonctionne pas ?

Comment est déclaré le map mPixelToTile?
Un petit peu plus de code aiderait pour mieux xomprendre ce qui va pas  ;)
« Modifié: Avril 07, 2012, 05:35:01 pm par Koryushin »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Maps et fonctions constantes
« Réponse #3 le: Avril 07, 2012, 05:42:34 pm »
Citer
Je pense que le sf::Color en clef c'est pour le système de tilemap du Site du Zero.
Il utilise une feinte pour identifier les tiles à utiliser et du coup l'éditeur de niveau peut être paint ou tout autre logiciel de création d'image.
Et pourquoi ne pas transformer les couleurs en tiles au chargement ? Pourquoi se trimballer les couleurs dans un std::map tout le temps ? Une fois chargées, on n'a plus besoin des informations qui représentaient les tiles à l'origine.

Citer
mPixelToTile[mPixelMap.getPixel(x, y)] ne fonctionne pas ?
Non, car l'opérateur [] n'est pas const, il insère un élément si la clé n'existe pas encore.

Citer
Comment est déclaré le map mPixelToTile?
Un petit peu plus de code aiderait pour mieux xomprendre ce qui va pas
Bah, j'ai déjà donné la réponse hein ;)
Laurent Gomila - SFML developer

Daymo

  • Newbie
  • *
  • Messages: 19
    • Voir le profil
Re : Maps et fonctions constantes
« Réponse #4 le: Avril 07, 2012, 07:52:44 pm »
Citer
Comment est déclaré le map mPixelToTile?
Un petit peu plus de code aiderait pour mieux xomprendre ce qui va pas
Bah, j'ai déjà donné la réponse hein ;)
Effectivement, et merci beaucoup !  :D

Cependant, rien ne s'affiche encore... Je cherche de mon côté, et voici le code si le concept (piqué au SdZ) vous intéresse ! (J’accepte aussi de l'aide et toute autre remarque, à préciser que le seul affichage est la couleur de fond de la fenêtre. ;) )

/***** main.cpp *****/

#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>

#include "TileMap.h"

 int main(int argc, char *argv[])
 {
     // Initialisation
     sf::RenderWindow Window(sf::VideoMode(1200, 800), "SFML Window", sf::Style::Default);

     TileMap Map("TileSet.png", "PixelSet.png", "MenuMap.png");

     // Boucle principale
    while (Window.isOpen()) // Tant que la fenêtre est ouverte
    {
        sf::Event Event;

        while (Window.pollEvent(Event)) // On récupère l'évènement suivant de la pile
        {
            if(Event.type == sf::Event::Closed || sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) // Si Escape est appuyée ou si la fenêtre est fermée
                 Window.close(); // Alors on ferme la fenêtre
        }

        Window.clear(sf::Color::Blue);
        Window.draw(Map);
        Window.display();
    }

    return EXIT_SUCCESS;
 }

/***** TileMap.h *****/

#ifndef TILEMAP_H
#define TILEMAP_H

#include <SFML/Graphics.hpp>

#include <string>
#include <map>

class ColorComparaison {
public:
    bool operator() (const sf::Color &left, const sf::Color &right) const
    {
        return (left.r + left.b + left.g) < (right.r + right.b + right.g); // Just histoire de faire le tri...
    }
};

class TileMap : public sf::Drawable
{
    public:
        TileMap(const std::string &tile_set, const std::string &pixel_set, const std::string &pixel_map);

    private:
        virtual void draw(sf::RenderTarget& target, sf::RenderStates states = sf::RenderStates::Default) const;

    private:
        sf::Image mPixelMap; // Carte sous forme d'image, contenant des pixel qui correspondent chacuns à un tile
        std::map <sf::Color, sf::Texture, ColorComparaison> mPixelToTile; // Tableau de correspondance entre les pixels et les tiles

        sf::Vector2i mTileSize; // Taille d'un tile
};

#endif // TILEMAP_H

/***** TileMap.cpp *****/

#include "TileMap.h"

TileMap::TileMap(const std::string &tile_set, const std::string &pixel_set, const std::string &pixel_map)
{
    // On convertit les noms d'images en images
    sf::Image mPixelMap;
    sf::Image TileSet; // Alignement de tiles
    sf::Image PixelSet; // L'alignement de pixel correspondant à celui de tiles

    if( !(mPixelMap.loadFromFile(pixel_map) && TileSet.loadFromFile(tile_set)  && PixelSet.loadFromFile(pixel_set)) ) // Chargement des images
        exit(EXIT_FAILURE); // On termine le programme si une image n'est pas valide

    // Taille d'un tile
    sf::Vector2i mTileSize(TileSet.getSize().x / PixelSet.getSize().x, TileSet.getSize().y);

     // On attribue chaque pixel à un tile, suivant l'odre des sets
    for(unsigned int i = 0; i < PixelSet.getSize().x; i++) // Pour chacun des pixels...
        mPixelToTile[PixelSet.getPixel(i, 0)].loadFromImage(TileSet, sf::IntRect(mTileSize.x * i, 0, mTileSize.x, mTileSize.y));
}

void TileMap::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    static sf::Sprite Drawer;

    // On parcourt la carte de pixels
    for(unsigned int x = 0; x < mPixelMap.getSize().x; x++)
        for(unsigned int y = 0; y < mPixelMap.getSize().y; y++)
        {
            Drawer.setTexture(mPixelToTile.find(mPixelMap.getPixel(x, y))->second);
            Drawer.setPosition(mTileSize.x * x, mTileSize.y * y);
            target.draw(Drawer, states);
        }

    // Test :
    static sf::Sprite Test;
    Test.setColor(sf::Color::Green);
    Test.setPosition(0, 0);
    target.draw(Test, states); // Même cela ne s'affiche pas...
}

Merci à tous !  :)
"C'est en forgeant qu'on devient musicien" - Les Shadocks

Koryushin

  • Jr. Member
  • **
  • Messages: 93
    • Voir le profil
Re : Maps et fonctions constantes
« Réponse #5 le: Avril 07, 2012, 08:37:42 pm »
Comme à dit Laurent pourquoi ce trimballer un map. Normalement il n'y  plus besoin des infos sur les pixels pour la suite. Au chargement un vector<sf::Sprite> ou vector<tile> si tu veux gérer plus d'infos devrait suffire.
C'est comme ça que je me suis amusé avec le code de sdz pour le rendre objet et compatible sfml.
Au chargement j'initialise avec une fonction qui va bien mon vector de tile.
Tile etant une structure contenant un sprite, sa postition, et d'autre infos utiles.

Merci Laurent j'en apprends tous les jours je me régale ;D

Daymo

  • Newbie
  • *
  • Messages: 19
    • Voir le profil
Re : Maps et fonctions constantes
« Réponse #6 le: Avril 07, 2012, 11:20:47 pm »
Comme à dit Laurent pourquoi ce trimballer un map. Normalement il n'y  plus besoin des infos sur les pixels pour la suite. Au chargement un vector<sf::Sprite> ou vector<tile> si tu veux gérer plus d'infos devrait suffire.
C'est comme ça que je me suis amusé avec le code de sdz pour le rendre objet et compatible sfml.
Au chargement j'initialise avec une fonction qui va bien mon vector de tile.
Tile etant une structure contenant un sprite, sa postition, et d'autre infos utiles.
Jusque là, je me trimbalais une map pour pouvoir ensuite retrouver la position de chacun des tiles, mais je pense que je vais transformer ça en un std::vector<Tile>, car ce n'étais pas le meilleur choix. :P

Mais je ne comprends toujours pas pourquoi rien ne s'affiche à part la couleur de fond de ma fenêtre, j'ai pourtant réalisé un code assez semblable (pour l'héritage de sf::Drawable) avec un vieux snapshot de la SFML 2.0 qui fonctionnais très bien...
Ce que je trouve le plus étrange, c'est que même le sprite "Test" (voir dans la fonction draw) ne s'affiche pas !
"C'est en forgeant qu'on devient musicien" - Les Shadocks

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Maps et fonctions constantes
« Réponse #7 le: Avril 08, 2012, 08:21:59 am »
Citer
Ce que je trouve le plus étrange, c'est que même le sprite "Test" (voir dans la fonction draw) ne s'affiche pas !
Il n'a aucune texture, que voudrais-tu qu'il affiche ?

Pour le reste, je n'ai pas regardé.
Laurent Gomila - SFML developer

Daymo

  • Newbie
  • *
  • Messages: 19
    • Voir le profil
Re : Maps et fonctions constantes
« Réponse #8 le: Avril 08, 2012, 01:51:11 pm »
Au temps pour moi, je pensais qu'un sprite affichable avec une taille par défaut étais automatiquement créé, désolé !
Je pense que je pourrais me débrouiller pour le reste, merci encore. :)
"C'est en forgeant qu'on devient musicien" - Les Shadocks

 

anything