SFML - C++ displaying a sprite help

I've been learning sfml lately and im trying to create just really simple games and applications to help learn. I saw on the sprite tutorial that puting the image and sprite into a class is much better programming and habit s. Here is the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef TANK_H
#define TANK_H
#include <SFML/Graphics.hpp>

class Tank
{
    public:
        Tank(const Tank& Copy);
        bool LoadFile(const std::string ImageFile);
    protected:
    private:
        static sf::Image Image;
        sf::Sprite Tank1;
};

#endif // TANK_H


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "Tank.h"
#include <iostream>
#include <SFML/Graphics.hpp>
Tank::Tank(const Tank& Copy):
Image(Copy.Image),
Tank1(Copy.Tank1)
{
    Tank1.SetImage(Image);
}

bool Tank::LoadFile(const std::string ImageFile)
{
    if(!Image.LoadFromFile(ImageFile))
    {
        return 1;
    }
    return 0;
}



But how would i go about loading an image and sprite into the class? I want to make a Tank object that holds the image i could display in the main loop, here is my guess:
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include "Tank.h"
#include <SFML/Graphics.hpp>


int main()
{
   sf::RenderWindow Window(sf::VideoMode(800,600,32), "TANKWARS");
   Tank Playerone(/* ??? */); //im still confused on how to declare this!
   if(!Playerone.LoadFile("Tank.tga"))
   {
       return EXIT_FAILURE;
   }
}
What do you mean? Do you want a class that handles sprites and images for you? I think a popular way of doing this is to have a further encapsulation of the std::map container, which allows you to associate images/sprites (The value) with a std::string (The key). This way you could write functions to load a file and give the image a name and add it to the map, or to retrieve an image with a certain name, or to convert an image to a sprite etc. That way you can have one image manager for your whole app.

Also, if your LoadFile function returns 0 on success, you should be testing for anything else if you want to return EXIT_FAILURE. So take out the "not" operator (!) in the if condition.
The people at the SFML forum understand, take a look to see what im asking:
http://en.sfml-dev.org/forums/index.php?topic=7579.new#new
closed account (10oTURfi)
First you need a default constructor.Tank() {} You can't create object of a class with only copy constructor. Also instead of sf::Image (which is used for pixel manipulation) use sf::Texture. To draw a sprite you will need a sf::Sprite object which will contain reference to the texture loaded from file.

sf::Sprite mySprite(myTexture);

Unlike textures, sprites can be drawn on window. You must also set position of sprite with mySprite.setPosition((float)x, (float)y); . x and y are pixel coordinates, where 0,0 is upper left corner and (on your Window) 800, 600 bottom right corner.

Also, you must not forget to clear the window from artifacts before drawing and displaying:

1
2
3
Window.clear();
Window.draw(mySprite);
Window.display();


Ofcourse, to prevent program from instantly closing, you will need a loop which will keep redrawing window content untill, say, key is pressed:

So that should look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    sf::Texture myTexture;
    myTexture.loadFromFile("myFile.png");
    sf::Sprite mySprite(myTexture);
    mySprite.setPosition(400, 300);

    sf::Event Event;
    while(Window.isOpen()) 
    {
        while(Window.pollEvent(Event))
        {
            if(Event.type == sf::Event::KeyPressed)
            {
                 Window.close();
            }
        }
        Window.clear();
        Window.draw(mySprite);
        Window.display();
    }
Thanks for the help, so do you mean i should function overload and create another constructor with no parameters? I just did that but im getting an undefined reference to Tank::Image for some strange reason... Thanks for the help!

ERROR:
1
2
3
4
5
6
obj\Debug\Tank.o||In function `Tank':|
J:\SFML\SFML_SmallGame\Tank.cpp|11|undefined reference to `Tank::Image'|
J:\SFML\SFML_SmallGame\Tank.cpp|11|undefined reference to `Tank::Image'|
obj\Debug\Tank.o:J:\SFML\SFML_SmallGame\Tank.cpp|18|undefined reference to `Tank::Image'|
||=== Build finished: 3 errors, 0 warnings ===|

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//Tank.cpp
#include <SFML/Graphics.hpp>
#include "Tank.h"
#include <iostream>

Tank::Tank(){

}
Tank::Tank(const Tank& Copy):
    Sprite(Copy.Sprite)
    {
        Sprite.SetImage(Image);
    }



bool Tank::LoadFile(const std::string ImageFile)
{
    if(!Image.LoadFromFile(ImageFile))
    {
        return 1;
    }
    return 0;
}


Tank.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef TANK_H
#define TANK_H
#include <SFML/Graphics.hpp>

class Tank
{
    public:
        Tank();
        Tank(const Tank& Copy);
        bool LoadFile(const std::string ImageFile);
    protected:
    private:
        static sf::Image Image;
        sf::Sprite Sprite;
};

#endif // TANK_H


main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include "Tank.h"
#include <SFML/Graphics.hpp>
class Tank;

int main()
{
   sf::RenderWindow Window(sf::VideoMode(800,600,32), "TANKWARS");
   Tank Copy;
   Tank Playerone(Copy);
   if(!Playerone.LoadFile("Tank.tga"))
   {
       return EXIT_FAILURE;
   }
}
Last edited on
static sf::Image Image;

Image is static.

In tank.cpp you need a line at file scope that looks like:

sf::Image Tank::Image ;

LoadFile should probably also be static, since it doesn't depend on an instance, if that's the route you want to go.
i appreciate the help guys. i understand what you're saying cire, but i put the line of code just under iostream declaration in tank.cpp and it says the exact same thing.
Perhaps you need to force a rebuild. Works fine for me.
Works now! Thank you so much for the help, love the people here.
Topic archived. No new replies allowed.