c++sdl-2roguelike

I don't know how to manage my classes sturctures with SDL2


I try to create some C++ "rogue-like" game with SDL-2. For this I followed the Lazy foo's tutorial to understand how work with SDL.

I've studied C++/C# for 3 year but now I study project management and don't have no more IT courses...

Here's the github for the code : https://github.com/Paingouin/Roguelike-SDL2-train/tree/master/

I created 2 class : LTexture to help managing loading and rendering of a picture and Glyph to manage the animation/scaling and the positioning of the picture...

Now, I wanted create a Entity class, composed of a Glyph Object, which I would use to represent a Wall, a monster, an item etc... but, I think if I do that I will use too much memory...

Maybe I should use an aggregation by initialize an Array of pointer of Glyph and associate it to my Entity's object... I don't know, I'm lost...

Can you help me? And, have you any tips or advice to help me structuring correctly?


Solution

  • actually your question can be answered without reffering directly to SDL and same issue may arise with any library(like sfml) and the solution is all about the same: the answer is the singleton design pattern since your texture why i say singleton? let's talk about the wall tile. you might have thousands or even more wall tiles all have the same texture, do you really want to load it time and time agan per each wall? no. it's the same texture, you want to have one instance of each given texture, even more: you can save resource work if you use sprite sheet that contains EVERYTHING or have let's say 3 sheets: here's an example in sfml though the idea should be the same in SDL. https://en.wikipedia.org/wiki/Singleton_pattern

    here's an sfml implementation but the idea behind it should be clear and easy to immitate:

    class Resources {
     sf::Clock m_clock; //holds clock
     sf::Texture m_soma,m_lvl,m_enemies; //holds hero,lvl &enemies textures respectively
     sf::Font m_font; //holds game font
     Resources();
    public:
    
     ~Resources() {}
     Resources(const Resources &) = delete;
     Resources& operator=(const Resources &) = delete;
    
    
     static Resources& instance();
     sf::Texture& texture();
     sf::Texture& lvlTexture();
     sf::Texture& Enemies();
     sf::Clock& clock();
     sf::Font & Font();
    };
    

    cpp file: notice i could use a vector instead of 3 textures

    Resources::Resources()
    {
      //loading textures(hero,lvls,enemies)
       if (!m_soma.loadFromFile("..\\resources\\sprites\\soma.png"))
       {
           std::cerr << "problem loading texture\n";
           throw ResourceExceptions("couldn't load player sprites!: must have    ..\\resources\\sprites\\soma.png");
       }
    
       if (!m_lvl.loadFromFile("..\\resources\\sprites\\lv.png"))
       {
        std::cerr << "problem loading texture\n";
        throw ResourceExceptions("couldn't load level sprites!: must have ..\\resources\\sprites\\lv.png");
       }
    
       if (!m_enemies.loadFromFile("..\\resources\\sprites\\enemies.png"))
       {
           std::cerr << "problem loading texture\n";
           throw ResourceExceptions("couldn't load enemies sprites!: must have ..\\resources\\sprites\\enemies.png");
       }
     //loading font once
       if (!m_font.loadFromFile("..\\resources\\font\\gothic.otf"))
       {
           std::cerr << "problem loading font\n";
           throw ResourceExceptions("couldn't load game Font: must have ..\\resources\\font\\gothic.otf");
       }
    
     }
    
     Resources & Resources::instance()
     {
        static Resources resource;
        return resource;
     }
    
    sf::Texture & Resources::texture()
    {
        return m_soma;
    }
    
    sf::Texture & Resources::lvlTexture()
    {
         return m_lvl;
    }
    
    sf::Texture & Resources::Enemies()
    {
         return m_enemies;
    }
    
    sf::Clock & Resources::clock()
    {
        return m_clock;
    }
    
    sf::Font & Resources::Font()
    {
      return m_font;
    }
    

    eg. of usage would be: m_sprite.setTexture(Resources::instance().texture());

    //---------------------------------------

    same idea can be applied anywhere, even more, if by a chance you'll deal with 3d objects and will render those you'll find that singleton isn't even enough there and you can refer to the "flyweight" design patters overall i suggest you to read two things: gameprogrammingpatterns.com and the legendary book: Design Patterns: Elements of Reusable Object-Oriented Software

    there're several code issues that exist in your code: eg. the switch case on movement. ask yourself this "what happens if suddenly i want to add an extra action?" "what if for eg. i want it to behave differently according to the previous movement?" your approach will carry you to extensive and LONG switch cases. both will show you ways that will allow you to change code more easily