Problems with class files with SFML

Im making a small game is SFML called skelton town. (not skeleton (its a inside refrence)) I have made a file called Player which i want to allow me to make the player, draw him and allow me to input the keyboard inputs for his movement. but when i include the header to allow me use the file in main nothing is drawn. But i get not actual errors so could you guys help.

Player.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "Player.h"
#include<iostream>
#include<SFML/Graphics.hpp>
Player::Player()
{
       sf::RenderWindow Window;

 sf::Texture pTexture;
    sf::Sprite playerImage;
    if(!pTexture.loadFromFile("Player.png", sf::IntRect(30,0,64,32)))
        std::cout<<"Error could not load player image"<<std::endl;
     playerImage.setTexture(pTexture);


    while(Window.isOpen())
    {
        sf::Event Event;
        while(Window.pollEvent(Event))
        {
            if (Event.type == sf::Event::Closed)
                Window.close();
        }
      Window.draw(playerImage);
        Window.display();

    }
}


Player.h
1
2
3
4
5
6
7
8
9
10
11
#ifndef PLAYER_H
#define PLAYER_H

class Player
{
    public:
        Player();

};

#endif // PLAYER_H 


main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<SFML/Graphics.hpp>
#include<iostream>
#include<SFML/Window/Keyboard.hpp>
#include "Player.h"
#include <cstdlib>
int main()
{

    sf::RenderWindow Window;
    Window.create(sf::VideoMode(1920, 1080), "Skelton Town", sf::Style::Fullscreen);

Player player;


    while(Window.isOpen())
    {
        sf::Event Event;
        while(Window.pollEvent(Event))
        {
            switch(Event.type)
            {
        case sf::Event::Closed:

                 Window.close();
                 break;
            }

        }

    
    }
        Window.display();

    }
}


Can someone help me. and explain why it is not working and correct me. Thank you!
1
2
3
Player::Player()
{
       sf::RenderWindow Window;
that `Window' variable is in no way related to the `Window' variable in main()
As ne555 pointed out the sf::RenderWindow member is not related to the one in your main.cpp file.

It also doesn't seem like you completely grasp the concept of the main game loop yet which is a very important thing in game development. I will just go through your code and point out things that I notice (I don't mean any of this as being mean more as constructive comments).

1. - sf::RenderWindow Window;

The first thing that sticks out is you are for some reason declaring a sf::RenderWindow variable inside of your Player class' constructor. That variable is completely local to the constructor and shouldn't be there. The sf::RenderWindow should be created in main.cpp only (Like you have) or in a class that manages the window/application as a whole.

So you are going to need to get rid of this.

2 -
1
2
sf::Texture pTexture;
sf::Sprite playerImage;


Next you are creating the sf::Texture and sf::Sprite variables like you should be for a entity of your game but what you are doing wrong is you are creating as a variable inside of your class' constructor again, so they will be completely local to the constructor and once the constructor ends (After line 12 in your main.cpp file) them variables will dissappear forever and you will have no way to access the texture or sprite objects.

These instead should be declared in the Player.hpp file and initialized either in your constructor or in a initialize method.

1
2
3
4
5
6
7
8
9
10
class Player
{
    public:
        Player();

    private:
        sf::Texture pTexture;
        sf::Sprite playerSprite;

};



3. -
1
2
3
4
5
6
7
8
9
10
11
12
while(Window.isOpen())
    {
        sf::Event Event;
        while(Window.pollEvent(Event))
        {
            if (Event.type == sf::Event::Closed)
                Window.close();
        }
      Window.draw(playerImage);
        Window.display();

    }


This all needs to be deleted. This is your main game loop (Or part of it I should say) and should only be in your main.cpp (Which you already have it in there). Also it have the same problem as the 2 items above, it is in the constructor and you are causing a finite loop inside of a constructor that won't end until the close button (Or alternatives) are hit. You are never even getting to create the player object until you hit the close button (You are never getting past line 12 on your main.cpp file).

Now what I assume you wanted to do with this loop is get it so that your player sprite is drawn, but this is not the way to do so.

To get your sprite object drawn that is in the player class from the main game loop inside of your main.cpp file you can do it one of two ways (There are more but these are the easiest).

A.) Provide a get function that returns a reference to the sf::Sprite object in your player class.

1
2
3
4
5
6
7
8
9
10
11
12
class Player
{
    public:
        Player();
    
        sf::Sprite& getSprite() { return playerImage; }

    private:
        sf::Texture pTexture;
        sf::Sprite playerImage;

};


Then in your main game loop inside of your main.cpp file you will use that get function in a draw call to draw it on the screen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
int main()
{

    sf::RenderWindow Window;
    Window.create(sf::VideoMode(1920, 1080), "Skelton Town", sf::Style::Fullscreen);

Player player;


    while(Window.isOpen())
    {
        sf::Event Event;
        while(Window.pollEvent(Event))
        {
            switch(Event.type)
            {
        case sf::Event::Closed:

                 Window.close();
                 break;
            }

        }
    
        Window.clear();
        Window.draw(player.getSprite());  // Key line here
        Window.display();

    }
}


B) The other way to do this would be to have your player class inheirit from sf::Drawable and then override the virtual draw() function to do the drawing in the player class. This is the best way to do this but takes more knowledge on inheiritence, though it will allows you to make a draw call like this Window.draw(player); in your main game loop.



Those are the main things you need to work on to get this working. I would also recommend you dig into how classes work a bit more before starting on this because you don't seem to understand what constructors are doing and why they are used. It would also be helpful to read up on what the main game loop is and what it does also, along with the basics of window management in sfml.

A very good book if you are interested in learning sfml is http://www.amazon.com/SFML-Game-Development-Jan-Haller/dp/1849696845 . I would highly recommend it though you need to know basic/advance C++ concepts to get all it's worth from the book.

Otherwise go through the basic tutorials found on the sfml website and learn the basics through their documentation also. Learn what the methods and classes do. The SFML wiki page also has quite a few tutorial/source code on it also

https://github.com/LaurentGomila/SFML/wiki/Tutorials
https://github.com/LaurentGomila/SFML/wiki/Sources

Anyways wish you the best of luck with your project :)
Last edited on
Topic archived. No new replies allowed.