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

Author Topic: sf::Drawables won't show.  (Read 1343 times)

0 Members and 1 Guest are viewing this topic.

Dude

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
sf::Drawables won't show.
« on: June 12, 2014, 03:00:49 am »
Hey there, everyone on SFML forum. First of all, I would like to thank everyone who answers questions in this forum. I've gotten some great help from you guys (by lurking).

Let's get to the point. I'm basically trying to create a good code "structure" for managing multiple states (like intro, menu, options, playing, etc). I've been following this guide, which has been helpful. The author of the article has written his program with SDL though, and I get problems trying to "remake" it for SFML.

My problem is simple, and hopefully easily solvable:
My sf::Drawables won't render, even though the game loop is rolling as it should (I believe). Maybe you could take a look at the code and see what's wrong. If something's unclear I'll try to explain (I'm kind of a noob though).

Note: I have included all SFML libraries where needed, and also put #ifndef, #define and #endif where appropriate, and will therefore omit them from the code. I have also removed all code that is irrelevant to the question, which is why the program seems incomplete :)

/** main.cpp **/
#include "GameEngine.hpp"
#include "IntroState.hpp"

int main() {
        // Create GameEngine instance, which also creates a window, like this:
        // sf::RenderWindow mWindow(sf::VideoMode(800, 600), "Window Title");
        // Also sets Running() to "true".
        GameEngine game;
       
        // Change GameState to IntroState and call its Init()-method
        game.ChangeState( IntroState::Instance() );

        // Game loop
        while ( game.Running() )
        {
                game.HandleEvents();
                game.Draw();
        }
        return 0;
}
 

/** GameEngine.hpp **/

class GameState;

class GameEngine
{
        public:
                void                                    ChangeState(GameState* state);
               
                void                                    HandleEvents();
                void                                    Draw();
               
                bool                                    Running() { return m_running; }
               
                sf::RenderWindow                mWindow;
        private:
                std::vector<GameState*> states;
               
                bool                                    m_running;
};
 

/** GameEngine.cpp **/
#include "GameEngine.hpp"
#include "GameState.hpp"

// An sf::RenderWindow is created in Init()-function here. Omitted for simplicity.
// sf::RenderWindow mWindow(sf::VideoMode(800, 600), "Window Title");

void GameEngine::ChangeState(GameState* state)
{
        // Clean up the old states
        if ( !states.empty() )
        {
                states.back()->Cleanup();
                states.pop_back();
        }

        // Store and initialize the new state
        states.push_back(state);
        states.back()->Init();
}

void GameEngine::HandleEvents()
{
        // Let the state handle events
        states.back()->HandleEvents(this);
}

void GameEngine::Draw()
{
        // Let the state draw the screen
        states.back()->Draw(this);
}
 

/** GameState.hpp **/
#include "GameEngine.hpp"

class GameState
{
        public:
                virtual void            Init()                                                  = 0;
                virtual void        HandleEvents(GameEngine* game)  = 0;
                virtual void        Draw(GameEngine* game)          = 0;

        protected:
                GameState() { };
};
 

/** IntroState.hpp **/
#include "GameState.hpp"

class IntroState : public GameState
{
        public:
                void                            Init();
                void                HandleEvents(GameEngine* game);
                void                Draw(GameEngine* game);

                static IntroState*  Instance() { return &m_IntroState; }

        protected:
                IntroState() { };

        private:
        sf::CircleShape         circle;
};
 

This is basically where I implement the part of the Game Loop that happens while IntroState (the intro screen) is active:
/** IntroState.cpp **/
#include "IntroState.hpp"

void IntroState::Init()
{
        // Create a shape to draw
        sf::CircleShape circle;
        circle.setRadius(50);
        circle.setPosition(100, 100);
        circle.setFillColor(sf::Color::Red);
}

void IntroState::HandleEvents(GameEngine* game)
{
        sf::Event event;
        while ( game->mWindow.pollEvent(event) )
                switch (event.type)
                {
                        // ... handle user input and such. No graphics in here.
                }
}

void IntroState::Draw(GameEngine* game)
{
        game->mWindow.clear(sf::Color::Black);
        game->mWindow.draw(circle);
        game->mWindow.display();
       
        //      Which is the same as
        //      (*game).mWindow.foo();
}
 

So basically I (try to) access mWindow through *game, which is public and declared inside GameEngine.hpp.

I get the sf::RenderWindow to display properly, I get it to clear with whichever color I choose (in this case sf::Color::Black), but I can't see the circle. I've tried with different shapes and texts, but I can't get any sf::Drawable to show at all.

I know it's a lot of code, sorry about that. Thank you in advance.

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: sf::Drawables won't show.
« Reply #1 on: June 12, 2014, 03:05:49 am »
You should really use a constructor and the initialization lists to construct your class instead of some Init() function... then maybe your error would show up faster.  ;)

    sf::CircleShape circle; // this isn't doing what you think it is doing
    circle.setRadius(50);
    circle.setPosition(100, 100);
    circle.setFillColor(sf::Color::Red);


(and to anyone else thinking about replying - please don't just reply and say exactly what the issue is... let the OP try to figure it out)
« Last Edit: June 12, 2014, 03:10:57 am by zsbzsb »
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

Dude

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
Re: sf::Drawables won't show.
« Reply #2 on: June 12, 2014, 03:33:25 am »
Do you mean both the Init-functions or only the one in GameState/IntroState?

And regarding the constructors, how would I declare them properly? The author of the guide I linked to said something about declaring them as:

protected:
    TheConstructor() { };

In order to "implement them as Singletons". If you could show an example of how I could do what you said, I would be very grateful. But maybe that's cheating ;)

EDIT: I'm guessing it could be something about circle being out of scope... or something. Lead me on the right path.
« Last Edit: June 12, 2014, 03:42:32 am by Dude »

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: sf::Drawables won't show.
« Reply #3 on: June 12, 2014, 03:48:06 am »
Quote
Do you mean both the Init-functions or only the one in GameState/IntroState?

All Init() functions should be moved to a constructor because as it currently stands you have 0 benefit from that current setup. It makes all your states require an extra function to be properly setup when you can easily go without. After all - this isn't C where constructors don't exist.  8)

Quote
And regarding the constructors, how would I declare them properly?

Try googling or get a good C++ book. Constructors are absolutely essential to good and modern programming practices. As for declaring them protected... it really depends on your code base and what you are trying to achieve.

Quote
In order to "implement them as Singletons". If you could show an example of how I could do what you said, I would be very grateful!

Code posted above has nothing to do with singletons / globals. Actually you should do your best to avoid all singletons / globals as they generally promote bad coding habits. (not to mention globals can cause crashes)

Quote
Or help me find out by myself

Try running the following code (and go learn about variable scope  ;))...

#include <iostream>
int main()
{
    int i = 666;
    std::cout << i << std::endl;
    {
        int i = 1995;
        std::cout << i << std::endl;
    }
    std::cout << i << std::endl;
    {
        i = 911;
        std::cout << i << std::endl;
    }
    std::cout << i << std::endl;
}
« Last Edit: June 12, 2014, 03:51:12 am by zsbzsb »
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

Dude

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
Re: sf::Drawables won't show.
« Reply #4 on: June 12, 2014, 03:57:07 am »
I will try rewriting the code tomorrow. It's 4 AM here :)

Thank you very much for your answer, sir. I'll be back.
« Last Edit: June 12, 2014, 08:59:48 pm by Dude »