C++ SFML Sprite not being drawn through classes

大憨熊 提交于 2019-12-11 23:13:32

问题


(No, I do not mean the very basics of displaying a sprite. I simply could not think of a better title since I do not fully understand what is going wrong.)

Simply put, I have a sprite that, when being drawn to the screen, will not show up, but if I do some tests by making temporary sprites in int main() and draw them to the screen, they show up perfectly fine. So I know that I am doing something wrong with the design of my classes or something because they are where the sprites will not show.

(note: all of my classes are under the namespace of rpg:: I will cut it out to save space, but I might use it in my code without thinking - so to remove any confusion that might happen)

Code:

rpg.h:

static sf::Texture PlayerTexture;

/*
    NOTE: Loads in All Textures for use
          --This works properly (tested)
*/
static void SetUp()
{
    if(!PlayerTexture.loadFromFile("C:/Program Files (x86)/Terentia/Files/Textures/player.png"))
    {
        std::cout<<"Error: texture failed to load..."<<std::endl;
    }
}

AbstractComponents.h

//Abstract class for handling graphics
class GraphicsComponent : public rpg::Component, public sf::Drawable
{
protected:
    sf::Sprite mySprite;

public:
    virtual void HandleEvents(GameObject& object, sf::RenderWindow& screen, rpg::EventList& events) = 0;

//Copy Constructor
GraphicsComponent(const GraphicsComponent& me) {
    mySprite = me.mySprite; }

GraphicsComponent& GraphicsComponent::operator= (const GraphicsComponent &me){
    mySprite = me.mySprite; }

GraphicsComponent() {}
virtual ~GraphicsComponent() {}
};

PlayerGraphicsComponent.h

class PlayerGraphicsComponent : public rpg::GraphicsComponent
{

public:

virtual void Receive(rpg::Message message);

virtual void HandleEvents(GameObject& object, sf::RenderWindow& screen, rpg::EventList& events);

PlayerGraphicsComponent() { mySprite.setTexture(rpg::PlayerTexture); }
~PlayerGraphicsComponent();

private:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    //Draw sprite onto the screen.
    target.draw(mySprite, states);

}//needed to make drawable
};

GameObject.h

class GameObject : public rpg::ContainerObject, public sf::Drawable
{
public:
sf::Vector2f myPosition;

rpg::Movable CanMove;

GameObject();
GameObject(std::shared_ptr<InputComponent> input,
            std::shared_ptr<GraphicsComponent> graphics,
            std::shared_ptr<PhysicsComponent> physics )
:   myInput(input),
    myGraphics(graphics),
    myPhysics(physics)
{myPosition.x = 0;
myPosition.y = 0;}

//Copy Constructor
GameObject(const GameObject& me) {
    myInput = me.myInput;
    myGraphics = me.myGraphics;
    myPhysics = me.myPhysics;
    myPosition = me.myPosition; }

GameObject& GameObject::operator= (const GameObject &me);

~GameObject();

void HandleEvents(sf::RenderWindow& screen, rpg::EventList& events)
{
    myInput->HandleEvents(*this, screen, events);
    myPhysics->HandleEvents(*this, screen, events);
    myGraphics->HandleEvents(*this, screen, events);
}

private:
std::shared_ptr<InputComponent>     myInput;
std::shared_ptr<GraphicsComponent>  myGraphics;
std::shared_ptr<PhysicsComponent>   myPhysics;


private:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    target.draw(*myGraphics, states);

}//needed to make drawable
};http://stackoverflow.com/questions/13899077/c-sfml-display-glitch-with-sprite-member-changed-by-mouseclick

main.cpp

int main()
{
//Loads in all textures, info, etc
rpg::SetUp(); 

//Create Player Object
ptrGameObject player = rpg::CreatePlayer();

//Create render window and give it it's info
sf::RenderWindow screen;
screen.create(sf::VideoMode(800, 640), "Terentia", sf::Style::Close);

screen.setVerticalSyncEnabled(1); // Setting max framerate to 60 (Facultative)
screen.setFramerateLimit(60); // Setting max framerate to 60 (Facultative)

rpg::EventList eventList;

while(screen.isOpen())
{
    sf::Event events;
    while(screen.pollEvent(events))
    {
        eventList.push_back(events);
        if (events.type == sf::Event::Closed)
        {
            screen.close();
        }
    }

    //Handle Object Events here
        player->HandleEvents(screen, eventList);
    //End Object Handle Events

    eventList.clear();

    //temp sprite for test
    std::shared_ptr<sf::Sprite> tempSprite(new sf::Sprite());

    tempSprite->setTexture(rpg::PlayerTexture);

    screen.clear();

    //Doesn't draw to screen
    screen.draw(*player);

    //Does draw to screen.
    screen.draw(*tempSprite);

    screen.display();

}

return 0;
}

I know there is a ton of code here, but I believe that at least most of it is relevant. I haven't the slightest idea as to why the sprite in the graphics component doesn't show, but the temporary sprite works perfectly fine, even though both sprites' textures point to the same texture. My guess is that I did something wrong with the draw function inside of the classes, but they look fine to me. The other thing I think it my be is that the object's sprite isn't keeping the texture for some reason, but I made it set its texture to the rpg::PlayerTexture in its HandleEvents() function so that it would set the texture for sure, but that didn't fix it either. I am at a complete loss to this and it is probably something simple.

Thanks for taking the time to read through all of this and, if you are able to, I would love an explanation as to why the problem is the problem. Thanks


回答1:


When you declare a member of a class as static it means no matter how many objects of the class are created, there is only ONE copy of the static member. You need to declare it as "extern". extern sf::Texture PlayerTexture



来源:https://stackoverflow.com/questions/25046423/c-sfml-sprite-not-being-drawn-through-classes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!