2017-01-24 3 views
0

어제 SFML 부드러운 움직임에 대해 question에 물어 보았습니다. 문제가 해결되었지만 이번에는 사용중인 스프라이트가 흰색 사각형으로 표시됩니다.SFML 스프라이트 흰색 사각형

나는 참고로 drawship 기능에 스프라이트를 보내려고했지만 내가 main.cpp에 해당 기능을 사용하고 있기 때문에 나는 this answer에 말했다 무엇 할 수 없습니다입니다. 그래서 저는이 문제를 어떻게 해결할 수 있을지 궁금합니다.

MAIN.CPP

#include <SFML/Audio.hpp> 
#include <SFML/Graphics.hpp> 
#include "Spaceship.hpp" 
#include <vector> 

#include "ResourcePath.hpp" 

int main(int, char const**) 
{ 

    // Create the main window 
    sf::RenderWindow window(sf::VideoMode(800, 600), "SpaceShuttle"); 
    window.setFramerateLimit(30); 
    // Call to non-static member function without an object argument 
    // Set the Icon 
    sf::Image icon; 
    if (!icon.loadFromFile(resourcePath() + "space-shuttle.png")) { 
     return EXIT_FAILURE; 
    } 
    window.setIcon(icon.getSize().x, icon.getSize().y, icon.getPixelsPtr()); 

    // Load a sprite to display 
    sf::Texture texture; 
    if (!texture.loadFromFile(resourcePath() + "bg.png")) { 
     return EXIT_FAILURE; 
    } 
    sf::Sprite sprite(texture); 

    // Create a graphical text to display 
    sf::Font font; 
    if (!font.loadFromFile(resourcePath() + "sansation.ttf")) { 
     return EXIT_FAILURE; 
    } 
    sf::Text text("SpaceShuttle K1LLM33K", font, 50); 
    text.setFillColor(sf::Color::White); 
    text.setPosition(100.0, 130.0); 


    // Load a music to play 
    /* sf::Music music; if (!music.openFromFile(resourcePath() + "nice_music.ogg")) { return EXIT_FAILURE; } 
    // Play the music 
    music.play(); 
    */ 

    Spaceship spaceship(window); 
    sf::Clock sf_clock; 


    // Start the game loop 
    while (window.isOpen()) { 
     // Get time elapsed since last frame 
     float dt = sf_clock.restart().asSeconds(); 

     // Process events 
     sf::Event event; 
     while (window.pollEvent(event)) { 
      // Close window: exit 
      if (event.type == sf::Event::Closed) { 
       window.close(); 
      } 

      // Escape pressed: exit 
      if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) { 
       window.close(); 
      } 


     } 
     //move spaceship 
     if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) { spaceship.moveship(dt, 'l'); } 
     else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) { spaceship.moveship(dt, 'r'); } 
     else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) { spaceship.moveship(dt, 'u'); } 
     else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) { spaceship.moveship(dt, 'd'); } 
     // Clear screen 
     window.clear(); 

     // Draw the sprite(s) 
     window.draw(sprite); 
     // 
     // To draw the Spaceship 
     // 
     spaceship.drawsprite(window); 

     // Draw the string(s) 
     window.draw(text); 

     // Update the window 
     window.display(); 
    } 

    return EXIT_SUCCESS; 
} 

spaceship.cpp

#include <SFML/Audio.hpp> 
#include <SFML/Graphics.hpp> 
#include "ResourcePath.hpp" 
#include "Spaceship.hpp" 

Spaceship::Spaceship(sf::RenderWindow& game_window){ 
    auto surface = game_window.getSize(); 
    ss_x = ss_y = 0.5f; 
    ss_speed_x = 250.f/surface.x; 
    ss_speed_y = 250.f/surface.y; 
    ss_width = 128; 
    ss_height = 128; 
    ss_radius = ss_width/2; 

    sf::Texture ship; 
    if (!ship.loadFromFile(resourcePath() + "space-shuttle-64.png")) { 
     return EXIT_FAILURE; 
    } 

    ss_sprite = sf::Sprite(ship); 
    ss_sprite.setOrigin(ss_width/2, ss_height/2); 

} 


void Spaceship::drawsprite(sf::RenderWindow& game_window){ 
    auto size = game_window.getSize(); 
    ss_sprite.setPosition(ss_x * size.x, ss_y * size.y); 
    game_window.draw(ss_sprite); 
} 

void Spaceship::moveship(float dt, char move){ 
    switch (move) { 
     case 'l': ss_x -= dt * ss_speed_x; break; 
     case 'r': ss_x += dt * ss_speed_x; break; 
     case 'u': ss_y -= dt * ss_speed_y; break; 
     case 'd': ss_y += dt * ss_speed_y; break; 
    } 
} 

Spaceship::~Spaceship(){} 

spaceship.hpp

#ifndef Spaceship_hpp 
#define Spaceship_hpp 
#include <iostream> 
#include <SFML/Audio.hpp> 
#include <SFML/Graphics.hpp> 
#include <stdio.h> 

using namespace std; 

class Spaceship { 
public: 
    Spaceship(); 
    Spaceship(sf::RenderWindow&); 
    ~Spaceship(); 
    void moveship(float, char); 
    void drawsprite(sf::RenderWindow&); 
private: 
    float ss_x, ss_y; 
    float ss_speed_x, ss_speed_y; 
    int ss_width, ss_height, ss_radius; 
    sf::Sprite ss_sprite; 

}; 

#endif /* Spaceship_hpp */ 
+0

'sf :: Texture ship;은'우주선'의 생성자에 국한되어 있습니다. 수명이 우주선의 수명보다 길어 지도록 더 넓은 범위에서 선언해야합니다. – Quentin

+0

당신은 그것을 더 넓은 범위에서 데칼합니까? –

답변

2

to the docs에 따르면, "텍스처는 한 스프라이트가 그것을 사용으로 존재해야합니다. 사실, 스프라이트는 자체 텍스처 복사본을 저장하지 않습니다. "따라서 sf::Texture을 생성자에서 Spaceship의 멤버로 수정해야합니다.

class Spaceship { 
    // Some stuff 
    sf::Texture ss_ship_texture; 
}; 

Spaceship::Spaceship(const sf::RenderWindow& window) { 
    // Some stuff 
    ss_ship_texture.loadFromFile("path/to/ship/image"); 
    ss_ship.setTexture(ss_ship_texture); 
} 
+0

내가 멤버 함수 안에두면 반복해서 만들지 않을까요? –

+0

Thnx alot man : D 이제는 잘 작동합니다. –

+1

초기 질문에서 각 프레임에서 텍스처를로드하는 중, 이것은 매우 비효율적입니다. 생성자에서이 작업을 수행하면이 작업은 한 번만 발생합니다. 이것은이 문제를 해결할 수있는 가장 간단한 방법이지만, 가장 깨끗하고 똑똑하지는 않습니다. Mario는 대답에서 지적했듯이 모든 자산을 관리하는 리소스 관리자 클래스를 가질 수 있습니다. 하지만 귀하의 경우에는 그것을 생성자에서 유지하는 것은 충분하고 간단합니다. – Zouch

2

텍스처 대신 흰색 사각형은 텍스처가 초기화/생성되지 않거나 파괴되거나 유효하지 않다는 것을 암시합니다.

귀하의 경우 Spaceship 생성자에 텍스처 객체를 생성하고 있습니다.이 객체는 생성자가 완료된 후에는 유효하지 않습니다. sf::Sprite은 실제 텍스처 사본이 아니라 텍스처에 대한 참조 (포인터)를 받거나 저장합니다.

외부에 저장해야합니다. 일부 리소스 관리자 클래스의 일부로 사용하거나 단순히 Spaceship 생성자로 전달합니다.

관련 문제