White Square in SFML, Sprite and texture stored in

2019-07-08 05:15发布

I'm experiencing the white square problem in SFML. I'm working on a game that uses a tiled map. A Game class will load the tile set as a sf::Texture from a file and then a getTileById function in Game will "Cut" out the appropriate tile from the tileset texture. Eg.

sf::Sprite GameScreen::getSpriteByPos(int pos, sf::Texture texture, int tileSize) {
    sf::IntRect subRect;
    subRect.left = (pos-1)*tileSize;
    subRect.top = (pos-1)*tileSize;
    subRect.width = tileSize;
    subRect.height = tileSize;

    sf::Sprite tileSprite(texture, subRect);
    return tileSprite;
}

The sprite will then be passed into a Tile object, which will then set its sprite_ attribute to it. Eg.

void Tile::setSprite(sf::Sprite sprite) {
    sprite_ = sprite;
}

The Game object will load all tiles in this way and store them all in a vector. To draw them, it will loop through the vector and call the Tile::draw(sf::RenderWindow&) method on each one of them (Passing in the RenderWindow to be drawn to). This method takes an sf::RenderWindow and the tile simply calls the sf::RenderWindow::draw(sf::Sprite) on the RenderWindow with its sprite_ attribute. Eg.

void Tile::draw(sf::RenderWindow &window){
    window.draw(sprite_);
    return;
}

I'd like to do drawing this way because the Tile::draw method is inherited from a Drawable class, so that all objects that are drawable can inherit from Drawable and implement their drawing method in a way that suits them, something that will be necessary in my project. The sprite is being drawn as a white square though, which strikes me as strange as the tileSet_ attribute has not been destroyed, it is an attribute of the Game class and still exists.

Can anybody tell me what is going on here? Any help would be appreciated.

1条回答
小情绪 Triste *
2楼-- · 2019-07-08 05:52

You are passing your texture "by value". That means you get a copy of your texture inside this function:

sf::Sprite GameScreen::getSpriteByPos(int pos, sf::Texture texture, int tileSize) {
    sf::IntRect subRect;
    subRect.left = (pos-1)*tileSize;
    subRect.top = (pos-1)*tileSize;
    subRect.width = tileSize;
    subRect.height = tileSize;

    sf::Sprite tileSprite(texture, subRect);
    return tileSprite;
}

But that copy is destroyed when the function ends.

You don't need that copy, so don't make a copy:

sf::Sprite GameScreen::getSpriteByPos(int pos, const sf::Texture& texture, int tileSize) {
    sf::IntRect subRect;
    subRect.left = (pos-1)*tileSize;
    subRect.top = (pos-1)*tileSize;
    subRect.width = tileSize;
    subRect.height = tileSize;

    sf::Sprite tileSprite(texture, subRect);
    return tileSprite;
}
查看更多
登录 后发表回答