[英]How to simplify game loop with multiple classes
对于我当前的项目,我有几个定义游戏关卡的类。 所有级别均采用以下形式:
class Level1
{
public:
Level1(int initialFrame);
void update(int frameCount, sf::RenderWindow* renderWindow);
void draw(sf::renderWindow* renderWindow);
bool finished;
};
请注意,函数 update 和 draw 的定义在关卡之间都不相同。 在 main 我的循环看起来像这样:
int main()
{
sf::RenderWindow renderWindow();
frames = 0;
progress = 0;
Level1* level1 = new Level1(0);
Level2* level2 = 0;
Level3* level3 = 0;
while (true) // Not actually like this, just put it here to illustrate my point
{
renderWindow.clear()
if (progress == 0)
{
level1->update(frames, &renderWindow)
level1->draw(&renderWindow)
if (level1->finished)
{
delete level1;
progress++;
level2 = new level2(frames);
}
}
if (progress == 1)
{
level2->update(frames, &renderWindow)
level2->draw(&renderWindow)
if (level2->finished)
{
delete level2;
progress++;
level3 = new level3(frames);
}
}
if (progress == 2)
{
level3->update(frames, &renderWindow)
level3->draw(&renderWindow)
if (level3->finished)
{
delete level3;
progress++;
}
}
frames++;
renderWindow.display();
}
}
所以我想简化这一点,因为我有类似的代码块一遍又一遍地运行。 为了解决这个问题,我创建了一个这样的模板:
template <class T>
void loop(T level, int frameCount, sf::RenderWindow* renderWindow, int* progress)
{
level->update(frameCount, renderWindow);
level->draw(renderWindow);
if (level->finished)
{
delete level;
*progress++;
}
}
这部分有效,但我坚持如何,a)在模板中完成一个后初始化下一个级别,以及 b)如何在我的游戏循环中实现模板 function 而不使用检查进度和手动编程在每个级别,就像我以前一样。 理想情况下,我想要一个级别列表,按照我希望它们播放的顺序排列,并且进度可以索引我正在使用循环的哪个级别,但我不确定如何实现它。
您应该制作一个抽象基础 class 级别:
class Level
{
public:
Level(int initialFrame);
virtual ~Level();
virtual void update(int frameCount, sf::RenderWindow* renderWindow) = 0;
virtual void draw(sf::renderWindow* renderWindow) = 0;
bool finished;
};
让你的所有关卡都继承自这个 class:
class Level1 : public Level
{
public:
Level1(int initialFrame);
void update(int frameCount, sf::RenderWindow* renderWindow) override;
void draw(sf::renderWindow* renderWindow) override;
};
然后根据当前进度在它们之间进行交换。
Level* currentLevel = new Level1(0);
...
while (true)
{
currentLevel->update(frames, &renderWindow)
currentLevel->draw(&renderWindow)
if (currentLevel->finished)
{
delete currentLevel;
progress++;
switch(progress)
{
case 1: currentLevel = new Level2(...); break;
case 2: currentLevel = new Level3(...); break;
case 3: currentLevel = new Level4(...); break;
...
}
}
因此,您可以为自己节省一些if
块。
你多虑了。
定义一个由所有关卡实现的关卡接口
class Level {
public:
virtual void update(int frameCount, sf::RenderWindow* renderWindow) = 0;
virtual void draw(sf::renderWindow* renderWindow) = 0;
virtual bool finished() = 0;
};
然后只需创建一个级别队列并从中弹出
auto Levels = std::queue<std::unique_ptr<Level>>();
Levels.push(std::make_unique<Level1>());
Levels.push(std::make_unique<Level2>());
Levels.push(std::make_unique<Level3>());
std::unique_ptr<Level> currentLevel = Levels.front();
Levels.pop();
while(true){
if(currentLevel->finished()){
if(Levels.empty()){
break;
currentLevel = std::move(Levels.front())
Levels.pop();
}
currentLevel->update(frames, &renderWindow)
currentLevel->draw(&renderWindow);
frames++;
renderWindow->display();
}
如果您绝对需要在构建时传递帧,或者您不想提前分配 memory,您可以创建一个函数列表,其中 function 返回std::unique_ptr<Level>
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.