2 votes

Pourquoi la méthode .setTexure() de la classe se comporte-t-elle différemment ?

La méthode .setTexure() de la classe de sprite sfml ne fonctionne pas dans le constructeur de l'itérateur, mais fonctionne lorsque l'itérateur est déjà créé.

Nous essayons de construire une structure pour les cadres qui sont dessinés sur la fenêtre. Nous utilisons la bibliothèque sfml, avec ses classes de sprites et de textures. Dans le constructeur de la structure frameData, nous chargeons une texture depuis un fichier, puis nous l'appliquons au sprite en utilisant la méthode .setTexture(). Lorsque nous compilons et exécutons notre programme, nous obtenons soit un bloc blanc, soit un plantage du programme, selon la machine.

Si nous créons un pointeur de référence à la texture avec .setTexture() en dehors du constructeur de frameData, cela fonctionne !

Tout cela se fait avec une structure itérative qui parcourt les différents cadres. Voici le code correspondant, d'abord c'est dans l'en-tête de la structure FrameData :

private:
    struct FrameData
    {
        FrameData(const std::string& fileName, int frameDelay);

        sf::Texture texture;
        sf::Sprite sprite;
        unsigned int frameDelay;
    };

Deuxièmement, voici les constructeurs actuels, qui ne fonctionnent pas :

const sf::Sprite& SpriteAnimator::currentFrame() const
{
    return currentFrame_->sprite;
}

SpriteAnimator::FrameData::FrameData(const std::string& fileName, int frameDelay)
: frameDelay(frameDelay)
{
    texture.loadFromFile(fileName);
    sprite.setTexture(texture);
}

Et troisièmement, voici ce qui fonctionne :

const sf::Sprite& SpriteAnimator::currentFrame() const
{
    currentFrame_->sprite.setTexture(currentFrame_->texture);
    return currentFrame_->sprite;
}

SpriteAnimator::FrameData::FrameData(const std::string& fileName, int frameDelay)
: frameDelay(frameDelay)
{
    texture.loadFromFile(fileName);
    sprite.setTexture(texture);
}

Une idée de la raison pour laquelle cela se produit, est-ce que quelque chose nous échappe ? Nous voulons que le constructeur fonctionne correctement, l'image actuelle est retournée beaucoup plus fréquemment que la texture ne change, donc nous n'avons pas besoin de mettre à jour la texture à chaque fois que l'image actuelle est retournée.

Merci !

1voto

s3binator Points 53

SOLVED ! Lisez le dernier paragraphe de la documentation de la classe sf::sprite :

Il est important de noter que l'instance sf::Sprite ne copie pas la texture qu'elle utilise. qu'elle utilise, elle ne fait que conserver une référence à celle-ci. Ainsi, une sf::Texture ne doit pas être détruite pendant qu'elle est utilisée par un sf::Sprite (i.e. ne jamais écrire une fonction qui utilise une instance locale de sf::Texture pour créer un sprite).

Donc créer un dépôt pour les textures en dehors de la portée de cette classe, puis passer les références fonctionne, comme strongdrink l'a recommandé !

1voto

elimirks Points 1032

J'ai eu un problème similaire avec ceci. Ma solution a été de stocker toutes mes textures dans un conteneur en dehors de la classe et d'utiliser un pointeur vers la texture au lieu de la texture elle-même. Cela fait d'une pierre deux coups car vous n'avez pas besoin de stocker plus d'une fois la même texture si vous voulez créer un autre objet à partir de la classe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X