1

I'm using SFML, and my game is coming along well. After implementing a player and tile system, I decided to make enemies. My enemies are stored in a std::vector, and they use a copy constructer that defines their position in the game. I've been trying for hours on end to get their textures to load correctly, but they don't. My player and tiles' textures load fine, but the enemies' textures will either display nothing or a white box depending on what I do. I pushed back an instance in main for testing, and I either get a white box, nothing, or the texture of a different object. I made sure the file path is correct and everything, but the texture just doesn't show correctly. Here is skeleton.h:

#include "Common.h"

class Skeleton {
public:
    Skeleton(RenderWindow* window, vector<Skeleton> *skeletonVector);
    Skeleton(float& x, float& y);
    void draw();
    void update();
    Sprite sprite;
private:
    Texture texture;
    RenderWindow* window = nullptr;
    vector<Skeleton>* skeletonVector = nullptr;
    const float SPRITE_SIZE;
};

and here is skeleton.cpp:


Skeleton::Skeleton(RenderWindow* window, vector<Skeleton>* skeletonVector) 
    :SPRITE_SIZE(16.f)
{
    texture.loadFromFile("Skeleton/s.png");
    this->window = window;
    this->skeletonVector = skeletonVector;
}

Skeleton::Skeleton(float& x, float& y)
    :SPRITE_SIZE(16.f)
{
    this->sprite.setTexture(texture);
    this->sprite.setOrigin(SPRITE_SIZE / 2, 0.f);
    this->sprite.setPosition(x, y);
}


void Skeleton::draw(){
    for (int i = 0; i < skeletonVector->size(); i++) {
        window->draw(skeletonVector->at(i).sprite);
    }
}

void Skeleton::update()
{
}

I already called draw in main, created an instance with the first constuctor to take in the window and vector from main, and pushed back an instance of my object in the vector. Could someone please try to explain why the textures aren't showing correctly? I'm open to any critisism or code changes too. Thanks!

4
  • this->skeletonVector = skeletonVector; just copies a pointer, not any data. If the original is destroyed, perhaps by going out of scope, then you have a dangling pointer. Since you didn't show us how this code is used it's hard to say what the issue is. It's also worth noting that the other constructor leaves the vector pointer set to nullptr and calling draw with an object like that is undefined behavior and very likely a crash. Commented Mar 1, 2022 at 5:29
  • Thanks for the response. this->skeletonVector is a pointer that takes the value of the passed value for convenience's sake. I don't believe that it's the reason for this bug. The first constructer is called in main to set up everything, while the second constructer uses values established by the first one like the textures and skeletonVector. I think the problem is with the loading from file function. I'm not sure how to call that function to get the texture before the other constructer is used. I want to avoid loading a texture for every instance, so that's why I have the two constructers. Commented Mar 1, 2022 at 5:38
  • Will the vector passed as a parameter to the constructor outlive that object in all cases? If you can't answer a guaranteed yes to that then you're doing it wrong. Your comment "the second constructer uses values established by the first one like the textures and skeletonVector" makes me think you do not understand how constructors work. If a constructor is called it is creating a new instance of an object. What you may have set other instances to has nothing to do with that new instance. If that constructor is called both window and skeletonVector will remain set to nullptr. Commented Mar 1, 2022 at 5:44
  • I think I see what you mean. You're saying that the constructer only changes the member values for a specific instance rather than the whole class? So instead of using a constructer in this fashion, would it be better to make an init function that changes the members of the class? I'm still a little confused on how I could change my code. Commented Mar 1, 2022 at 5:50

1 Answer 1

1

Your second constructor will not work since the texture is not set. You should only have one constructor which takes the RenderWindow* and the vector* as mandatory parameters or you're not gonna be able to interact with your vector within the class methods. Your texture problem probably comes from when you call the second constructor

Skeleton::Skeleton(float& x, float& y)
{
    this->sprite.setTexture(texture);

because this line is trying to apply the texture to the sprite while this texture has not loaded any file (because you do it in the other constructor).

So what you want to do here is either get rid of one of your constructors, load the texture in the second constructor as well (but I think if you only do that you will get in other kinds of troubles with manipulating the vector and drawing them to the RenderWindow) or overloading the copy constructor of your class (and get rid of one of your actual constructors anyway). So here's my suggestion :

Skeleton::Skeleton(RenderWindow* window, vector<Skeleton>* skeletonVector, float& x, float& y) 
    :SPRITE_SIZE(16.f)
{
    texture.loadFromFile("Skeleton/s.png");
    this->window = window;
    this->skeletonVector = skeletonVector;
    this->sprite.setTexture(texture);
    this->sprite.setOrigin(SPRITE_SIZE / 2, 0.f);
    this->sprite.setPosition(x, y);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.