2017-01-24 10 views
0

Ich habe eine question über SFML glatte Bewegung gestern gefragt ... und dieses Problem wurde gelöst, aber dieses Mal zeigt das Sprite, das ich verwende, als ein weißes Quadrat.SFML Sprite weißes Quadrat

Ich habe versucht, das Sprit zu drawship Funktion als Referenz zu senden, aber da ich diese Funktion auf main.cpp verwende ich bin nicht in der Lage zu tun, was auf this answer erzählt wird. Also frage ich mich, wie ich dieses Problem beheben kann.

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;' ist lokal für 'Spaceship's Konstruktor. Sie müssen es in einem größeren Umfang deklarieren, so dass seine Lebensdauer mindestens der des Raumschiffs entspricht. – Quentin

+0

ho entwirfst du es in einem größeren Umfang? –

Antwort

2

to the docs Laut „Die Textur muss so lange existieren, wie das Sprite es verwendet. Tatsächlich speichert das Sprite keine eigene Kopie der Textur ", also verschiebe einfach die sf::Texture vom Konstruktor zu einem Mitglied von Spaceship sollte es beheben.

+0

würde es nicht immer wieder erstellen, wenn ich es in eine Member-Funktion platziert? –

+0

Thnx viel Mann: D Das funktioniert jetzt gut. –

+1

In Ihrer ersten Frage haben Sie die Textur bei jedem Frame geladen, das ist schrecklich ineffizient. Wenn Sie dies im Konstruktor tun, geschieht dies nur einmal. Dies ist der einfachste Weg, um dieses Problem anzugehen, aber nicht das sauberste noch das klügste. Wie Mario in seiner Antwort darauf hingewiesen hat, können Sie eine Ressource-Manager-Klasse haben, um alle Ihre Assets zu verwalten. Aber in Ihrem Fall ist es gut und einfach genug, es im Konstruktor zu behalten – Zouch

2

Ein weißes Quadrat und nicht Ihre Textur deutet normalerweise darauf hin, dass die Textur nicht initialisiert/erstellt oder zerstört/ungültig wird.

In Ihrem Fall erstellen Sie ein Texturobjekt in Ihrem Spaceship-Konstruktor, das nicht gültig ist, sobald der Konstruktor fertig ist. Beachten Sie, dass nur einen Verweis (Zeiger) auf Ihre Textur empfängt/speichert, anstatt eine Kopie der tatsächlichen Textur.

Sie müssen es draußen speichern, z. als Teil einer Ressource-Manager-Klasse oder einfach an den Spaceship-Konstruktor übergeben.