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

How to animate through an a container for windows.draw()?

我有一个对象容器:

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;

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

#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();
}

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

例如,您可以使用复合 class 来指示应该绘制哪个对象,或者您可以从 sf::Drawable 派生自己的基础 class 并实现 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 以了解有关如何构建游戏和如何构建计时器的一般说明。

或者,您可以保留程序原样,并在您的决策方法中插入 and/or 从向量中删除。