C ++ SFML错误sf :: NonCopyable :: Noncopyable

时间:2015-09-24 18:13:46

标签: c++ sfml

我找不到在我的代码中修复此错误的方法,在谷歌搜索和检查源代码后,我找不到解决方法。

错误:

Error   1   error C2248: 'sf::NonCopyable::NonCopyable' : cannot access private member declared in class 'sf::NonCopyable'  d:\sfml-2.3.1\include\sfml\window\window.hpp    521

 Error  2   error C2248: 'sf::NonCopyable::NonCopyable' : cannot access private member declared in class 'sf::NonCopyable'  d:\sfml-2.3.1\include\sfml\graphics\rendertarget.hpp    419

这是我认为错误所在的代码,否则它是很多代码。如果你需要完整的代码,只需要它,我会快速编辑这篇文章。

SceneNode.h

#ifndef SCENENODE_H
#define SCENENODE_H

#include <SFML/Graphics/Drawable.hpp>
#include <SFML/Graphics/Transformable.hpp>
#include <SFML/System/NonCopyable.hpp>
#include <SFML/System/Time.hpp>

#include <vector>
#include <memory>

class SceneNode : public sf::Transformable, public sf::Drawable, private sf::NonCopyable
{
public:
    typedef std::unique_ptr<SceneNode> Ptr;

private:
    std::vector<Ptr> children;
    SceneNode* parent;

    virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
    virtual void drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const;

    void drawChildren(sf::RenderTarget& target, sf::RenderStates states) const;
    virtual void updateCurrent(sf::Time dt);
    void updateChildren(sf::Time dt);

public:
    SceneNode();

    void update(sf::Time dt);
    void attachChild(Ptr child);
    Ptr detachChild(const SceneNode& node);

    sf::Transform getWorldTransform() const;
    sf::Vector2f getWorldPosition() const;
};

#endif

SceneNode.cpp

#include "SceneNode.h"
#include <cassert>

SceneNode::SceneNode() : parent(nullptr) {}

void SceneNode::attachChild(Ptr child){
    child->parent = this;
    children.push_back(std::move(child));
}

SceneNode::Ptr SceneNode::detachChild(const SceneNode& node){
    auto found = std::find_if(children.begin(), children.end(),
        [&](Ptr& p) {return p.get() == &node; });

    assert(found != children.end());

    Ptr result = std::move(*found);
    result->parent = nullptr;
    children.erase(found);
    return result;
}

void SceneNode::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const{}

void SceneNode::draw(sf::RenderTarget& target, sf::RenderStates states) const{
    states.transform *= getTransform();

    drawCurrent(target, states);
    drawChildren(target, states);
}

void SceneNode::update(sf::Time dt){
    updateChildren(dt);
    updateCurrent(dt);
}

void SceneNode::updateChildren(sf::Time dt){
    for (Ptr& child : children)
        child->update(dt);
}

void SceneNode::updateCurrent(sf::Time dt){
    for (Ptr& child : children)
        child->update(dt);
}

void SceneNode::drawChildren(sf::RenderTarget& target, sf::RenderStates states) const{
    for(const Ptr& child : children)
        child->draw(target, states);
}

sf::Transform SceneNode::getWorldTransform() const{
    sf::Transform transform = sf::Transform::Identity;

    for (const SceneNode* node = this; node != nullptr; node = node->parent)
        transform = node->getTransform() * transform;

    return transform;
}

sf::Vector2f SceneNode::getWorldPosition() const{
    return getWorldTransform() * sf::Vector2f();
}

Airplane.h

#ifndef AIRPLANE_H
#define AIRPLANE_H

#include "Entity.h"
#include "ResourceIdentifiers.h"

#include <SFML/Graphics/Sprite.hpp>

class Airplane : public Entity
{
public:
    enum Type{
        Raptor, Eagle,
    };

    Airplane(Type type, const TextureHolder& textures);

private:
    virtual void drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const;

    Type type;
    sf::Sprite sprite;
};

#endif

Airplane.cpp

#include "Airplane.h"

#include "ResourceHolder.h"

Textures::ID toTextureID(Airplane::Type type){
    switch (type){
    case Airplane::Eagle:
        return Textures::Eagle;
    case Airplane::Raptor:
        return Textures::Raptor;
    }
    return Textures::Eagle;
}

Airplane::Airplane(Type _type, const TextureHolder& textures)
    : type(_type), sprite(textures.get(toTextureID(type)))
{
    sf::FloatRect bounds = sprite.getLocalBounds();
    sprite.setOrigin(bounds.width / 2.f, bounds.height / 2.f);
}

void Airplane::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const{
    target.draw(sprite, states);
}

SpriteNode.h

#ifndef SPRITENODE_H
#define SPRITENODE_H

#include "SceneNode.h"
#include <SFML/Graphics/Sprite.hpp>
#include <SFML/Graphics/RenderStates.hpp>
#include <SFML/Graphics/RenderTarget.hpp>

class SpriteNode : public SceneNode
{
    sf::Sprite sprite;

    virtual void drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const;
public:
    explicit SpriteNode(const sf::Texture& texture);
    SpriteNode(const sf::Texture& texture, const sf::IntRect& rect);
};

#endif

SpriteNode.cpp

#include "SpriteNode.h"

SpriteNode::SpriteNode(const sf::Texture& texture) : sprite(texture)
{ }

SpriteNode::SpriteNode(const sf::Texture& texture, const sf::IntRect& rect) : sprite(texture, rect)
{ }

void SpriteNode::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const{
    target.draw(sprite, states);
}

World.h

#ifndef WORLD_H
#define WORLD_H

#include <SFML/System/NonCopyable.hpp>
#include <SFML/Graphics/View.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <array>
#include "ResourceIdentifiers.h"
#include "ResourceHolder.h"
#include "SceneNode.h"
#include "SpriteNode.h"
#include "Airplane.h"

class World : private sf::NonCopyable
{
    enum Layer{
        Background,
        Air,
        LayerCount
    };

    sf::RenderWindow window;
    sf::View worldView;
    TextureHolder textures;
    SceneNode sceneGraph;
    std::array<SceneNode*, LayerCount> sceneLayers;

    sf::FloatRect worldBounds;
    sf::Vector2f spawnPosition;
    float scrollSpeed;
    Airplane* playerAirplane;

    void loadTextures();
    void buildScene();
public:
    explicit World(sf::RenderWindow& window);
    void update(sf::Time dt);
    void draw();
};

#endif

World.cpp

#include "World.h"

World::World(sf::RenderWindow& win) : window(win),
worldView(win.getDefaultView()),
worldBounds(0.f, 0.f, worldView.getSize().x, 2000.f),
spawnPosition(worldView.getSize().x / 2.f, worldBounds.height - worldView.getSize().y / 2.f),
scrollSpeed(-50.f),
playerAirplane(nullptr),
textures()
{
    loadTextures();
    buildScene();

    worldView.setCenter(spawnPosition);
}

void World::loadTextures(){
    textures.load(Textures::Eagle, "D:/SFMLpro/Eagle.png");
    textures.load(Textures::Raptor, "D:/SFMLpro/Raptor.png");
    textures.load(Textures::Desert, "D:/SFMLpro/Desert.png");
}

void World::buildScene(){
    for (std::size_t i = 0; i < LayerCount; ++i){
        SceneNode::Ptr layer(new SceneNode());
        sceneLayers[i] = layer.get();

        sceneGraph.attachChild(std::move(layer));
    }

    sf::Texture& texture = textures.get(Textures::Desert);
    sf::IntRect textureRect(worldBounds);
    texture.setRepeated(true);

    std::unique_ptr<SpriteNode> backgroundSprite(new SpriteNode(texture, textureRect));
    backgroundSprite->setPosition(worldBounds.left, worldBounds.top);
    sceneLayers[Background]->attachChild(std::move(backgroundSprite));

    std::unique_ptr<Airplane> leader(new Airplane(Airplane::Eagle, textures));
    playerAirplane = leader.get();
    playerAirplane->setPosition(spawnPosition);
    playerAirplane->setVelocity(40.f, scrollSpeed);
    sceneLayers[Air]->attachChild(std::move(leader));

    std::unique_ptr<Airplane> leftEscort(new Airplane(Airplane::Raptor, textures));
    leftEscort->setPosition(-80.f, 50.f);
    playerAirplane->attachChild(std::move(leftEscort));

    std::unique_ptr<Airplane> rightEscort(new Airplane(Airplane::Raptor, textures));
    rightEscort->setPosition(80.f, 50.f);
    playerAirplane->attachChild(std::move(leftEscort));
}

void World::draw(){
    window.setView(worldView);
    window.draw(sceneGraph);
}

void World::update(sf::Time dt){
    worldView.move(0.f, scrollSpeed * dt.asSeconds());

    sf::Vector2f position = playerAirplane->getPosition();
    sf::Vector2f velocity = playerAirplane->getVelocity();

    if (position.x <= worldBounds.left + 150 || position.x >= worldBounds.left + worldBounds.width - 150){
        velocity.x = -velocity.x;
        playerAirplane->setVelocity(velocity);
    }

    sceneGraph.update(dt);
}

Game.h

#ifndef GAME_H
#define GAME_H

#include "ResourceHolder.h"
#include "World.h" 
#include <SFML/Graphics/RenderStates.hpp>
#include <SFML/Graphics/RenderTarget.hpp>

class Game{
    sf::RenderWindow window;
    World world;

    void processEvents();
    void update(sf::Time deltaTime);
    void render();

    void handlePlayerInput(sf::Keyboard::Key key, bool isPressed);

public:
    Game();
    void run();
};

#endif

Game.cpp

#include "Game.h"

Game::Game() : window(sf::VideoMode(1600, 900), "SFML"), world(window) {}

void Game::run(){
    sf::Clock clock;
    sf::Time timeSinceLastUpdate = sf::Time::Zero;
    const sf::Time timePerFrame = sf::seconds(1.f / 60.f);

    while (window.isOpen()){
        processEvents();
        timeSinceLastUpdate += clock.restart();
        while (timeSinceLastUpdate > timePerFrame){
            timeSinceLastUpdate -= timePerFrame;
            processEvents();
            update(timePerFrame);
        }
        render();
    }
}

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

void Game::update(sf::Time deltaTime){
    world.update(deltaTime);
}

void Game::render(){
    window.clear();
    world.draw();

    window.setView(window.getDefaultView());
    window.display();
}

void Game::handlePlayerInput(sf::Keyboard::Key key, bool isPressed){}

谢谢

1 个答案:

答案 0 :(得分:4)

很多代码,但是这里

World::World(sf::RenderWindow& win) : window(win)

您要复制sf::RenderWindow,但似乎通过从NonCopyable派生来禁用复制构造函数。

编辑(回复评论):如果您的意思是他要求如何解决,如果他确定sf::RenderWindow的实例在{{1}的生命周期内保持有效,则该成员可以作为参考对象...