You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:12:31