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

Author Topic: Obtaining a sf::Sprite value thanks to a pointer  (Read 7263 times)

0 Members and 3 Guests are viewing this topic.

Kromah

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Obtaining a sf::Sprite value thanks to a pointer
« on: April 04, 2012, 09:37:28 pm »
Hi everyone.
For some reason that would be long to explain, I've got an array filled with pointers, all pointing on a Sprite address. Now I have to Draw() theses Sprites thank to a loop. Everything seems alright, but when I run the code, here is the horrible message delivered by the programme :



Here is the part of the code dealing with it :

std::vector<sf::Sprite*> drawTable; //The array containing pointers
 

//The function that allows to add Sprites addresses in the array
void Drawing::addSprite(Sprite *sprite)
{
    drawTable.push_back(sprite);
}

//The function that allows to display all the sprites
void Drawing::drawFrame()
{
    for(i=0; i<drawTable.size(); i++)
    {
        m_app->Draw(*drawTable[i]); //Here is the line causing the crash !
    }
    i = 0;
}

The doc informs me that the Draw() function prototype is that one :
virtual void sf::RenderTarget::Draw(const Drawable & Object) [virtual]

I confess I'm a bit lost. I don't feel at ease with this concept of virtual function or else... Some one may give me some help?
Thanks for reading me, and have a good day !

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: Obtaining a sf::Sprite value thanks to a pointer
« Reply #1 on: April 04, 2012, 09:51:04 pm »
So what exactly is your m_app variable?
It should be an initialized and instanced sf::RenderWindow (or sf::RenderTexture), is that so?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Obtaining a sf::Sprite value thanks to a pointer
« Reply #2 on: April 04, 2012, 10:01:52 pm »
Can you show where addSprite is called?
Laurent Gomila - SFML developer

Kromah

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: Obtaining a sf::Sprite value thanks to a pointer
« Reply #3 on: April 04, 2012, 10:17:22 pm »
eXpl0it3r : that's it, m_app is actually a pointer on the sf::RenderWindow. In fact, I created a "Drawing" class that draws all the elements of the scene. To that extent, I had to create a pointer on app to be able to Draw the Sprites easily.
Here is the implementation code :

class Drawing
{
    public:
        Drawing(sf::RenderWindow *app);
        void addSprite(sf::Sprite *sprite); //Ajouter un sprite en liste
        void drawFrame(); //Placer tous les sprites contenus

    private:
        std::vector<sf::Sprite*> drawTable;
        int i;
        sf::RenderWindow *m_app;
        int ordreY;
};

Laurent : Sure, I use it in main(), each time I have to add a sprite in the scene :

int main()
{
    RenderWindow app(VideoMode(800, 600, 32), "RPG Test");

    Drawing drawing1(&app); //Moteur graphique
    Personnage joueurP;
    drawing1.addSprite(& joueurP.GetSprite());
...
}

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Obtaining a sf::Sprite value thanks to a pointer
« Reply #4 on: April 04, 2012, 10:29:44 pm »
I guess joueurP.GetSprite() returns by value, so you're adding pointers to temporary sprites in your array, and when you draw them they don't exist anymore.
Laurent Gomila - SFML developer

Kromah

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: Obtaining a sf::Sprite value thanks to a pointer
« Reply #5 on: April 04, 2012, 10:41:50 pm »
Oh, yeah, I see what you mean. I confess I'm powerless now, how could I manage to keep a "permanent" value returned by GetSprite() ? I do think you're right, it would entirely explain my error message.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: Obtaining a sf::Sprite value thanks to a pointer
« Reply #6 on: April 04, 2012, 10:53:52 pm »
Don't return by value, return by reference or pointer instead.

Also if you don't do modify the returned sprite in the Drawing class, you could also save the sprites as constante references instead of pointers, because we all know, pointers can be evil. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Obtaining a sf::Sprite value thanks to a pointer
« Reply #7 on: April 05, 2012, 08:39:25 am »
Or redesign your engine, to use a better approach ;)

This is wrong:
drawing1.addSprite(& joueurP.GetSprite());

This would be much better:
joueurP.draw(drawing1);

... or, if you need to "register" the player to be drawn automatically later,
drawing1.addEntity(joueurP);

// Personnage would have to inherit from an "Entity" class,
// with a draw function (at least)
Laurent Gomila - SFML developer

Kromah

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: Obtaining a sf::Sprite value thanks to a pointer
« Reply #8 on: April 05, 2012, 09:40:38 pm »
I think I understood what you mean. Consequently, I tried to directly create a Personnage entity when I use the function addSprite() :

drawing1.addSprite(new Personnage);

The only problem is that I can't make understand to Drawing::drawFrame() function that sf::Sprite has a function called GetSprite().

void Drawing::drawFrame()
{
    for(i=0; i<drawTable.size(); i++)
    {
        m_app->Draw(*drawTable[i].getSprite());
    }
    i = 0;
}

Tell me if you don't understand what I did. For my part, I do have a headache just looking at this piece of code  :(

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Obtaining a sf::Sprite value thanks to a pointer
« Reply #9 on: April 05, 2012, 10:16:59 pm »
Your code is wrong, you must write drawTable[ i ]->getSprite() or (*drawTable[ i ]).getSprite().
Laurent Gomila - SFML developer

Kromah

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: Obtaining a sf::Sprite value thanks to a pointer
« Reply #10 on: April 05, 2012, 11:20:15 pm »
You're a genius!! Thank you so much, I'm struggling with it since yesterday!
But my addSprite() function only accepts Personnage type class. It means that I can't register any object unless it is a Personnage class.

void addSprite(Personnage *joueur);

You talked about inheriting from an Entity class with a draw() function. What did you mean? I don't see how I could use a parent class to accept any type of object. I confess I have some gaps in C++, which can be quite penalizing...

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Obtaining a sf::Sprite value thanks to a pointer
« Reply #11 on: April 06, 2012, 09:35:50 am »
Yeah, you should probably learn more about abstraction / inheritance before trying to design complicated things :)
Laurent Gomila - SFML developer

Kromah

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: Obtaining a sf::Sprite value thanks to a pointer
« Reply #12 on: April 08, 2012, 02:30:16 pm »
Ok, I finally managed to solve it :D
Thank you so much, what an honor to be help by a SFML developer  :'(