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

Author Topic: Draw from multiple classes  (Read 4512 times)

0 Members and 1 Guest are viewing this topic.

Fanjad

  • Newbie
  • *
  • Posts: 2
    • View Profile
Draw from multiple classes
« on: September 17, 2012, 02:39:08 am »
Hey guys,

I'm new to SFML and currently trying to draw to one window from multiple classes:
My plan is to create a little "Pong clone" with different classes; one for the window, one for the players and one for the ball (maybe one for collisions, don't mind yet). But I don't know how to draw from the "Player"-class or the "Ball"-Class to the window created by the "Window"-Class. A - very - little example would be extremly helpful :)

Thanks!

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11016
    • View Profile
    • development blog
    • Email
Re: Draw from multiple classes
« Reply #1 on: September 17, 2012, 02:57:23 am »
There are multiple ways to achieve such a thing and it largely depends on the structure you chose for your 'engine'. ;)

One way would be to assume that every class than can get displayed are derived from sf::Drawable. Thus the class that is responsible to 'manage' those drawables could simply hold a std::vector of std::unique_ptr to all your drawables.

Here's some quickly cooked code which defines just two drawable classes and one application class. Everything should of course get extended and properly declared & defined in header and source files, etc...
Be warned the code uses some C++11 features which aren't supported by all compilers, specially not MSVC.
#include <SFML/Graphics.hpp> // sf::Drawable, sf::RenderTarget, sf::RenderStates, sf::Sprite, sf::CircleShape, sf::RenderWindow, sf::Event

#include <vector> // std::vector
#include <memory> // std::unique_ptr

class Player : public sf::Drawable
{
private:
        void draw(sf::RenderTarget& target, sf::RenderStates states) const
        {
                target.draw(m_sprite, states);
        }
       
private:
        sf::Sprite m_sprite;
};

class Ball : public sf::Drawable
{
private:
        void draw(sf::RenderTarget& target, RenderStates states) const
        {
                target.draw(m_circle, states);
        }

private:
        sf::CircleShape m_circle;
};

class App
{
public:
        App()
        {
                m_drawables.push_back(std::make_unique(Ball));
                m_drawables.push_back(std::make_unique(Player));
        }

        void run()
        {
                sf::Event event;
                while(m_window.pollEvent(event))
                {
                        if(event.type == sf::Event::Closed)
                                m_window.close;
                }
               
                m_window.clear();
               
                for(auto it = m_drawables.begin(); it != m_drawables.end(); it++)
                        m_window.draw(*(*it));
               
                m_window.draw();
        }
       
private:
        sf::RenderWindow m_window;
        std::vector<std::unique_ptr<sf::Drawable>> m_drawables;
};

int main()
{
        App app;
        app.run();
}

Obviously it's all untested, but it should demonstrate one possible principle.
There are many other ways and all have their ups and downs... ;)
« Last Edit: September 17, 2012, 02:59:35 am by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Fanjad

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Draw from multiple classes
« Reply #2 on: September 17, 2012, 04:20:39 am »
Thanks a lot :) I will test it as soon as possible :)

/E: Tested your code, but my compiler (MSVC 2010) is not very happy :(
m_drawables.push_back(std::make_unique(Ball));
m_drawables.push_back(std::make_unique(Player));

The compiler doesn't allow type names here. (He even doesn't know make_unique)
« Last Edit: September 17, 2012, 05:01:26 am by Fanjad »

masskiller

  • Sr. Member
  • ****
  • Posts: 284
  • Pointers to Functions rock!
    • MSN Messenger - kyogre_jb@hotmail.com
    • View Profile
    • Email
Re: Draw from multiple classes
« Reply #3 on: September 17, 2012, 05:36:01 am »
The only thing that comes to mind is that that code is C++ 11 and your compiler doesn't support it, get the latest version of GCC and it should work if it is what I just said.
Programmer, Artist, Composer and Storyline/Script Writer of "Origin of Magic". If all goes well this could turn into a commercial project!

Finally back into the programming world!

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Draw from multiple classes
« Reply #4 on: September 17, 2012, 09:46:02 am »
The only thing that comes to mind is that that code is C++ 11 and your compiler doesn't support it, get the latest version of GCC and it should work if it is what I just said.
No. std::make_unique() just doesn't exist. Yesterday I wrote my own version of it...

Apart from that, VS 2010 supports some C++11 features like std::unique_ptr and move semantics.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: Draw from multiple classes
« Reply #5 on: September 17, 2012, 11:13:40 am »
The implementation of draw is not correct. If you try player.move(100, 100); and you'll be disappointed because the player won't move at all.

You have to update the states. Here is an example that also use a sprite as renderer.
SFML / OS X developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11016
    • View Profile
    • development blog
    • Email
Re: Draw from multiple classes
« Reply #6 on: September 17, 2012, 11:45:41 am »
The implementation of draw is not correct. If you try player.move(100, 100); and you'll be disappointed because the player won't move at all.
The implementation is correct. ;)
I just didn't inherit from sf::Transformable thus not implementing move()/setPosition() etc, thus a call to getTransform() wouldn't even work within the current class.
Of course it can be a good idea to inherit from sf::Transformable, but then the questions is if one really wants to use a sf::Sprite internally since it would then be code repetition (a sprite is already a Drawable and Transformable)...
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: Draw from multiple classes
« Reply #7 on: September 17, 2012, 12:18:51 pm »
Indeed, I read your code too fast.

Quote
since it would then be code repetition
I wouldn't say it's repetition, but more reusing what already exists. The difference is kind of subtle so it could lead to an interesting debate, unfortunately I don't have time right now to open a new thread about this.

The thing is I've implement SFML on mac for some time now but I never had the opportunities of creating an application that really uses SFML (school is time consuming, you know) and now that I've this opportunity all those design question become really interesting and motivating. But I'm completely out of topic now.  ::)
SFML / OS X developer

 

anything