我在实现此功能时遇到麻烦。

//Engine.cpp

void Game::createPlayer(sf::Sprite &player)
{   ///Can't get this to work
    sf::Texture player_texture;
    if (!player_texture.loadFromFile("player.png"))
    {
        //Error Loading
    }
    player.setTexture(player_texture);
}


我希望它代替“在无效Game :: run中创建玩家”,但我意识到Player_texture对于Createplayer是本地的,并且当函数返回时它将不存在。

void Game::run()
{
    sf::RenderWindow window(sf::VideoMode(SCREEN_X, SCREEN_Y), "Shogun Master");
    srand((unsigned int)time(NULL));
    //Creates Player    [Makes into function]
    sf::Texture player_texture;
    player_texture.loadFromFile("sprites/player.png");
    sf::Sprite player(player_texture);
    //Creates Enemy [Make into function]
    sf::Texture enemy_texture;
    enemy_texture.loadFromFile("sprites/enemy.png");
    sf::Sprite enemy[MAX_ENEMIES];
    for (int x = 0; x < MAX_ENEMIES; x++)
    {
        enemy[x].setTexture(enemy_texture);
        enemy[x].setPosition(rand_int(100, SCREEN_X - 100), rand_int(100, SCREEN_Y - 100)); //Spawning Point
    }
    //Sets Positions
    player.setPosition(500, 300);

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            check_closeWindows(event, window);  //Closes Game if Executed
            player_movement(event);             //Moves Character
            attack(event);                      //Character's attacks
        }
        border(player);                 //Border so player does not go off screen
        for (int x = 0; x < total_enemies; x++)
            border(enemy[x]);
        movementUpdate(player, enemy);  //Player & Enemy Movement Updates
        collision(player, enemy[0]);

        window.clear();
        window.draw(player);    //Draws Player
        for (int x = 0; x < total_enemies; x++)
            window.draw(enemy[x]);      //Draws Enemy
        window.display();
    }
}


所以我将如何实现它,以使我的精灵不会返回白盒,因为它超出了范围。

//Engine.h

void Game::createPlayer(sf::Sprite &player);

最佳答案

您正在调用的setTexture()方法的文档(http://www.sfml-dev.org/documentation/2.0/classsf_1_1Sprite.php#a3729c88d88ac38c19317c18e87242560)说:


  Texture参数是指只要精灵使用它就必须存在的纹理。实际上,精灵不会存储纹理的副本,而是保留指向您传递给该函数的指针的指针。如果源纹理被破坏并且精灵试图使用它,则行为是不确定的。


解决此问题的一种方法是制作自己的同时包含Sprite及其纹理的结构或类:

struct SpriteWithTexture
{
    sf::Texture texture;
    sf::Sprite sprite;

    SpriteWithTexture()
    {
        sprite.setTexture(texture);
    }

    SpriteWithTexture(const SpriteWithTexture& that)
        : texture(that.texture)
    {
        sprite.setTexture(texture);
    }

    SpriteWithTexture& operator=(const SpriteWithTexture& that)
    {
        texture = that.texture;
        sprite.setTexture(texture);
        return *this;
    }
};


然后,您可以从函数中返回此代码:

SpriteWithTexture Game::createPlayer()
{
    SpriteWithTexture player;
    if (!player.texture.loadFromFile("player.png"))
    {
        //Error Loading
    }
    return player;
}


现在,纹理将始终与精灵保持一致。

但是请注意,在构造“敌人”时,对所有敌人使用单个纹理。为了能够在多个精灵之间共享一个纹理,我们可以增强上述内容:

struct SpriteWithTexture
{
    std::shared_ptr<sf::Texture> texture;
    sf::Sprite sprite;

    SpriteWithTexture(const std::shared_ptr<sf::Texture>& texture_)
        : texture(texture_)
    {
        sprite.setTexture(*texture);
    }
};


现在您可以通过以下方式使用它:

std::shared_ptr<sf::Texture> player_texture(new sf::Texture);
player_texture->loadFromFile("sprites/player.png");
SpriteWithTexture player(player_texture);

std::shared_ptr<sf::Texture> enemy_texture(new sf::Texture);
enemy_texture->loadFromFile("sprites/enemy.png");
std::vector<SpriteWithTexture> enemies;
for (int x = 0; x < MAX_ENEMIES; x++)
{
    enemies.emplace_back(enemy_texture); // construct enemy Sprite
    enemies.back().sprite.setPosition(rand_int(100, SCREEN_X - 100), rand_int(100, SCREEN_Y - 100)); //Spawning Point
}


现在向量中的所有敌人都共享一个纹理。也许这对效率很重要。

关于c++ - Sprite 不在范围内,因为它是本地的,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36853738/

10-11 11:35