2016-04-26 7 views
0

この機能を実装する際に問題があります。スプライトがローカルなので範囲外です

私はそれが「空のゲームでプレイヤーを作成する::実行を交換したいが、私はPlayer_textureがCreateplayerにローカルであり、ときに関数が存在しないことをことを実現//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); 
} 

戻ります。それがスコープ外に行ってきましたので、私のスプライトが白いボックスを返さないように

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); 
+1

機能を実装すると[Spriteのホワイトボックスになる可能性があります](http://stackoverflow.com/questions/36852825/sprite-becomes-white-box-when-i-implement-function) – Hiura

+0

与えられた答えを完全に考慮せずに全く同じ質問をしています... – Hiura

答えて

2

あなたが呼んでいるsetTexture()メソッドのドキュメント(http://www.sfml-dev.org/documentation/2.0/classsf_1_1Sprite.php#a3729c88d88ac38c19317c18e87242560)は言う:

テクスチャ引数は限りスプライトがそれを使用して存在している必要がありますテクスチャを指します。実際、スプライトは独自のテクスチャのコピーを格納するのではなく、この関数に渡したポインタを保持します。ソーステクスチャが破棄され、スプライトがそれを使用しようとすると、動作は未定義です。そして、あなたはあなたの関数からこれを返すことができ

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; 
    } 
}; 

:これに対処するため

一つの方法は、Spriteとその食感の両方が含まれている独自の構造体やクラスを作ることであろう

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

これで、テクスチャは常にスプライトと同程度に長くなります。

ただし、「敵」を構築するときには、それらのすべてに単一のテクスチャを使用することに注意してください。多くのスプライト間の1つのテクスチャを共有可能にするために、我々は上記を向上させることができます。

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 
} 

は今、ベクターシェアのすべての敵単一のテクスチャを。おそらく、これは効率性にとって重要です。

+1

'SpriteWithTexture'の最初の草案はバグです:コピーすると、コピーされたスプライトはコピーされたテクスチャへの参照を持たず、元のテクスチャまた、2番目のバージョンは私にとっては複雑すぎるようです。[OPの重複した質問](http://stackoverflow.com/a/36855842/520217)で説明したように、リソースマネージャを使う方がよいでしょう。この方法では、テクスチャの格納は実際には別のタスクであり、残りのプログラムとは切り離されています。 – Hiura

+0

@Hiura:ありがとう、私はあなたが正しく指摘したバグを修正したと信じています。 –

+0

実際はそうではありません。スプライトも完全にコピーする必要があります(テクスチャ参照を上書きする前に)。テクスチャ参照以外のプロパティもあります。 ;-) – Hiura

関連する問題