#flicker #allegro5
#мерцание #allegro5
Вопрос:
Это игровой цикл в моем коде и коде рисования:
float frames_per_second = 60;
display_timer = al_create_timer(1/frames_per_second);
queue = al_create_event_queue();
al_register_event_source(queue, al_get_timer_event_source(display_timer));
al_start_timer(display_timer);
while(!end_game)
{
ALLEGRO_EVENT event;
al_wait_for_event(queue, amp;event);
if(event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) break;
if(event.any.source == al_get_timer_event_source(display_timer))
{update_display();}
update_input();
}
void update_display()
{
al_clear_to_color(al_map_rgb(255, 255,255));
draw_objects(); //this is just an al_draw_bitmap() call
al_flip_display();
}
Анимация, созданная при перемещении объектов на экране, мерцает, я удивлен этим, поскольку я записываю в задний буфер экрана, поэтому я ожидаю двойную буферизацию. Что я могу сделать, чтобы исправить мерцание? Спасибо.
Комментарии:
1. По умолчанию используется двойная буферизация. Можете ли вы опубликовать код чертежа? Бит, который вы указали, действительно не имеет отношения к проблеме.
2. Я обновил сообщение. Мне любопытно, почему игровой цикл не имеет значения? Это то, что контролирует скорость обновления экрана, я подумал, что это, должно быть, проблема с частотой обновления.
3. Это не имеет значения, потому что, если это двойная буферизация, не имеет значения, как быстро вы обновляете экран… вы никогда не получите мерцания. И под мерцанием вы подразумеваете, что экран становится белым на короткую секунду, а затем вы видите объекты? (В отличие от сдвига, когда объекты кажутся разрезанными пополам.) Возможно, вы захотите попробовать
al_set_new_display_option(ALLEGRO_SINGLE_BUFFER, 0, ALLEGRO_REQUIRE);
перед созданием отображения.4. Ну, я могу перемещать изображение на экране с помощью клавиш, и анимация получается неровной. Похоже, что оно замедляется с интервалами. Я попробовал al_set_new_display_option (ALLEGRO_SINGLE_BUFFER, 0, ALLEGRO_REQUIRE); Я не вижу никаких изменений.
5. Хорошо, это другая проблема. Я опубликую ответ, который может помочь.
Ответ №1:
Не имеющее отношения к проблеме, вы можете проверить таймер, выполнив поиск ALLEGRO_EVENT_TIMER
события. Вы можете использовать event.timer.source
, чтобы проверить, какой это таймер, если у вас их несколько.
Я думаю, что основная проблема здесь в том, что вы рисуете графику со скоростью 60 кадров в секунду, но обновляете входные данные с неограниченной скоростью. На самом деле все наоборот. Вы хотите обновлять входные данные с фиксированной скоростью. Вы можете рисовать графику так часто, как вам нравится… хотя нет смысла обновлять графику, если ничего не изменилось.
Так что это должно выглядеть как-то больше похоже:
if(event.type == ALLEGRO_EVENT_TIMER)
{
update_input();
update_display();
}
Однако это не реализует пропуск кадра, если все становится слишком медленным. Что вам следует сделать, так это настроить таймер в выделенной очереди (которая не содержит других источников событий). Затем, пока в этой выделенной очереди таймера находятся события, обновляйте входные данные.
Затем обновите отображение, предполагая, что вы обработали хотя бы один тик. Таким образом, вы можете, если все становится слишком медленным, выполнить несколько обновлений ввода для каждого нарисованного кадра.
Комментарии:
1. Анимация мерцает не так сильно, но она все еще присутствует. Я предполагаю, что использование
al_get_next_event
вместоal_wait_for_event
в этом случае должно быть в порядке. Я заметил увеличение использования памяти сal_wait_for_event
.