【问题标题】:SFML Sprite white squareSFML 雪碧白色方块
【发布时间】:2017-01-24 09:41:17
【问题描述】:

我昨天向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;
}

宇宙飞船.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(){}

宇宙飞船.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 */

【问题讨论】:

  • sf::Texture ship; 对于 Spaceship 的构造函数是本地的。您需要在更广泛的范围内声明它,使其生命周期至少与宇宙飞船的生命周期一样。
  • 你是否在更广泛的范围内贴花?

标签: c++ sprite sfml


【解决方案1】:

根据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);
}

【讨论】:

  • 如果我将它放在成员函数中,它不会一遍又一遍地创建它吗?
  • 在您最初的问题中,您在每一帧加载纹理,这是非常低效的。在构造函数中这样做只会使这种情况发生一次。这是解决此问题的最简单方法,但不是最干净也不是最聪明的方法。正如马里奥在他的回答中指出的那样,您可以拥有一个资源管理器类来管理您的所有资产。但是在您的情况下,将其保留在构造函数中既好又简单
【解决方案2】:

一个白色方块而不是你的纹理通常暗示纹理没有被初始化/创建或者它被破坏/无效。

在您的情况下,您正在 Spaceship 构造函数中创建纹理对象,一旦构造函数完成,该对象将无效。请注意,sf::Sprite 只是接收/存储对纹理的引用(指针),而不是实际纹理的副本。

您必须将其存储在外部,例如作为某些资源管理器类的一部分,或者只是将其传递给您的 Spaceship 构造函数。

【讨论】:

    猜你喜欢
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-13
    • 1970-01-01
    相关资源
    最近更新 更多