SFML community forums

Help => Graphics => Topic started by: nightlet on January 05, 2010, 11:50:42 pm

Title: Inheriting from Drawable
Post by: nightlet on January 05, 2010, 11:50:42 pm
I'm attempting to inherit from Drawable in order to have multiple sprites behaving as if they were one (with a view to using it for a 2D skeletal animation system) - my overall code compiles fine if I do not declare any instances of the below class.

Code: [Select]
#include <vector>

#include <SFML/Graphics.hpp>

class MSprite : public sf::Drawable
  {
  public:
    MSprite(sf::Image& Image, float Rotation = 0)
      {
      Sprite.SetImage(Image);
      Sprite.SetRotation(Rotation);
      DrawBehind = true;
      }

    bool DrawBehind;

    sf::Sprite Sprite;

    std::vector<MSprite> Children;

    virtual void Render(sf::RenderTarget& target) const
      {
      if (DrawBehind) //draw below (before) child sprites
        {
        target.Draw(Sprite);
        for (unsigned int i = 0; i < Children.size(); i++)
          {
          target.Draw(Children[i]);
          }
        }
      else //draw above (after) child sprites
        {
        for (unsigned int i = 0; i < Children.size(); i++)
          {
          target.Draw(Children[i]);
          }
        target.Draw(Sprite);
        }
      }
  };


I get the below error when trying to compile with a declaration, no errors if I don't.
Code: [Select]
c:\dev\000\main.cpp||In function `int main(int, char**)':|
c:\dev\000\main.cpp|17|error: no matching function for call to `CGameEngine::CGameEngine()'|
c:\dev\000\gameengine.h|15|note: candidates are: CGameEngine::CGameEngine(const CGameEngine&)|
||=== Build finished: 1 errors, 0 warnings ===|


I'm using a structure based mostly on this: http://gamedevgeek.com/tutorials/managing-game-states-in-c/, but changed to use SFML instead of SDL.

Am I missing something ludicrously simple, like I think I am?
Title: Inheriting from Drawable
Post by: Nexus on January 06, 2010, 12:07:42 am
How is CGameEngine related to your code?
Title: Inheriting from Drawable
Post by: nightlet on January 06, 2010, 12:16:13 am
Quote from: "Nexus"
How is CGameEngine related to your code?


I'm using it to manage/switch between various states (ie. an intro, menu, game proper, etc).
Title: Inheriting from Drawable
Post by: Dravere on January 06, 2010, 12:32:30 am
Quote from: "nightlet"
Quote from: "Nexus"
How is CGameEngine related to your code?


I'm using it to manage/switch between various states (ie. an intro, menu, game proper, etc).

Very well, but the error says, it can't find an empty constructor for CGameEngine. The error has nothing to do with the code you showed us.

Dravere
Title: Inheriting from Drawable
Post by: nightlet on January 06, 2010, 12:35:59 am
Addendum:
Seems to work just fine when I use it in the code found on http://www.sfml-dev.org/tutorials/1.5/graphics-sprite.php in place of a sprite.

Am I declaring it in a manner that the compiler doesn't like? (I'm still getting to grips with C++)

As noted above, the below class compiles without error if I switch out MSprite for a standard sf::Sprite (it even seems to complain if I declare an instance of it in the class without ever actually referring to it).

Code: [Select]
class CGameEngine
  {
  public:
    void Init(const char* title, int width = 800, int height = 600, int bpp = 0, bool fullscreen = false);
    void Cleanup();

    void ChangeState(CGameState* state);
    void PushState(CGameState* state);
    void PopState();

    void HandleEvents();
    void Update();
    void Draw();

    bool Running() { return m_running; }
    void Quit() { m_running = false; }

    sf::RenderWindow screen;
    sf::Font defaultfont;

  private:
    // the stack of states
    std::vector<CGameState*> states;

    bool m_running;
    bool m_fullscreen;

    sf::Image cursorimage;
    MSprite cursor;

    bool _debug;
  };


Code: [Select]
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>

#include <cstdlib>

#include <sstream>
#include <stdio.h>

#include "gameengine.h"
#include "gamestate.h"

#include "csprite.h"

void CGameEngine::Init(const char* title, int width, int height, int bpp, bool fullscreen)
  {
  _debug = true;
  screen.Create(sf::VideoMode(800, 600), title);
  screen.SetFramerateLimit(60);
  screen.ShowMouseCursor(false);
  screen.Show(true);

  if (!cursorimage.LoadFromFile("./data/images/pointer.png"))
    Quit();

  cursor.Sprite.SetImage(cursorimage);

  m_running = true;

  printf("CGameEngine Init\n");
  }


void CGameEngine::Cleanup()
  {
  // cleanup the all states
  while (!states.empty())
    {
    states.back()->Cleanup();
    states.pop_back();
    }

  // switch back to windowed mode so other
  // programs won't get accidentally resized
  if (m_fullscreen)
    {
    }

  printf("CGameEngine Cleanup\n");

  // shutdown SFML
  screen.Close();
  }


void CGameEngine::ChangeState(CGameState* state)
  {
  // cleanup the current state
  if (!states.empty())
    {
    states.back()->Cleanup();
    states.pop_back();
    }

  // store and init the new state
  states.push_back(state);
  states.back()->Init(this);
  }


void CGameEngine::PushState(CGameState* state)
  {
  // pause current state
  if (!states.empty())
    {
    states.back()->Pause();
    }

  // store and init the new state
  states.push_back(state);
  states.back()->Init(this);
  }


void CGameEngine::PopState()
  {
  // cleanup the current state
  if (!states.empty())
    {
    states.back()->Cleanup();
    states.pop_back();
    }

  // resume previous state
  if (!states.empty())
    {
    states.back()->Resume();
    }
  }


void CGameEngine::HandleEvents()
  {
  const sf::Input& Input = screen.GetInput();
  MousePosition.x = Input.GetMouseX();
  MousePosition.y = Input.GetMouseY();

  // let the state handle events
  states.back()->HandleEvents(this);
  }


void CGameEngine::Update()
  {
  cursor.SetPosition(MousePosition);

  // let the state update the game
  states.back()->Update(this);
  }


void CGameEngine::Draw()
  {
  screen.Clear(sf::Color(0, 0, 0));
  // let the state draw the screen
  states.back()->Draw(this);
  screen.Draw(cursor);
  screen.Display(); //flip buffer
  }


(edit - would probably help if i included the implementation...)
Title: Inheriting from Drawable
Post by: Nexus on January 06, 2010, 12:43:54 am
C++ provides constructors to get rid of C-Style Init() functions. You must initialize the member MSprite in your initialization list of the CGameEngine() constructor.