如何通过 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 从向量中删除。
我有一个对象容器:
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 从向量中删除。