SFML - C++ displaying a sprite help

Apr 13, 2012 at 4:39am
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;
   }
}
Apr 13, 2012 at 5:42am
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.
Apr 13, 2012 at 7:01pm
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
Apr 13, 2012 at 7:21pm
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();
    }
Apr 13, 2012 at 7:29pm
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 Apr 13, 2012 at 7:30pm
Apr 14, 2012 at 12:29am
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.
Apr 14, 2012 at 2:50am
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.
Apr 14, 2012 at 3:48am
Perhaps you need to force a rebuild. Works fine for me.
Apr 14, 2012 at 5:36am
Works now! Thank you so much for the help, love the people here.
Topic archived. No new replies allowed.