白色方块而不是实际图像

问题描述 投票:0回答:1

我最近通过一本书开始学习 SFML,并提出了一个问题,当您加载图像时,您会得到一个大的白色方块。

我有类

TextureHolder
用于管理游戏资源,例如纹理,精灵等(尚未完成)。我试图给它一个 RAII 方法,所以现在它不起作用(我通过书本学习)

纹理.hpp

#pragma once

#include <map>
#include <memory>
#include <SFML/Graphics.hpp>

namespace Textures {
    enum class ID { Landscape, Airplane, Missile };
}

class TextureHolder final {
public:
    void load(Textures::ID id, const std::string& filename);
    sf::Texture& get(Textures::ID id);
    const sf::Texture& get(Textures::ID id) const;

private:
    std::map<Textures::ID, std::unique_ptr<sf::Texture>> m_TextureMap;
};

纹理.cpp

#include <iostream>

#include "Textures.hpp"

void TextureHolder::load(Textures::ID id, const std::string &filename) {
    std::unique_ptr<sf::Texture> texture(new sf::Texture());
    if (!texture->loadFromFile(filename)) {
        std::cerr << "Failed to load texture from file: " << filename << std::endl;
        return;
    }

    m_TextureMap.insert(std::make_pair(id, std::move(texture)));
}

sf::Texture &TextureHolder::get(const Textures::ID id) {
    const auto found = m_TextureMap.find(id);
    return *found->second;
}

const sf::Texture& TextureHolder::get(const Textures::ID id) const {
    const auto found = m_TextureMap.find(id);
    return *found->second;
}

游戏.hpp

#pragma once

#include <bitset>
#include <SFML/Graphics.hpp>

enum Movement {
    Up,
    Down,
    Left,
    Right,
    MovementCount
};

class Game final {
public:
    explicit            Game();
    void                run();
    ~Game() =           default;
private:
    void                processEvents();
    void                update(sf::Time deltaTime);
    void                render();
    void                handlePlayerInput(sf::Keyboard::Key , bool );

    sf::RenderWindow  m_window;
    sf::Texture       m_texturePlane;
    sf::Sprite        m_spritePlane;

    std::bitset<MovementCount> m_isMoving;
};

游戏.cpp

#include "Game.hpp"

#include <iostream>

#include "Textures.hpp"

namespace {
    constexpr short WIDTH = 640;
    constexpr short HEIGHT = 480;
    const std::string TITLE = "SFML Application";
    constexpr float PLAYER_SPEED = 500.0f;
}

Game::Game() : m_window(sf::VideoMode(WIDTH, HEIGHT), TITLE) {
    m_window.setVerticalSyncEnabled(true);

    TextureHolder texture_holder;
    texture_holder.load(Textures::ID::Airplane, "/home/davit/CLionProjects/untitled/plane-animated-top-down-game-art.png");
    m_spritePlane.setTexture(texture_holder.get(Textures::ID::Airplane));
}

void Game::run() {
    sf::Clock clock;
    sf::Time timeSinceLastUpdate = sf::Time::Zero;
    const auto TimePerFrame = sf::seconds(1.f / 60.f);
    while (m_window.isOpen()) {
        const sf::Time elapsedTime = clock.restart();
        timeSinceLastUpdate += elapsedTime;
        while (timeSinceLastUpdate > TimePerFrame) {
            timeSinceLastUpdate -= TimePerFrame;
            processEvents();
            update(TimePerFrame);
        }
        render();
    }
}

void Game::processEvents() {
    sf::Event event;
    while (m_window.pollEvent(event)) {
        switch (event.type) {
            case sf::Event::KeyPressed:
                handlePlayerInput(event.key.code, true);
                break;
            case sf::Event::KeyReleased:
                handlePlayerInput(event.key.code, false);
                break;
            case (sf::Event::Closed):
                m_window.close();
                break;
        }
    }
}

void Game::handlePlayerInput(sf::Keyboard::Key key, bool isPressed) {
    if (key == sf::Keyboard::W)
        m_isMoving[Up] = isPressed;
    else if (key == sf::Keyboard::S)
        m_isMoving[Down] = isPressed;
    else if (key == sf::Keyboard::A)
        m_isMoving[Left] = isPressed;
    else if (key == sf::Keyboard::D)
        m_isMoving[Right] = isPressed;
}

void Game::update(const sf::Time deltaTime) {
    sf::Vector2f movement(0.f, 0.f);
    if (m_isMoving[Up])
        movement.y -= PLAYER_SPEED;
    if (m_isMoving[Down])
        movement.y += PLAYER_SPEED;
    if (m_isMoving[Left])
        movement.x -= PLAYER_SPEED;
    if (m_isMoving[Right])
        movement.x += PLAYER_SPEED;

    m_spritePlane.move(movement * deltaTime.asSeconds());
}

void Game::render() {
    m_window.clear();
    m_window.draw(m_spritePlane);
    m_window.display();
}
c++ game-development sfml raii
1个回答
0
投票

这里的问题与您上次发布此代码时的问题相同。

来自 sf::Sprite::setTexture 的 SFML 文档

纹理参数指的是只要存在就必须存在的纹理 精灵使用它。

这对于您的代码来说并非如此,这就是为什么您会得到一个白色矩形。

Game::Game() : m_window(sf::VideoMode(WIDTH, HEIGHT), TITLE) {
    m_window.setVerticalSyncEnabled(true);

    TextureHolder texture_holder;
    texture_holder.load(Textures::ID::Airplane, "/home/davit/CLionProjects/untitled/plane-animated-top-down-game-art.png");
    m_spritePlane.setTexture(texture_holder.get(Textures::ID::Airplane));
}

texture_holder
变量被销毁,
Game
构造函数的末尾和其中的所有纹理也同时被销毁。您必须将纹理保留移出游戏构造函数。例如将其放在 Game 类中

© www.soinside.com 2019 - 2024. All rights reserved.