代码之家  ›  专栏  ›  技术社区  ›  JeroenD

带有键盘监听器的游戏循环

  •  0
  • JeroenD  · 技术社区  · 11 年前

    对于我正在制作的C++/OpenGL游戏,我既想要一个键盘输入处理程序,也想要一个持续的屏幕更新,因为游戏中有不断移动的部分。 现在我已经了解到,我可以使用glutKeyboardFunc()作为键盘监听器,使用一个简单的while循环进行持续的屏幕更新(而gameRunning{…})。

    但我如何将两者结合起来,因为如果我使用while循环,那么键监听器永远不会被调用,因为游戏仍然在运行while循环。

    3 回复  |  直到 11 年前
        1
  •  1
  •   Brent Bradburn    11 年前

    This tutorial at Lighthouse3d.com 涵盖你所谈论的一切。

    关键观察:您不使用自己的“while”循环来创建动画。循环内置于函数中 glutMainLoop() ,一旦设置好所有内容,就可以调用它。

        2
  •  0
  •   Community CDub    7 年前

    看来你在找 glutIdleFunc 你会有一个持续的屏幕更新(记得打电话 glutPostRedisplay 在末尾)。虽然您没有固定的时间步长(不能保证以恒定的间隔调用)。必须阅读 fix your timestep .

    我知道,你需要抛弃GLUT,得到一个更好的库,比如SDL或GLFW。

        3
  •  0
  •   rcgldr    11 年前

    您可以使用多个线程,其中一个用于显示,一个用于键盘捕获,另一个用于物理更新。如果物理需要以固定频率运行,这里有一段Windows XP或更高版本的代码,它使用高频计数器,如果有足够的“空闲”时间,就可以休眠:

    typedef unsigned long long UI64;    /* unsigned 64 bit int */
    #define FREQ 400                    /* 400 hz */
    static LARGE_INTEGER liPerfFreq;    /* 64 bit frequency */
    LARGE_INTEGER liPerfTemp;           /* used for query */
    UI64 uFreq = FREQ;                  /* process frequency */
    UI64 uOrig;                         /* original tick */
    UI64 uWait;                         /* tick rate / freq */
    UI64 uRem = 0;                      /* tick rate % freq */
    UI64 uPrev;                         /* previous tick based on original tick */
    UI64 uDelta;                        /* current tick - previous */
    UI64 u2ms;                          /* 2ms of ticks */
    UI64 i;                          
        timeBeginPeriod(1);             /* set period to 1ms */
        Sleep(128);                     /* wait for it to stabilize */
        u2ms = ((UI64)(liPerfFreq.QuadPart)+499) / ((UI64)500);
        QueryPerformanceCounter(&liPerfTemp);
        uOrig = uPrev = liPerfTemp.QuadPart;
        for(i = 0; i < (uFreq*30); i++){
            /* physics step code goes here */
            /* update uWait and uRem based on uRem */
            uWait = ((UI64)(liPerfFreq.QuadPart) + uRem) / uFreq;
            uRem  = ((UI64)(liPerfFreq.QuadPart) + uRem) % uFreq;
            /* wait for uWait ticks */
            while(1){
                QueryPerformanceCounter(&liPerfTemp);
                uDelta = (UI64)(liPerfTemp.QuadPart - uPrev);
                if(uDelta >= uWait)
                    break;
                if((uWait - uDelta) > u2ms)
                    Sleep(1);   /* up to 2ms on win xp */
            }
        }