【问题标题】:SFML C++ drawing a vector of shapesSFML C++ 绘制形状向量
【发布时间】:2017-01-30 18:35:16
【问题描述】:

我刚刚重新开始编码。尝试制作一个简单的突破游戏,我确实开始制作一个简单的“乒乓”游戏,但发现它很容易,所以我试图将它扩展到一个突破游戏(为那些不知道它是什么的人附上图片)。

为了处理屏幕顶部的块,我使用了块向量,现在我正试图将它们绘制到屏幕上。由于出现错误,我无法执行此操作:

错误 C2664: 'void sf::RenderTarget::draw(const sf::Vertex *,size_t,sf::PrimitiveType,const sf::RenderStates &)' : 无法将参数 1 从 'Block' 转换为 'const sf::Drawable &'

block.cpp 文件里面

这里是相关代码,还有更多功能,但不适用于此。很抱歉那里有任何错误的代码:)

block.cpp

Block::Block(float startX, float startY)
{
    position.x = startX;
    position.y = startY;

    colour = sf::Color::White;

    block.setSize(sf::Vector2f(width, height));
    block.setFillColor(colour);
    block.setPosition(position);
}

void Block::draw(Block block, sf::RenderWindow& window)
{
    window.draw(block);
}

blockContainer.cpp

#pragma once

class ContainerOfBlocks
{
public:
    ContainerOfBlocks(int useless);
    ~ContainerOfBlocks();

    std::vector<Block> getContainer();

    void drawContainer(sf::RenderWindow& window);

private:
    std::vector<Block> blockContainer;
};

blockContainer.h

#pragma once

class ContainerOfBlocks
{
public:
    ContainerOfBlocks(int useless);
    ~ContainerOfBlocks();

    std::vector<Block> getContainer();

    void drawContainer(sf::RenderWindow& window);

private:
    std::vector<Block> blockContainer;
};

感谢您的帮助:)

【问题讨论】:

    标签: c++ sfml


    【解决方案1】:

    (我必须把它放在这里,因为我还没有足够的声誉来发表评论)

    一些事情

    • 我不明白你为什么有这个代码void Block::draw(Block block, sf::RenderWindow &amp;window)。它应该是void Block::draw(sf::RenderWindow &amp;window),然后只需绘制block(这是一个类成员)或者如果你想从其他地方绘制块,请通过引用传递block

    • 无论如何,Block 应该继承自sf::Drawable 并使用其函数进行绘制。我认为这就是错误消息所说的。例如class Block : public sf::Drawable { ... }; 和要绘制的函数将是标题中的virtual void draw(sf::RenderTarget &amp;renderTarget, sf::RenderStates renderStates) const; 和.cpp 中的void draw(sf::RenderTarget &amp;renderTarget, sf::RenderStates renderStates) const { renderTarget.draw(block); }。然后你可以迭代你已经拥有的块向量并绘制每个块

    • 函数 std::vector&lt;Block&gt; getContainer() 应该返回对向量的引用 (std::vector&lt;Block&gt; &amp;getContainer())

    • 这不是错误,但我更喜欢使用 #ifndef ... #define... #endif 标头保护而不是 #pragma once

    编辑(关于您在下面的回复):

    我做了一个使用你大部分代码的快速项目。

    (也请务必阅读我在代码下方的注释)

    这是编译后的样子:

    代码:

    block.h

    #ifndef BLOCK_H_INCLUDED
    #define BLOCK_H_INCLUDED
    
    #include <SFML/Graphics.hpp>
    
    class Block : public sf::Drawable {
     public:
      Block();
      Block::Block(float startX, float startY);
      virtual ~Block();
    
     private:
      virtual void draw(sf::RenderTarget &renderTarget, sf::RenderStates renderStates) const;
    
      sf::RectangleShape block;
      sf::Vector2f position;
      float width;
      float height;
      sf::Color colour;
    };
    
    #endif
    

    block.cpp

    #include "block.h"
    
    Block::Block() :
      position(sf::Vector2f()),
      width(40.0f),
      height(20.0f),
      colour(sf::Color())
    {
    }
    
    Block::Block(float startX, float startY) :
      width(40.0f),
      height(20.0f)
    {
      position.x = startX;
      position.y = startY;
    
      colour = sf::Color::White;
    
      block.setSize(sf::Vector2f(width, height));
      block.setFillColor(colour);
      block.setPosition(position);
    }
    
    Block::~Block() {
    }
    
    void Block::draw(sf::RenderTarget &renderTarget, sf::RenderStates renderStates) const {
      renderTarget.draw(block);
    }
    

    blockContainer.h

    #ifndef BLOCKCONTAINER_H_INCLUDED
    #define BLOCKCONTAINER_H_INCLUDED
    
    #include "block.h"
    
    class ContainerOfBlocks : public sf::Drawable {
     public:
      ContainerOfBlocks();
      ContainerOfBlocks(int useless, const sf::Vector2f pos);
      ~ContainerOfBlocks();
    
      std::vector<Block> &getContainer();
      void drawContainer(sf::RenderWindow &window);
    
     private:
      virtual void draw(sf::RenderTarget &renderTarget, sf::RenderStates renderStates) const;
    
      std::vector<Block> blockContainer;
    };
    
    #endif
    

    blockContainer.cpp

    #include "blockContainer.h"
    
    ContainerOfBlocks::ContainerOfBlocks() {
    }
    
    ContainerOfBlocks::ContainerOfBlocks(int useless, const sf::Vector2f pos) {
      if (useless > 0) {
        float x = pos.x;
        float y = pos.y;
        for (std::size_t i = 0; i < static_cast<std::size_t>(useless); ++i) {
          blockContainer.push_back(Block(x, y));
          x += 50.0f;
        }
      }
    }
    
    ContainerOfBlocks::~ContainerOfBlocks() {
    }
    
    std::vector<Block> &ContainerOfBlocks::getContainer() {
      return blockContainer;
    }
    
    void ContainerOfBlocks::drawContainer(sf::RenderWindow &window) {
      for (std::size_t i = 0; i < blockContainer.size(); ++i) {
        window.draw(blockContainer[i]);
      }
    }
    
    void ContainerOfBlocks::draw(sf::RenderTarget &renderTarget, sf::RenderStates renderStates) const {
      for (std::size_t i = 0; i < blockContainer.size(); ++i) {
        renderTarget.draw(blockContainer[i]);
      }
    }
    

    main.cpp

    #include <SFML/Graphics.hpp>
    
    #include "block.h"
    #include "blockContainer.h"
    
    int main() {
      sf::RenderWindow window(sf::VideoMode(400, 200), "SFML works!");
      window.setFramerateLimit(30);
      window.setVerticalSyncEnabled(false);
    
      // create container with 5 blocks in it, starting at pos 10/10
      // this container will be drawn using ContainerOfBlocks' void drawContainer(sf::RenderWindow &window)
      ContainerOfBlocks testBlocks(5, sf::Vector2f(10.0f, 10.0f)); 
    
      // create another container, starting at pos 10/50
      // this one will be drawn using sf::Drawable's function to draw
      ContainerOfBlocks testBlocks2(5, sf::Vector2f(10.0f, 50.0f)); 
    
      while (window.isOpen()) {
        sf::Event evt;
        while (window.pollEvent(evt)) {
          if (evt.type == sf::Event::Closed) {
            window.close();
          }
        }
        window.clear();
        testBlocks.drawContainer(window);
        window.draw(testBlocks2);
        window.display();
      }
    
      return 0;
    }
    

    如您所见,Block 现在继承自 sf::Drawable,可以使用 xxx.draw(block) 进行绘制。

    BlockContainer 现在有两个不同的函数来绘制它的内容(这只是为了演示目的,你只需要一个函数来绘制取决于你更喜欢什么)。如果想保留自己的绘图功能,可以将: public sf::DrawableBlockContainer中去掉。

    main() 中创建了两个块容器,一个(testBlocks)将使用BlockContainervoid drawContainer(sf::RenderWindow &amp;window) 绘制函数从您的原始代码中绘制,另一个(testBlocks2)使用sf::Drawable'秒。

    还要注意&amp;getContainer() 现在如何返回对块向量的引用。如果您不返回引用,则原始向量不会受到您想从外部对其执行的任何操作的影响。

    【讨论】:

    • 好的,我已经编辑了我的代码以包含 sf::Drawable。我添加了在 .h 和 .cpp 中绘制的函数。我不知道如何让它返回对向量的引用,我现在会研究一下。但是当我调用绘图函数时。我实际上在参数中输入了什么?因为它需要 (sf::RenderTarget &renderTarget, sf::RenderStates states) 被覆盖?
    • 我已经想出了如何在没有整个 'sf::Drawable' 的情况下做到这一点。所以我的旧功能很好,我只是犯了一些简单的错误(就像平常一样)。谢谢你的回答:)
    • 谢谢,所以我在输出中看到的内容在屏幕上没有区别。无论我是创建自己的函数还是会看到相同的函数。是的,我没有注意到我的参考文献中的错误。谢谢你:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    相关资源
    最近更新 更多