Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: How to code nicely with SFML?  (Read 4859 times)

0 Members and 1 Guest are viewing this topic.

easy

  • Full Member
  • ***
  • Posts: 146
    • MSN Messenger - easy82.contact@gmail.com
    • View Profile
    • Email
How to code nicely with SFML?
« on: August 24, 2011, 05:46:35 pm »
Hello!

I've got concerns about the my current game code. It's going to be a simple game but with educative code inside, a proof-of-concept. It's more advanced than the provided pong example, so I needed to separate objects.

Currently I've got a bunch of .h and .cpp files:
    CAnimator - an animator class for animating sprites,
    CCamera - manages cameras for one or two players,
    CEntity - handles the players, monsters,
    CInterface - all the GUI stuff is in here,
    CLevel - manages the level related stuff,
    CGame - groups all these togther, [/list]

    It all works fine, and shaping up really nicely, but there are some things I don't like about it:
      - It's half this and half that: SFML has references all around, and my classes use pointers (the actual example below does not actually show the pointers)
      - Due to the SFML design, I'm not passing pointers but references to the constructors, which enforces me to initalize them on startup... which is exxxtremely restrictive
      - I like the clean design of SFML but I seem to not understand some basic concepts here... I'm a pointer-user guy


    For example, look at the following piece of code. You can see the animator  and the entity class constructors. Since the entity has 2 animators, I have to initiate them in the constructor. And the dependencies would grow from class to class.

    Code: [Select]
    //! Constructor
    CAnimator(sf::RenderWindow& Window, sf::Texture& Texture, int TileSize, sf::Sprite& Sprite,
              const SAnimation& Animation = SAnimation())
    : window(Window), texture(Texture), tileSize(TileSize), sprite(Sprite), animation(Animation)
    {
    /* ...*/
    }

    //! Constructor
    CEntity::CEntity(sf::RenderWindow& Window, sf::Texture& Texture, int TileSize, CLevel& Level,
                     CInterface& Interface, const sf::Vector2i& TilePos, int Direction)
        : window(Window), texture(Texture), tileSize(TileSize), level(Level), interface(Interface),
          tilePos(TilePos), direction(Direction),
          bodyAnimator(window, texture, tileSize, body), faceAnimator(window, texture, tileSize, face)
    {
      /* ... */
    }


    So, basically, I'd like advises on: How to code nicely with SFML?

    Thanks in advance,
    easy

    Nexus

    • SFML Team
    • Hero Member
    • *****
    • Posts: 6287
    • Thor Developer
      • View Profile
      • Bromeon
    Re: How to code nicely with SFML?
    « Reply #1 on: August 24, 2011, 05:59:10 pm »
    Quote from: "easy"
    - It's half this and half that: SFML has references all around, and my classes use pointers (the actual example below does not actually show the pointers)
    If this doesn't please you, then use references. Generally, you will always be confronted with different code styles when using different libraries, you should get used to it.

    Quote from: "easy"
    - Due to the SFML design, I'm not passing pointers but references to the constructors, which enforces me to initalize them on startup... which is exxxtremely restrictive
    Actually, direct initializations are better, since they can guarantee a consistent object state. Don't use subsequent Init() functions unless absolutely necessary. Initialize objects as soon as possible and don't provide default constructors that leave the object in a meaningless or even erroneous state.

    But apart from that, transforming references and pointers to each other is trivial. You don't need to use references yourself just because SFML does.

    Quote from: "easy"
    - I like the clean design of SFML but I seem to not understand some basic concepts here...
    You have to be more specific.

    Quote from: "easy"
    For example, look at the following piece of code. You can see the animator  and the entity class constructors. Since the entity has 2 animators, I have to initiate them in the constructor. And the dependencies would grow from class to class.
    Well, your animator class tends to have too much responsibilities. Why don't you write a function void Animate(sf::Sprite& sprite)? That's what I did in thor::Animator. Why does it even need a sf::RenderWindow? The sprite can be drawn from the outside.

    The Entity class is even worse: While it should be a class purely related to game logics, it contains a lot of data that is used to draw it. Don't let the entities draw themselves, do this from the outside (for example by a central Renderer class). Separate graphics and game logics. You'll find about 20 threads in this forum where I gave a detailed explanation about that separation ;)

    And don't use that "C" prefix. The reasons are explained here.
    Zloxx II: action platformer
    Thor Library: particle systems, animations, dot products, ...
    SFML Game Development:

    easy

    • Full Member
    • ***
    • Posts: 146
      • MSN Messenger - easy82.contact@gmail.com
      • View Profile
      • Email
    How to code nicely with SFML?
    « Reply #2 on: August 24, 2011, 06:35:43 pm »
    Thanks for your answers Nexus!

    I'm going to have a look at your project Thor and see how you handle all these situations.

    I think yes, it's possible to separate graphics (sound, network, etc.) and logic in my case, too, but I think it's also logical that an object should take care of itself. You know the old examples of a the Box which is a class, and you can move/rotate/scale/draw it.

    If I follow you correctly I should draw this Box in another place according to the parameters of the Box. In this case, Box is like a container. This way I can drop most of the dependencies of my classes. True, true and true. But I think this logic comes from the design of SFML.

    About the "C" prefix: I use them on my classes. For the structs I use "S" and for the enums I use "E" prefixes.

    Nexus

    • SFML Team
    • Hero Member
    • *****
    • Posts: 6287
    • Thor Developer
      • View Profile
      • Bromeon
    How to code nicely with SFML?
    « Reply #3 on: August 24, 2011, 06:53:32 pm »
    Quote from: "easy"
    but I think it's also logical that an object should take care of itself
    That is only true up to a certain degree. The object has to interact with its environment anyway, and some functionality (like rendering) is mostly more appropriate when outsourced.

    To take SFML as an example, sf::Sprite doesn't draw itself, but sf::RenderWindow draws it. You can apply a similar concept to your design. The big advantages are that the dependencies are smaller, and that you only have to adapt your Renderer class if something in SFML changes or if you want to add rendering functionality (like colorizing). With your current approach, you would have to modify every entity.

    Quote from: "easy"
    About the "C" prefix: I use them on my classes. For the structs I use "S" and for the enums I use "E" prefixes.
    What do you use for typedefs and templates? My points are 1. that the exact type category (class, struct, enum, something else) is often irrelevant, and 2. that you can't be consistent at all. It is not possible to add a "C" prefix to every class in C++, at latest if you use generic code. In the end, type prefixes promise more than they keep, and thus may lead to unnecessary confusion without bringing any real advantages.
    Zloxx II: action platformer
    Thor Library: particle systems, animations, dot products, ...
    SFML Game Development:

    easy

    • Full Member
    • ***
    • Posts: 146
      • MSN Messenger - easy82.contact@gmail.com
      • View Profile
      • Email
    How to code nicely with SFML?
    « Reply #4 on: August 24, 2011, 08:11:13 pm »
    I need to think the design of the code over again according what you've suggested.

    As for the prefix issue:
    - Typedefs: practically I don't use typedefs. I know I did, but I just cannot recall when I used them (it must have been a long time ago). What's the problem with them?

    - Templates: I'm trying to avoid them, whenever it's possible. If they're a must, I only use them for smaller classes. Example:

    template<class T> class CManager;

    CManager<CEntity> entities;

    Nexus

    • SFML Team
    • Hero Member
    • *****
    • Posts: 6287
    • Thor Developer
      • View Profile
      • Bromeon
    How to code nicely with SFML?
    « Reply #5 on: August 24, 2011, 11:17:33 pm »
    Quote from: "easy"
    - Typedefs: practically I don't use typedefs. I know I did, but I just cannot recall when I used them (it must have been a long time ago). What's the problem with them?
    I'm using typedefs all the time, mostly for containers. Identifiers are shorter and type modifications (like std::list to std::vector) are only necessary in one place.

    The problem with them is that you have to decide whether you use "C" for typedefs, too. If you do, you go against the original intention, namely to abstract from types. When you suddenly use a BigInt class instead of int, you have to rename all corresponding typedefs. If you don't, you break with the convention that all class types are prefixed with "C", so you cannot rely on it anymore. In both cases, you're better off without any prefix.

    It is even more extreme for struct and class: These keywords are absolutely identical except for the default visibility. Structures are classes. Especially if you use private and public to denote all members, you can directly replace struct/class by the other keyword and have exactly the same semantic. Nevertheless, your convention enforces a change in the type name.

    Quote from: "easy"
    - Templates: I'm trying to avoid them, whenever it's possible. If they're a must, I only use them for smaller classes.
    I have a lot of templates in reusable libraries, and a few in client projects. Again, you loosen your convention, since class templates are actually no classes. Also consider the template parameters (like T): In generic code, you can't say whether a type is a class or not. Anyway, it is completely irrelevant. But again, you suddenly have class types in your code without being prefixed, which is inconsistent.

    But more important, why do you need to know whether a type is a class or not? It often doesn't matter. In cases where it does matter, you need to know more about the type anyway in order to use it (e.g. which methods it provides). You don't get any relevant information by using prefixes, but still have the above mentioned drawbacks.

    Notice that this naming convention with "C" prefixes had another origin (sort of namespace for MFC classes, like "gl" for OpenGL). It was considered a good idea to use in own code by some programmers, with the result that MFC classes and own user code cannot be distinguished anymore. And somehow, it has gained popularity, although there is no reason to use it in modern C++. No one of the big C++ experts (Sutter, Meyers, Alexandrescu, ...) makes use of type prefixes. Neither do the standard library, nor Boost, nor SFML (which I consider one of the most properly designed C++ libraries).
    Zloxx II: action platformer
    Thor Library: particle systems, animations, dot products, ...
    SFML Game Development:

    easy

    • Full Member
    • ***
    • Posts: 146
      • MSN Messenger - easy82.contact@gmail.com
      • View Profile
      • Email
    How to code nicely with SFML?
    « Reply #6 on: August 25, 2011, 11:30:05 am »
    Hi Nexus!

    I understand your feelings, and I believe you make all your suggestions with a good intention, and also what you're suggesting is good and it does work. For example, yesterday I've started to redesign the game internals and not only I get rid of a lot of dependencies and inconsistency, but everything seems to be more clear and well organised. Thank you for all this! :)

    On the other hand, about prefixes, I think it's more about personal preference. I like to identify my stucts as structs, and I never use them as any other object but stucts. That is, they're all public. That's what they intended to be. Most of the time I regard them as containers, they don't even have any funcions inside, but their constructor to set them up. What you're talking about is much higher level of abstraction (like in Thor), which I'm trying to avoid all the time. I like to keep things simple and crystal clear.

    But I'm also trying to learn from others, like as from you and from your work. There are practices however, which are just not for me. It's like when I was learning how to play the guitar, I absolutely hated the idea of , even if they're cool and everybody goes crazy about it. It's jut ... it looks so stupid. :D

    Cheers,
    easy

    Nexus

    • SFML Team
    • Hero Member
    • *****
    • Posts: 6287
    • Thor Developer
      • View Profile
      • Bromeon
    How to code nicely with SFML?
    « Reply #7 on: August 25, 2011, 11:39:30 am »
    Quote from: "easy"
    I like to identify my stucts as structs, and I never use them as any other object but stucts. That is, they're all public. That's what they intended to be. Most of the time I regard them as containers, they don't even have any funcions inside, but their constructor to set them up.
    I actually do it like this. Mostly, structs are functors or small collections of data. In principle, they could be used like classes, but many people separate struct semantically from class.

    Quote from: "easy"
    On the other hand, about prefixes, I think it's more about personal preference. [...] What you're talking about is much higher level of abstraction (like in Thor), which I'm trying to avoid all the time. I like to keep things simple and crystal clear.
    No problem, if you understand your code better with prefixes. I just wanted to show you that there is no absolute necessity, and when code becomes more complex and abstract, there arise a lot of drawbacks :)
    Zloxx II: action platformer
    Thor Library: particle systems, animations, dot products, ...
    SFML Game Development:

    easy

    • Full Member
    • ***
    • Posts: 146
      • MSN Messenger - easy82.contact@gmail.com
      • View Profile
      • Email
    How to code nicely with SFML?
    « Reply #8 on: August 25, 2011, 12:38:14 pm »
    Again, I thank you for your suggestions, I really appreciate them.

    What bothers me is the tone you're using sometimes, even if the intenion was good:

    Quote
    Generally, you will always be confronted with different code styles when using different libraries, you should get used to it.


    Quote
    No problem, if you understand your code better with prefixes.


    I've been programming for a long time now (either in a good or bad way), this is not my first attempt, I'm not a n00b (but to SFML), and I often ask for for learning purposes, and I don't feel ashamed about it.

    Quote
    SFML (which I consider one of the most properly designed C++ libraries).


    C++ is nice (apart from many other good selling points) because it does not limit your programming style.

    My original question was to get ideas about coding in a style that fits SFML. You've answered not only this, but gave other me practices to follow. I also think SFML is structured nicely (without having a peek into its sources). About my practices, they have been influenced lately by the Irrlicht Engine, which I recommend you to study as for its design.

    Cheers,
    easy

    Nexus

    • SFML Team
    • Hero Member
    • *****
    • Posts: 6287
    • Thor Developer
      • View Profile
      • Bromeon
    How to code nicely with SFML?
    « Reply #9 on: August 25, 2011, 01:02:50 pm »
    Sorry, I didn't mean to be rude or anything at all. I'm not native english, so it may happen sometimes that my statements sound different than intended. :?

    I understand that "you should get used to it" may be better formulated, but I really don't see what's wrong with "No problem, if you understand your code better with prefixes". I actually meant it like this, it was not a sarcastic statement. I accept it if you prefer this code style, that's all I wanted to say :)

    I have already worked a little bit with the Irrlicht engine, and I am planning to use it for a bigger project in the future. But I don't like some design choices, for example the manual reference counting with grab() and drop() or the operator overloading in the vector classes. In general however, I have a good impression of Irrlicht (especially in contrast to the beast Ogre :D).
    Zloxx II: action platformer
    Thor Library: particle systems, animations, dot products, ...
    SFML Game Development:

    easy

    • Full Member
    • ***
    • Posts: 146
      • MSN Messenger - easy82.contact@gmail.com
      • View Profile
      • Email
    How to code nicely with SFML?
    « Reply #10 on: August 25, 2011, 03:58:32 pm »
    Okay, everything is fine! Peace :D

    Silvah

    • Guest
    How to code nicely with SFML?
    « Reply #11 on: August 25, 2011, 04:42:36 pm »
    I just couldn't resist... :D

    Quote from: "Nexus"
    But more important, why do you need to know whether a type is a class or not? It often doesn't matter. In cases where it does matter, you need to know more about the type anyway in order to use it (e.g. which methods it provides).
    In cases where it does matter, good IDEs will highlight the class name with a different color anyway :P

    Quote from: "Nexus"
    Sorry, I didn't mean to be rude or anything at all. I'm not native english, so it may happen sometimes that my statements sound different than intended. :?
    No offence, but IMO you really should work on that, sometimes when I'm reading your posts I have the feeling that you think you're the only one who knows all the idiocies of C++. Then again, neither I am native English speaker, and I know this one sounds a little bit different than I wanted it to ;)

    Quote from: "Nexus"
    But I don't like some design choices, for example the manual reference counting with grab() and drop()
    intrusive_ptr comes to the rescue! :D

    MorleyDev

    • Full Member
    • ***
    • Posts: 219
    • "It is not enough for code to work."
      • View Profile
      • http://www.morleydev.co.uk/
    How to code nicely with SFML?
    « Reply #12 on: August 25, 2011, 05:15:53 pm »
    I find the best use for prefixing is to narrow autocomplete down a bit further. For example, I know if I'm working with my own code and type _, autocomplete will show all private variables in that class.

    It may not make much semantic difference, but I find it makes autocomplete actually run much faster by reducing the amount of work it has to do per character typed, and also reduces how much time I'm looking through autocomplete because I'm having a mental blank on the name of a variable, which makes a practical difference.
    UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

    All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

    easy

    • Full Member
    • ***
    • Posts: 146
      • MSN Messenger - easy82.contact@gmail.com
      • View Profile
      • Email
    How to code nicely with SFML?
    « Reply #13 on: August 25, 2011, 05:37:22 pm »
    True, thanks for the addition.

    Nexus

    • SFML Team
    • Hero Member
    • *****
    • Posts: 6287
    • Thor Developer
      • View Profile
      • Bromeon
    How to code nicely with SFML?
    « Reply #14 on: August 25, 2011, 06:18:54 pm »
    Silvah, thanks for the hint. I wasn't aware that my posts leave this impression, and this is certainly not my intention. Now that you say it, I think that this mostly happens in C++ discussions where others spread myths and I try to fight them ;)

    I actually want to help, nevertheless I see that the intention in such posts is sometimes unclear. I'm trying to improve that. If you see posts where I react like this, don't hesitate to inform me via PM :)
    Zloxx II: action platformer
    Thor Library: particle systems, animations, dot products, ...
    SFML Game Development:

     

    anything