如何通过windows.draw()的容器动画?

时间:2015-12-20 08:54:02

标签: c++ sfml auto

我有一个容器容器:

std::vector<sf::Drawable> gameObjects;

我的目标是遍历这些对象并绘制它们:

for (auto it : gameObjects)
{
     window.draw(*it);
}

您可以假设这些方法已经实施。我的意思是'animate':我希望一次一个地绘制这些对象,而不是立即绘制。

void Run::render()
{
    window.clear(colorWindow);

    for (auto it : gameObjects)
    {
         window.draw(*it);
    }

    window.display();    
}

也就是说,让每个render()在容器中绘制一个额外的对象。你知道怎么做吗?提前谢谢。

编辑:我尝试了一些非传统的东西 - 我认为这不是一个好习惯,但它有效:

int count = 0;
int countReset = 1;

...

while (countReset > count)
{
    objects.at(count++).draw(window);

}
countReset++;
count = 0;

2 个答案:

答案 0 :(得分:2)

您永远不应该在渲染中对游戏做出决定。你应该在某个地方有一个更新方法,决定输入和时间的传递如何影响你的游戏世界。渲染应该只做一件事:渲染。没有决策,没有数据操作。

例如,您可以使用复合类来指示应该绘制哪个对象,或者您可以从sf :: Drawable派生自己的基类并实现bool IsVisible() const;方法。无论哪种方式,决定是否在其他地方绘制,渲染只执行命令具体呈现的内容:

struct MaybeDrawn
{
   bool IsVisible;
   sf::Drawable Object;      
};

...

std::vector<MaybeDrawn> gameObjects;

...

void Run::render()
{
    window.clear(colorWindow);

    for (auto it : gameObjects)
    {
         if(it->IsVisible)
         {
             window.draw(it->Object);
         }
    }

    window.display();    
}

你的决定,如何以及何时将bool设置为true应该在你的Update / ChangeWorld方法中发生。也许你想看一下here关于如何构建游戏以及如何构建计时器的一般描述。

或者,您可以保留您的程序,并在决策制定方法中插入和/或删除矢量。

答案 1 :(得分:1)

在对象列表中为索引使用静态计数器。如果时间段已过,则测量时间并增加计数器。所以下次在列表中绘制下一个对象。

#include <chrono>

void Run::render()
{
    // actual time
    std::chrono::high_resolution_clock::time_point actTime = std::chrono::high_resolution_clock::now();

    // remember time
    static bool init = false;
    std::chrono::high_resolution_clock::time_point lastTime;
    if ( !init )
    {
        lastTime = actTime;
        init = true;
    }

    // delta time
    long microseconds = std::chrono::duration_cast<std::chrono::duration<long, std::micro> >( actTime - lastTime ).count();
    double deltaTms = ((double)microseconds) / 1000.0;

    window.clear(colorWindow);

    static size_t actObjInx = 0;
    window.draw(gameObjects[actObjInx]);

    // increment object index if time period has elapsed
    if ( deltaTms > 100.0 ) // 0.1 seconds
    {
        lastTime = actTime;

        actObjInx ++;
        if ( actObjInx == gameObjects.size() )
            actObjInx = 0;
    }

    window.display();
}