繁体   English   中英

如何使用多个类简化游戏循环

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM