SFML community forums

Help => General => Topic started by: NGM88 on June 01, 2017, 07:06:44 pm

Title: vector of Drawable AND Transformable
Post by: NGM88 on June 01, 2017, 07:06:44 pm
Hi, I'm trying to create a vector for objects from VARIOUS classes that all inherit from Drawable AND Transformable.

if I use

std::vector<std::reference_wrapper<const sf::Drawable>>

then I can't get their position with getPosition()

and if I use

std::vector<std::reference_wrapper<const sf::Transformable>>

then I can't draw them.

I need to be able to do both (getPosition AND draw).

Title: Re: vector of Drawable AND Transformable
Post by: Elias Daler on June 01, 2017, 07:14:19 pm
Maybe you should create a class DrawableTransformable : public sf::Drawable, sf::Transformable and inherit your classes from it, and then make vector of std::reference_wrapper of DrawableTransformable.
Title: Re: vector of Drawable AND Transformable
Post by: NGM88 on June 01, 2017, 07:20:23 pm
Maybe you should create a class DrawableTransformable : public sf::Drawable, sf::Transformable and inherit your classes from it, and then make vector of std::reference_wrapper of DrawableTransformable.

trying that at the moment, but can't quite figure out the definition of the virtual draw function.
Title: Re: vector of Drawable AND Transformable
Post by: NGM88 on June 01, 2017, 07:26:16 pm
   void Draw(sf::RenderTarget& target, sf::RenderStates states) const
   {
      states.transform *= getTransform();
      target.draw(SOMETHING??, states);
   }

this is what I have so far. I'm not sure how to get that SOMETHING part.
Title: Re: vector of Drawable AND Transformable
Post by: Elias Daler on June 01, 2017, 07:29:57 pm
Well, the class should have something which will be used for drawing. For example, it may store a sf::Sprite or sf::VertexArray. And then you'll pass it into a target.draw function. sf::Drawable has nothing which you can use for drawing, it's an abstract interface which is used by sf::RenderTarget to call virtual draw functions.
Title: Re: vector of Drawable AND Transformable
Post by: eXpl0it3r on June 01, 2017, 09:35:31 pm
Also note, the suggestion works, but you can't store SFML objects (e.g. Sprite, Shape, etc) in your vector.
Title: Re: vector of Drawable AND Transformable
Post by: NGM88 on June 01, 2017, 11:41:31 pm
Here's some code showing where I'm stuck.

What I'm trying to do is first put various derived classes of Dude (such as RedDude here) into a vector to sort them by position, and then put everything from vector into a vector of sf::Drawables (along with some other stuff like the background which I don't want mixed with the "Dudes") so that I can draw them.

Problem is I don't really understand what to put into the base class:

#include <SFML/Graphics.hpp>
#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
#include "AssetManager.h"

class Dude : public sf::Drawable, public sf::Transformable
{
public:

   void Draw(sf::RenderTarget& target, sf::RenderStates states) const
   {
      states.transform *= getTransform();
      target.draw(*THING, states);
   }

private:

   std::unique_ptr<sf::Drawable> THING;
};

class RedDude : public Dude
{
public:
   bool load()
   {
      red_dude = sf::Sprite(AssetManager::GetTexture("Media/red_dude.png"));
      red_dude.setTextureRect(sf::IntRect(0, 0, 96, 140));
      red_dude.setScale(1, 1);
      red_dude.setOrigin(48, 124);

      return true;
   }

   virtual void draw(sf::RenderTarget& target, sf::RenderStates states)const
   {
      states.transform *= getTransform();
      states.texture = &red_dude_tex;
      target.draw(red_dude, states);
   }

   sf::Sprite red_dude;
   sf::Texture red_dude_tex;
};

std::vector<std::unique_ptr<Dude>> Dudes;
std::vector<std::reference_wrapper<const sf::Drawable>> World;

int main()
{
   sf::RenderWindow window(sf::VideoMode(800, 600), "SFML");

   std::unique_ptr<RedDude> d1 = std::make_unique<RedDude>();

   d1->load();
   d1->setPosition(50,50);

   Dudes.push_back(std::move(d1));
   World.push_back(std::move(Dudes[0]));

   while (window.isOpen())
   {
      sf::Event event;
      while (window.pollEvent(event))
      {
         if (event.type == sf::Event::Closed)
            window.close();
      }

      window.clear();
      window.draw(World[0]);
      window.display();
   }

   return 0;
}

-------

trying to compile this code gives me an error at this line:

World.push_back(std::move(Dudes[0]));

... says that argument type doesn't match the object type.
Title: Re: vector of Drawable AND Transformable
Post by: Elias Daler on June 01, 2017, 11:44:43 pm
You don't need to have Dude::Draw function, because RedDude::draw function will be called because it's virtual.
Title: Re: vector of Drawable AND Transformable
Post by: NGM88 on June 01, 2017, 11:47:36 pm
You don't need to have Dude::Draw function, because RedDude::draw function will be called because it's virtual.

Thanks a lot for the fast replies. I still get the same error at World.push_back though.
Title: Re: vector of Drawable AND Transformable
Post by: Elias Daler on June 02, 2017, 01:19:13 am
That's because you're trying to push_back unique_ptr<Dude> while World expects to have something convertible to sf::Drawable&. Just do this:
World.push_back(*Dudes[0]);
Title: Re: vector of Drawable AND Transformable
Post by: NGM88 on June 02, 2017, 06:22:52 am
That's because you're trying to push_back unique_ptr<Dude> while World expects to have something convertible to sf::Drawable&. Just do this:
World.push_back(*Dudes[0]);

I get an "Exception thrown: read access violation." error.

am I not supposed to have anything else in the base class?
Title: Re: vector of Drawable AND Transformable
Post by: Elias Daler on June 02, 2017, 09:08:23 am
What causes that exception? Btw, I just noticed that you don't initialize red_dude_tex.
No, you're not supposed to have anything else in base class as far as I can tell.
Title: Re: vector of Drawable AND Transformable
Post by: NGM88 on June 02, 2017, 10:53:07 am
What causes that exception? Btw, I just noticed that you don't initialize red_dude_tex.
No, you're not supposed to have anything else in base class as far as I can tell.

oh my god, you're right. that stupid assetmanager confused me. thanks so much!
Title: Re: vector of Drawable AND Transformable
Post by: Elias Daler on June 02, 2017, 12:26:24 pm
You're welcome. :)