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

快板5游戏:以恒定速度运行的游戏循环?

  •  5
  • amarillion  · 技术社区  · 15 年前

    在Allegro 5中,最好的方法是什么来编写始终以相同速度运行的游戏循环,并且正确地将绘图逻辑与更新逻辑分开?我是否应该使用线程?我应该使用新的Allegro事件系统吗?

    2 回复  |  直到 12 年前
        1
  •  3
  •   amarillion    12 年前

    摘自Allegro维基:

    al_install_timer(1.0 / FPS);
    
    ...
    
    while (1) {
            al_wait_for_event(queue, &event);
    
            /* handle input events */
    
            if (event.type == ALLEGRO_EVENT_TIMER) {
                    handle_game_tick();
                    need_redraw = true;
            }
    
            if (need_redraw && al_event_queue_is_empty(queue)) {
                    render_last_frame();
                    need_redraw = false;
            }
    }
    

    如果要跳过帧,则在检测到帧落后时(例如,使用al_current_time()函数),跳过render_last_frame()命令。

        2
  •  3
  •   Leftium    14 年前

    Here 是Allefant答案的更完整版本(请按照链接逐行详细解释):

    #include <stdio.h>
    #include <allegro5/allegro.h>
    
    const float FPS = 60;
    
    int main(int argc, char **argv)
    {
       ALLEGRO_DISPLAY *display = NULL;
       ALLEGRO_EVENT_QUEUE *event_queue = NULL;
       ALLEGRO_TIMER *timer = NULL;
       bool redraw = true;
    
       if(!al_init()) {
          fprintf(stderr, "failed to initialize allegro!\n");
          return -1;
       }
    
       timer = al_create_timer(1.0 / FPS);
       if(!timer) {
          fprintf(stderr, "failed to create timer!\n");
          return -1;
       }
    
       display = al_create_display(640, 480);
       if(!display) {
          fprintf(stderr, "failed to create display!\n");
          al_destroy_timer(timer);
          return -1;
       }
    
       event_queue = al_create_event_queue();
       if(!event_queue) {
          fprintf(stderr, "failed to create event_queue!\n");
          al_destroy_display(display);
          al_destroy_timer(timer);
          return -1;
       }
    
       al_register_event_source(event_queue, al_get_display_event_source(display));
    
       al_register_event_source(event_queue, al_get_timer_event_source(timer));
    
       al_clear_to_color(al_map_rgb(0,0,0));
    
       al_flip_display();
    
       al_start_timer(timer);
    
       while(1)
       {
          ALLEGRO_EVENT ev;
          al_wait_for_event(event_queue, &ev);
    
          if(ev.type == ALLEGRO_EVENT_TIMER) {
             redraw = true;
          }
          else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
             break;
          }
    
          if(redraw && al_event_queue_is_empty(event_queue)) {
             redraw = false;
             al_clear_to_color(al_map_rgb(0,0,0));
             al_flip_display();
          }
       }
    
       al_destroy_timer(timer);
       al_destroy_display(display);
       al_destroy_event_queue(event_queue);
    
       return 0;
    }