簡體   English   中英

為什么當我 hover cursor 在快板的 x 軸上從 0 到 100 區域時程序突然關閉

[英]Why the program suddenly closes when I hover the cursor in area from 0 to 100 on x axis in allegro

我是 allegro 的新手,正在嘗試制作一個非常基本的小型繪畫程序。 我希望這個程序在 800x600 平面上從 A(0, 0) 到 B(100, 600) 的區域中停止繪畫。 當我 hover 我的 cursor 在這個區域時,程序突然自行關閉。 這是代碼:

    #include <allegro5/allegro.h>
    #include <allegro5/allegro_native_dialog.h>
    #include <allegro5/allegro_primitives.h>

    #define screen_width 800
    #define screen_height 600

    int main()
    {
        al_init();
        ALLEGRO_DISPLAY* display = al_create_display(screen_width, screen_height);

        al_install_mouse();
        al_install_keyboard();
        al_init_primitives_addon();

        ALLEGRO_EVENT_QUEUE* event_que = al_create_event_queue();
        al_register_event_source(event_que, al_get_display_event_source(display));
        al_register_event_source(event_que, al_get_keyboard_event_source());
        al_register_event_source(event_que, al_get_mouse_event_source());

        bool game_over = false, hold = false;
        int x = 10, y = 10;

        while (!game_over){
            ALLEGRO_EVENT event;
            al_wait_for_event(event_que, &event);

            if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN){
                hold = true;
            }
            if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP){
                hold = false;
            }
            if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE){
                game_over = true;
            }
            if (hold){
                x = event.mouse.x;
                y = event.mouse.y;
                if (x > 100){
                    al_draw_filled_circle(x, y, 4, al_map_rgb(210, 0, 0));
                }
            }

            al_flip_display();
        }

        al_destroy_event_queue(event_que);
        al_destroy_display(display);

        return 0;
    }

編輯:

我發現每當我 hover 在從 (0, 0) 到 (100, 600) 的那個區域中執行這個 if 語句時:

if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)

我不知道它為什么會執行。

讓我們看看ALLEGRO_EVENT event是什么,通過文檔

ALLEGRO_EVENT是所有內置事件結構的聯合,即它是一個足夠大的 object 以容納任何事件類型的數據。 所有事件都具有以下共同字段:

typeALLEGRO_EVENT_TYPE

表示事件的類型。

[...]

通過檢查type字段,您可以訪問特定於類型的字段

如果event.type不是鍵盤事件,則不能執行訪問event.keyboard成員的操作,因為那時您正在從非活動的聯合成員中讀取。 那是未定義的行為,所以推測不是很有用 - 但在這種情況下,看起來你讀取了一些鼠標坐標,就好像它是一個鍵一樣,但事實並非如此。 UB 導致的結果毫無意義,但似乎在這種情況下,它們與坐標相關,使您的代碼認為 Esc 被按下。

在閱讀keyboard成員之前檢查您是否有鍵盤事件type

if (event.type == ALLEGRO_EVENT_KEY_DOWN &&
    event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
{
    game_over = true;
}

在使用union的任何地方都需要非常小心,以了解任何成員在讀取時都是有效的。 唯一真正確定的方法是用類型標記它 - 甚至這要求你記得先檢查類型!

一種更好的方法是std::variant ,它可以讓您檢查當前持有的類型,或者,如果轉換為它,則如果它不持有則拋出。 當然,你不能在這里使用它,除非有人為ALLEGRO_EVENT創建了一個包裝器——你可能有時間! - 但我提到它是為了替換您自己代碼中的union

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM