iProgram
iProgram

Reputation: 6577

SFML Ambiguous conversion from derived class when implementing draw function

I am trying to create by own game engine where each basic is a GameObject which will consist of an update function and other notifiers.

Here is my code so far:

#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include "AssetManager.hpp"

class GameObject : public sf::Drawable, public sf::Transformable
{
public:
  virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const{
    target.draw(*this, states);
  };
};

class Sprite : public GameObject, public sf::Sprite {
public:
  Sprite(AssetManager assetManager, std::string assetName) : sf::Sprite(){
    setTexture(assetManager.getTextureNamed(assetName));
  }
};


int main(int argc, char const** argv)
{
  sf::RenderWindow window(sf::VideoMode::getDesktopMode(), "");
  AssetManager assetManager = AssetManager("/Users/iProgram/Desktop/My Game Engine/My Game Engine");
  assetManager.loadTextureWithName("tank", "tank.png", sf::Vector2f(16,16));

  Sprite tank = Sprite(assetManager, "tank");

  while(window.isOpen()){
    window.clear();
    window.draw(tank);
    window.display();
  }

  return EXIT_SUCCESS;
}

Please note, the asset manager simply stores textures in memory and returns it when needed with a given size.

The problem is on the line: window.draw(tank);, I am getting the error

Ambiguous conversion from derived class 'const Sprite' to base class 'const sf::Drawable':

Why is this as I have implemented the draw function in the GameObject class and how can I fix it?

Upvotes: 0

Views: 436

Answers (2)

iProgram
iProgram

Reputation: 6577

To solve this issue, I dod not have to use private inheritance as some suggested, I just needed my base class (GameObject) to inherit nothing. My Sprite class would then inherit sf::Sprite like so:

#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include "AssetManager.hpp"

class GameObject{
public:
  virtual void update(){}
};

class Sprite : public GameObject, public sf::Sprite {
public:
  Sprite(AssetManager* assetManager, std::string assetName) : sf::Sprite(assetManager->getTextureNamed(assetName)){
  }
};

class Tank: public Sprite{
public:
  Tank(AssetManager* assetManager) : Sprite(assetManager, "tank"){
    setScale(3, 3);
  };

  virtual void update(){
    move(1,0);
  }
};

int main(int argc, char const** argv)
{
  sf::RenderWindow window(sf::VideoMode::getDesktopMode(), "");
  AssetManager* assetManager = new AssetManager("/Users/iProgram/Desktop/My Game Engine/My Game Engine");
  assetManager->loadTextureWithName("tank", "tank.png", sf::Vector2f(16,16));

  Tank tank = Tank(assetManager);
  while(window.isOpen()){
    sf::Event event;
    while(window.pollEvent(event)){
      if(event.type == sf::Event::Closed){
        window.close();
      }
    }
    tank.update();
    window.clear();
    window.draw(tank);
    window.display();
  }

  return EXIT_SUCCESS;
}

Upvotes: 0

Hatted Rooster
Hatted Rooster

Reputation: 36503

Your Sprite class inherits from GameObject which inherits from sf::Drawable. Your class also inherits from sf::Sprite which also inherits from sf::Drawable. Now your Sprite class has 2 inherited sf::Drawable subobjects and the compiler can't choose.

To fix this, either rethink your design or inherit virtually.

Upvotes: 1

Related Questions