0
votes

I'm afraid I've come to C++ from my limited Python experience. In Python I often use Tkinter to handle my GUI, and I can pass my 'canvas' or 'window' to other classes which store it and then can draw to the canvas / window having only passed it across once.

I'm looking to do the same with SFML and C++ but, so far, have only found solutions where my sf::RenderWindow must be passed to a method every time that method is called.

For example, I have a 'player' class that I'd like to hold the sprite of the player and move the sprite every time Player.move('up') is called, at the moment the solutions I've found say I have to use the following code (it may be slightly incorrect, I've just typed this out whilst on the train, but hopefully you get the picture):

Main.cpp

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include "Player.h"
int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "My Game");

    Player player(); //Nothing passed
    player.move(window, "up"); //Pass window every time
    player.move(window, "down");
    player.move(window, "left");
    return 0;
}

Player.cpp

Player::move(sf::RenderWindow& window, char direction){
    /*Code to move the sprite shall be on this line*/        
    window.draw(sprite);
}

I understand that passing the render-window window to a method isn't a huge hardship, but I feel like there must be a way to do it more like this:

Main.cpp

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include "Player.h"
int main(){
    sf::RenderWindow window(sf::VideoMode(800, 600), "My Game");

    Player player(window); //Pass window once.
    player.move("up"); // Relax knowing that everything is already handled.
    player.move("down");
    player.move("left");
    return 0;
}

Player.cpp

Player::Player(sf::RenderWindow& win_gui){
    window = win_gui;
}

Player::move(char direction){
    /*various case statements to move the sprite on this line*/        
    window.draw(sprite);
}

I'm either missing something huge or misunderstand completely. My guess is both. If it's possible in another language, why not C++?

1
Why should move even call draw? Isolate rendering from game logic. - LogicStuff
'down' that should be double quotes. Is this code compiling? - Guillaume Racicot
Guillame, I have corrected the single quotes. I'm currently on a very long train journey and typed this out from memory, so there's probably more mistakes. LogicStuff, why shouldn't move call draw? I've been taught to make methods handle as much of a process as anyone might expect. If I give someone this class to work with their SFML game and they type "player.move("up");" they'll be quite confused when player doesn't move up. If I can't do that kind of thing with methods then the only things we'd have in the world are getters and setters, how boring! - Matthew

1 Answers

1
votes

You can inherit from sf::Drawable which contains a pure virtual draw() method.

class Player : public sf::Drawable
{
     protected:
          void draw(sf::RenderTarget& target, sf::RenderStates state) const
          {
               target.draw(sprite);
          }
};

while Player class becoming a sf::Drawable, you will be able to do this:

Player player;
window.draw(player);

thats also how entities are drawn in sfml like shapes, sprites, vertices etc.