如何制作一个正确的事件循环(或任何它被称为)?

时间:2014-01-30 00:55:59

标签: c infinite-loop event-loop

我不是程序员或其中任何一个,我只是对这些东西感兴趣的人。

我一直在努力使自己成为一个Xbox 360控制器映射器,将控制器按键转换为模拟键盘按键。原因是我真诚地不喜欢那些人,而且必须付出代价才能获得大部分。承诺,如果我做得足够好,我喜欢我制作的东西,我会免费分发给大家使用。

无论如何,我已经制作了一个有效的命令行版本,但仍然像我希望的那样友好,但仍然做得更好,大多数人都想要它甚至像这样。有一点我不得不问......

由于我不是程序员或任何类型的人,我缺乏经验丰富的教学,除了我从互联网上获得的教学。但是这个我找不到的东西:如何在循环中为程序制作适当的呼吸间隙?也许我应该先问一下,这是不是正确的......

...
while ( 1 ) {
    if ( ( GetAsyncKeyState( keyID ) & 0x8000 ) == 0x8000 ) {
        /* do this, do that */
        break;
    }
    /* breathing */
}
...

......像上面那样的结构?

我假设并且仍然认为它是,因为我不知道如何用这种C语言捕获用户的输入。 知道假设

更好

如果是这样,那么我的主要问题是;如何给程序提供呼吸空间,这样它不会给CPU带来太多压力?换句话说,我应该如何替换上面的/* breathing */部分?我一直在使用Sleep( 20~25 );,我的任务管理器只是一直显示0%的CPU使用率,即使Sleep( 5 )实际上是......

使用睡眠有什么不好吗?还有更好的选择吗?

1 个答案:

答案 0 :(得分:0)

这是一个使用SDL2演示游戏事件循环的相当简单的程序:

#include <SDL.h>
#include <stdio.h>

void on_render(SDL_Window* window, SDL_Renderer* renderer);

int main(int argc, char** argv)
{
    SDL_Window      *mainwindow = NULL;
    SDL_Renderer    *renderer = NULL;
    SDL_Event       event = { 0 };
    int             exit = 0;   // If 1, the event loop will break.

    // INITIALIZE SDL (VIDEO ONLY):
    if(SDL_Init(SDL_INIT_VIDEO) == -1) {
        printf("SDL_Init() failed with \"%s.\"", SDL_GetError());
        return 1;
    }

    // CREATE WINDOW:
    mainwindow = SDL_CreateWindow("SDL2 Application", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN);
    if(!mainwindow) {
        printf("SDL_CreateWindow() failed with \"%s.\"", SDL_GetError());
        return -1;
    }

    // CREATE RENDERER:
    renderer = SDL_CreateRenderer(mainwindow, -1, SDL_RENDERER_ACCELERATED);
    if(!renderer) {
        printf("SDL_CreateRenderer() failed with \"%s.\"", SDL_GetError());
        return -1;
    }

    // MAIN LOOP:
    while(!exit) {

        // EVENT LOOP:
        if(SDL_WaitEvent(&event)) {
            switch(event.type) {
            case SDL_QUIT:
                exit = 1;
                break;
            case SDL_KEYDOWN:
                if(event.key.keysym.sym == SDLK_ESCAPE) exit = 1;
                break;
            case SDL_WINDOWEVENT:
                switch(event.window.event) {
                case SDL_WINDOWEVENT_CLOSE:
                    exit = 1;
                    break;
                }
                break;
            default: break;
            }
        }

        // RENDER SCREEN:
        on_render(mainwindow, renderer);

        // SWAP BUFFERS TO DISPLAY:
        SDL_RenderPresent(renderer);
    }

    // CLEAN-UP:
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(mainwindow);
    SDL_Quit();

    return 0;
}

void on_render(SDL_Window* window, SDL_Renderer* renderer)
{
    int rect_width = 300, rect_height = 300;
    SDL_Rect window_rect = { 0 };

    // CLEAR THE SCREEN WITH A BLUE COLOR:
    SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
    SDL_RenderClear(renderer);

    // DRAW A RECTANGLE:
    SDL_GetWindowSize(window, &window_rect.w, &window_rect.h);

    SDL_Rect draw_rect = {
        (window_rect.x + (window_rect.w / 2) - (rect_width / 2)) - 1,
        (window_rect.y + (window_rect.h / 2) - (rect_height / 2)) - 1,
        rect_width + 2,
        rect_height + 2
    };

    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_RenderFillRect(renderer, &draw_rect);
}

来自Xeek的{​​{1}}在我过去询问事件循环时为我写了这个。

现在,如果你不是在编写游戏,也许你不想消耗所有的CPU时间,在这种情况下简单的

freenode

在最外面的usleep (1); 循环结束之前应该剪切它。

使用你的代码,这是一个例子(恰好依赖于拥有POSIXy系统(Linux,OSX等):

while

编辑:

我们是微秒,而不是毫秒。傻我:)。

相关问题