2017-09-23 4 views
1

Linux Mint 18.1でSFML 2.3.2をC++ 17を使って拾ってきました。 Hello Worldの後の2番目のプロジェクトとして、古い携帯電話があらかじめインストールされていたSnakeを再現しようとしています。ほとんどのものは今まで働いていましたが、後で対処しなければならないわずかな例外がありますが、ゲームによってはまだ完了していないものがあります。SFMLのスプライトで表示されない画像

これまでのところ、低レベルの言語でGUIや画像を使ったことがないので、正しく理解していることを確認してください。まず、イメージをテクスチャにロードしてから、スプライトにテクスチャを追加してから、そのスプライトをウィンドウに描画しますか?

プログラムは完璧にコンパイルされ、すべて正しく初期化され、説明できない主な問題はなく実行されます。画像が表示されない点を除きます。スプライトはデフォルトのモノクローム背景色で表示されますが、画像は表示されません。

私は間違っていますが、どうすれば修正できますか?ありがとう!

// HEADERS 
#include <iostream> 
#include <SFML/Graphics.hpp> 
#include <SFML/Graphics/Color.hpp> 
#include <SFML/Graphics/Font.hpp> 
#include <SFML/Graphics/Image.hpp> 
#include <SFML/Graphics/Rect.hpp> 
#include <SFML/Graphics/Sprite.hpp> 
#include <SFML/Graphics/Texture.hpp> 
#include <SFML/System/String.hpp> 
#include <SFML/Window/Keyboard.hpp> 

// CREATE NEW FONT 
sf::Font create_font() 
{ 
    sf::Font f; 
    bool id = f.loadFromFile("/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-B.ttf"); 

    if (id == false) 
    { 
     std::cerr << "Font:\tCould not be loaded." << std::endl; 
    } 
    else 
    { 
     std::cerr << "Font:\tLoaded successfully." << std::endl; 
    } 

    return f; 

} 

// CREATE NEW SPRITE USING TEXTURE, GIVEN ARE PATH WITH COORDINATES AND DIMENSIONS 
sf::Sprite load_img(std::string path, long x, long y, long w, long h) 
{ 
    sf::Texture t; 
    bool id = t.loadFromFile(path); 

    if (id == false) 
    { 
     std::cerr << "Texture:\t" << path << "\tFailed to load." << std::endl; 
    } 
    else 
    { 
     std::cerr << "Texture:\t" << path << "\tLoaded successfully." << std::endl; 
    } 

    sf::Sprite s(t); 
    s.setTextureRect(sf::IntRect((int)x, (int)y, (int)w, (int)h)); 
    s.setPosition(x, y); 
    return s; 
} 


// MAIN FUNCTION 
int main() 
{ 
    // DECLARING/DEFINING VARIABLES 
    unsigned long window_width = 512; 
    unsigned long window_height = 512; 
    unsigned long score = 0; 
    unsigned long head_old_position_x, head_old_position_y; 
    std::string title = "Snek"; 
    std::string wdir = "/home/kate/Documents/coding/snek/"; 

    // WINDOW 
    sf::RenderWindow window(sf::VideoMode(window_width, window_height), title); 
    window.setFramerateLimit(60); 

    // SPRITES 
    sf::Sprite background = load_img(wdir + "img/background.png", 0, 0, 512, 512); 
    sf::Sprite head = load_img(wdir + "img/head.png", 47, 39, 8, 8); 
    sf::Sprite body = load_img(wdir + "img/body.png", 39, 39, 8, 8); 
    sf::Sprite poison = load_img(wdir + "img/poison.png", 119, 119, 8, 8); 
    sf::Sprite trap = load_img(wdir + "img/trap.png", 159, 159, 8, 8); 
    sf::Sprite candy = load_img(wdir + "img/candy.png", 199, 199, 8, 8); 

    // FONT 
    sf::Font font = create_font(); 

    // TEXT 
    sf::Text score_display(title, font, 20); 
    sc// HEADERS 
#include <iostream> 
#include <SFML/Graphics.hpp> 
#include <SFML/Graphics/Color.hpp> 
#include <SFML/Graphics/Font.hpp> 
#include <SFML/Graphics/Image.hpp> 
#include <SFML/Graphics/Rect.hpp> 
#include <SFML/Graphics/Sprite.hpp> 
#include <SFML/Graphics/Texture.hpp> 
#include <SFML/System/String.hpp> 
#include <SFML/Window/Keyboard.hpp> 

// CREATE NEW FONT 
sf::Font create_font() 
{ 
    sf::Font f; 
    bool id = f.loadFromFile("/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-B.ttf"); 

    if (id == false) 
    { 
     std::cerr << "Font:\tCould not be loaded." << std::endl; 
    } 
    else 
    { 
     std::cerr << "Font:\tLoaded successfully." << std::endl; 
    } 

    return f; 

} 

// CREATE NEW SPRITE USING TEXTURE, GIVEN ARE PATH WITH COORDINATES AND DIMENSIONS 
sf::Sprite load_img(std::string path, long x, long y, long w, long h) 
{ 
    sf::Texture t; 
    bool id = t.loadFromFile(path); 

    if (id == false) 
    { 
     std::cerr << "Texture:\t" << path << "\tFailed to load." << std::endl; 
    } 
    else 
    { 
     std::cerr << "Texture:\t" << path << "\tLoaded successfully." << std::endl; 
    } 

    sf::Sprite s(t); 
    s.setTextureRect(sf::IntRect((int)x, (int)y, (int)w, (int)h)); 
    s.setPosition(x, y); 
    return s; 
} 


// MAIN FUNCTION 
int main() 
{ 
    // DECLARING/DEFINING VARIABLES 
    unsigned long window_width = 512; 
    unsigned long window_height = 512; 
    unsigned long score = 0; 
    unsigned long head_old_position_x, head_old_position_y; 
    std::string title = "Snek"; 
    std::string wdir = "/home/kate/Documents/coding/snek/"; 

    // WINDOW 
    sf::RenderWindow window(sf::VideoMode(window_width, window_height), title); 
    window.setFramerateLimit(60); 

    // SPRITES 
    sf::Sprite background = load_img(wdir + "/img/background.png", 0, 0, 512, 512); 
    sf::Sprite head = load_img(wdir + "/img/head.png", 47, 39, 8, 8); 
    sf::Sprite body = load_img(wdir + "/img/body.png", 39, 39, 8, 8); 
    sf::Sprite poison = load_img(wdir + "/img/poison.png", 119, 119, 8, 8); 
    sf::Sprite trap = load_img(wdir + "/img/trap.png", 159, 159, 8, 8); 
    sf::Sprite candy = load_img(wdir + "/img/candy.png", 199, 199, 8, 8); 

    // FONT 
    sf::Font font = create_font(); 

    // TEXT 
    sf::Text score_display(title, font, 20); 
    score_display.setString(std::to_string(score)); 
    score_display.setPosition(5, 5); 

    // LOOP 
    while (window.isOpen()) 
    { 
     sf::Event event; 
     while (window.pollEvent(event)) 
     { 
      if (event.type == sf::Event::Closed) 
      { window.close(); } 

      head_old_position_x = head.getPosition().x; 
      head_old_position_y = head.getPosition().y; 

      // MOVEMENT BASED ON KEYBOARD INPUT 
      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) 
      { 
       head.setPosition(head.getPosition().x - 8, head.getPosition().y); 
       body.setPosition(head_old_position_x, head_old_position_y); 
      } 

      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) 
      { 
       head.setPosition(head.getPosition().x, head.getPosition().y - 8); 
       body.setPosition(head_old_position_x, head_old_position_y); 
      } 

      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) 
      { 
       head.setPosition(head.getPosition().x + 8, head.getPosition().y); 
       body.setPosition(head_old_position_x, head_old_position_y); 
      } 

      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) 
      { 
       head.setPosition(head.getPosition().x, head.getPosition().y + 8); 
       body.setPosition(head_old_position_x, head_old_position_y); 
      } 


      if (body.getPosition().x == candy.getPosition().x && body.getPosition().y == candy.getPosition().y) 
      { 
       score ++; 
       score_display.setString(std::to_string(score)); 
      } 


      // REFRESH WINDOW 
      window.clear(); 
      window.draw(background); 
      window.draw(head); 
      window.draw(body); 
      window.draw(poison); 
      window.draw(trap); 
      window.draw(candy); 
      window.draw(score_display); 
      window.display(); 
     } 
    } 

    return 0; 
} 
ore_display.setString(std::to_string(score)); 
    score_display.setPosition(5, 5); 

    // LOOP 
    while (window.isOpen()) 
    { 
     sf::Event event; 
     while (window.pollEvent(event)) 
     { 
      if (event.type == sf::Event::Closed) 
      { window.close(); } 

      head_old_position_x = head.getPosition().x; 
      head_old_position_y = head.getPosition().y; 

      // MOVEMENT BASED ON KEYBOARD INPUT 
      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) 
      { 
       head.setPosition(head.getPosition().x - 8, head.getPosition().y); 
       body.setPosition(head_old_position_x, head_old_position_y); 
      } 

      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) 
      { 
       head.setPosition(head.getPosition().x, head.getPosition().y - 8); 
       body.setPosition(head_old_position_x, head_old_position_y); 
      } 

      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) 
      { 
       head.setPosition(head.getPosition().x + 8, head.getPosition().y); 
       body.setPosition(head_old_position_x, head_old_position_y); 
      } 

      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) 
      { 
       head.setPosition(head.getPosition().x, head.getPosition().y + 8); 
       body.setPosition(head_old_position_x, head_old_position_y); 
      } 


      if (body.getPosition().x == candy.getPosition().x && body.getPosition().y == candy.getPosition().y) 
      { 
       score ++; 
       score_display.setString(std::to_string(score)); 
      } 


      // REFRESH WINDOW 
      window.clear(); 
      window.draw(background); 
      window.draw(head); 
      window.draw(body); 
      window.draw(poison); 
      window.draw(trap); 
      window.draw(candy); 
      window.draw(score_display); 
      window.display(); 
     } 
    } 

    return 0; 
} 
+0

コンソールにメッセージはありますか? –

+0

イメージが表示されない通常の理由は、テクスチャが有効範囲外であるか、またはロードできなかったためです。 –

+0

@ArnavBorborahいいえ、何もSFML関数から何もありません。私自身のエラーチェックは*すべてが*意図したとおりに動作しているはずであることを確認します。 – Katembers

答えて

0

私はそれを持っていると思います。あなたはすべてのはイベントループ内

をものを描いているので、おそらく何も表示されません

while(window.isOpen())ループ範囲でその原料を入れてみてください。

+0

はい。それでおしまい!ありがとう!最後に、Dは先週、狂ったように自分のコードを見ていて、それを見つけることができませんでした。 – Katembers

0

テクスチャの範囲外です。詳細はWhen is an object "out of scope"?を参照してください。テクスチャはload_img関数内で宣言しますが、sf::Texture t;はload_imgを終了してスプライトを返した後に削除されます。

これは、テクスチャをload_img関数の外に保存し、参照渡しする更新された関数です。関連する部分のみが表示されます。まず、テクスチャをload_img関数に渡します。 sf::Texture t;を削除します。

sf::Sprite load_img(std::string path, long x, long y, long w, long h, sf::Texture& t) 
{ 
    bool id = t.loadFromFile(path); 
    [...] 
} 

テクスチャを宣言し、load_img関数に渡します。

sf::Texture headtexture; 
sf::Sprite head = load_img(wdir + "img/head.png", 47, 39, 8, 8, headtexture); 

すべてのスプライトでこれを行うと、正しく動作し、画像/スプライトが正しく表示されます。コメントに基づいて

編集 25 - 9月 - 2017

、ここでは機能せず、最小限の作業例です:

// HEADERS 
#include <iostream> 
#include <SFML/Graphics.hpp> 
#include <SFML/Graphics/Color.hpp> 
#include <SFML/Graphics/Font.hpp> 
#include <SFML/Graphics/Image.hpp> 
#include <SFML/Graphics/Rect.hpp> 
#include <SFML/Graphics/Sprite.hpp> 
#include <SFML/Graphics/Texture.hpp> 
#include <SFML/System/String.hpp> 
#include <SFML/Window/Keyboard.hpp> 

// MAIN FUNCTION 
int main() 
{ 
    // DECLARING/DEFINING VARIABLES 
    unsigned long window_width = 512; 
    unsigned long window_height = 512; 
    std::string title = "Snek"; 
    std::string wdir = "/home/kate/Documents/coding/snek/"; 

    // WINDOW 
    sf::RenderWindow window(sf::VideoMode(window_width, window_height), title); 
    window.setFramerateLimit(60); 

    // SPRITES 
    sf::Texture headtexture; 
    sf::Sprite head; 

    headtexture.loadFromFile(wdir + "img/head.png"); 
    head.setTexture(headtexture); 
    head.setTextureRect(sf::IntRect(47, 39, 8, 8)); 
    head.setPosition(30, 30); 

    // LOOP 
    while (window.isOpen()) 
    { 
     sf::Event event; 
     while (window.pollEvent(event)) 
     { 
      if (event.type == sf::Event::Closed) 
      { window.close(); } 

      // REFRESH WINDOW 
      window.clear(); 
      window.draw(head); 
      window.display(); 
     } 
    } 

    return 0; 
} 
+0

私はすでに昨日疑っており、すべてを100%確実にするために 'int main()'に移動しました。スプライトはデフォルトのモノクローム背景色で表示されますが、イメージはそこにありません。基本的に、私が見るのは窓の黒い背景だけです。 – Katembers

+0

はい、現在、関数内でテクスチャを定義していますが、終了時にスコープが外れて未定義の動作になる場合があります。 –

+0

テクスチャとスプライトの両方が 'int main()'で排他的に使用されるように変更しました。それはどこにも決して行きません。まだ動作しません。 – Katembers

0

おそらくあなたはテクスチャへの参照を失ってしまいました。あなたの場合、テクスチャはload_img()関数のローカル変数です。

スプライトが使用している間は、テクスチャをロードして使用可能にしておく必要があります。

この問題が説明されているSFMLチュートリアルのthisセクションを読むことをお勧めします。

+0

私はあなたがすべてを 'main'に移したというコメントを読みました。あなたはそのコードで更新できますか?おそらくそのように我々は任意のエラーを終了することができます – alseether

+0

それは問題の一部だったが、主な問題はどこかにあった。解決策としてマークした答えを見てください。それがここでの主な問題でした。 – Katembers

関連する問題