如何在C++ Allegro中实现文本闪烁且不阻塞程序事件处理
如何在Allegro中实现文本闪烁同时不阻塞事件处理?
我编写了这段代码来实现文本闪烁:
bool running = true; int width = al_get_display_width(display); while (running) { for (;;) { al_clear_to_color(al_map_rgb(255, 255, 255)); al_draw_bitmap(bitmap, 0, 0, 0); al_draw_text(font, al_map_rgb(0, 0, 0), 760, 375, 0, "Play (Spacebar)"); al_flip_display(); al_rest(1.5); al_clear_to_color(al_map_rgb(255, 255, 255)); al_draw_bitmap(bitmap, 0, 0, 0); al_flip_display(); al_rest(0.5); } ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { running = false; } }如您所见,我通过无限循环实现文本闪烁,但该循环会阻塞整个程序,导致窗口关闭等后续事件无法正常处理。请问如何实现文本闪烁的同时,保证窗口关闭等其他功能正常运行?
核心问题在于你用了无限for循环+al_rest(),这俩操作会彻底卡死程序的事件处理流程:al_rest会让线程休眠,而无限循环直接把事件处理代码永远挡在了后面,自然没法响应窗口关闭这类事件。
正确的思路是利用Allegro的事件驱动模型,结合时间戳控制文本的显示/隐藏状态,完全抛弃阻塞式的循环和休眠。具体实现看下面:
修改后的代码示例
bool running = true; int width = al_get_display_width(display); // 控制文本是否显示 bool show_text = true; // 创建60FPS定时器,驱动画面更新和状态检查 ALLEGRO_TIMER* timer = al_create_timer(1.0 / 60.0); al_register_event_source(queue, al_get_timer_event_source(timer)); al_start_timer(timer); // 定义文本显示/隐藏的持续时长(秒) const float show_duration = 1.5f; const float hide_duration = 0.5f; float current_state_duration = show_duration; // 记录上次切换状态的时间点 double last_switch_time = al_get_time(); while (running) { ALLEGRO_EVENT event; // 处理所有待触发的事件,避免程序阻塞 while (al_get_next_event(queue, &event)) { if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { running = false; } else if (event.type == ALLEGRO_EVENT_TIMER) { // 每次定时器触发时,检查是否到了切换文本状态的时间 double current_time = al_get_time(); if (current_time - last_switch_time >= current_state_duration) { show_text = !show_text; last_switch_time = current_time; // 切换对应状态的持续时长 current_state_duration = show_text ? show_duration : hide_duration; } } // 这里可以扩展处理其他事件,比如空格键触发游戏开始 } // 统一绘制逻辑 al_clear_to_color(al_map_rgb(255, 255, 255)); al_draw_bitmap(bitmap, 0, 0, 0); if (show_text) { al_draw_text(font, al_map_rgb(0, 0, 0), 760, 375, 0, "Play (Spacebar)"); } al_flip_display(); } // 记得清理资源 al_destroy_timer(timer);
关键改进说明
- 用定时器替代阻塞休眠:定时器事件会定期触发,既可以驱动画面更新,也能用来检查文本状态切换,完全不会阻塞事件处理流程
- 批量处理事件:用
al_get_next_event循环处理所有待处理的事件,保证窗口关闭、按键输入等操作都能及时响应 - 时间戳控制状态:通过记录上次切换的时间,对比当前时间判断是否需要切换文本显示状态,逻辑清晰且不占用额外资源
- 统一绘制流程:所有绘制操作都放在事件处理之后的主循环里,保证画面流畅更新
这样修改后,文本会按照你想要的1.5秒显示、0.5秒隐藏的节奏闪烁,同时程序能正常响应所有事件。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

