C++-通过调用main()函数重新启动游戏

C++ - Restarting a game by calling the main() function

本文关键字:函数 重新启动 游戏 main 调用 C++-      更新时间:2023-10-16

我正在构建一个小游戏。其中一个输入选项是重新启动游戏。我能想到的唯一方法是从主函数中调用主函数

int main(int argc, char argv[]) {
 ...
 if (input == "restart") {
  main(argc, argv);
 }

这种形式不好吗?它会起作用吗?

否,C++标准不允许手动调用main

引用标准(C++11:3.6.1主要功能)

不得在程序中使用功能主体。悬挂机构(3.5)主要是实现定义。将main定义为已删除或将main声明为内联、静态或constexpr的程序是错误的-形成。name main不会以其他方式保留。

不能递归调用main()。这实际上是未定义的行为。

使用循环:

int main() {
     bool restart = false;
     do {
         // Do stuff ...
         // Set restart according some condition inside of the loop
         if(condition == true) {
             restart = true;
         } // (or simplyfied restart = condtion;)
     } while(restart);
}

不要这样做。从…起http://en.cppreference.com/w/cpp/language/main_function

主要功能有几个特殊特性:

1) 它不能在程序中的任何位置使用

a) 特别是,它不能递归地调用

由于递归调用main在C++中是不可能的,也不会真正解决问题,下面是我关于如何处理这个问题的2美分:

基本上,任何大型程序都是一个看起来像这样的循环:

int main()
{
    bool quit = false;
    //Initialise and aquire resources...
    while (!quit)
    {
        //Run game and set quit if user wants to quit...
    }
    //free resources, should be automatic when RAII is adhered.
}

你的游戏应该已经是这样了,因为任何不是循环的程序都会立即退出,不会成为一个游戏。只需将结构更改为:

int main()
{
    bool quit = false;
    bool restart = false;
    while (!quit)
    {   
        Restart = false;
        //Initialise and aquire resources...
        while (!quit && !restart)
        {
            //Run game and update quit and restart according to user input.            
        }
        //free resources, should be automatic when RAII is adhered.
    }
}

您可以使用GOTO,但这通常不是一种好的编程方式。正如那些家伙提到的那样,使用布尔值或循环来检查当前状态或任何其他方式,而不是goto,因为它有时会在编译器中引起问题。然而,它在C中仍然可用,而不是C++(AFAIK)

如果除了重新加载内部资源外,还需要重新加载游戏链接到的库等外部内容,则可以通过在线程中重新启动游戏、分离线程然后关闭来完成此操作。

我在我制作的一个游戏中使用了这个功能,我可以自动更新,以启动新的更新的可执行文件和库。

int main() {
    //initialize the game
    bool restart=false, quit=false;
    while (!quit) {
        //Main loop of the game
    }
    if (restart) {
        #ifdef _WIN32
            std::thread relaunch([](){ system("start SpeedBlocks.exe"); });
        #elif __APPLE__
            std::thread relaunch([](){
                std::string cmd = "open " + resourcePath() + "../../../SpeedBlocks.app";
                system(cmd.c_str());
            });
        #else
            std::thread relaunch([](){ system("./SpeedBlocks"); });
        #endif
        relaunch.detach();
    }
    return 0;
}

有点像黑客,但它能完成任务。#ifdef只是让它使用Windows/Max/Linux的正确启动命令。