[英]Why the program suddenly closes when I hover the cursor in area from 0 to 100 on x axis in allegro
I'm new in allegro and trying to make a small, very basic painting program.我是 allegro 的新手,正在尝试制作一个非常基本的小型绘画程序。 I want this program to stop painting when in the area from A(0, 0) to B(100, 600) on 800x600 plane.
我希望这个程序在 800x600 平面上从 A(0, 0) 到 B(100, 600) 的区域中停止绘画。 When I hover my cursor in this area the program suddenly closes itself.
当我 hover 我的 cursor 在这个区域时,程序突然自行关闭。 Here is the code:
这是代码:
#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;
}
Edit:编辑:
I've found that whenever i hover in that area from (0, 0) to (100, 600) this if statement is being executed:我发现每当我 hover 在从 (0, 0) 到 (100, 600) 的那个区域中执行这个 if 语句时:
if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
I don't know why it is executing.我不知道它为什么会执行。
Let's look at what ALLEGRO_EVENT event
is, via the docs :让我们看看
ALLEGRO_EVENT event
是什么,通过文档:
An
ALLEGRO_EVENT
is a union of all builtin event structures, ie it is an object large enough to hold the data of any event type.ALLEGRO_EVENT
是所有内置事件结构的联合,即它是一个足够大的 object 以容纳任何事件类型的数据。 All events have the following fields in common:所有事件都具有以下共同字段:
type
(ALLEGRO_EVENT_TYPE
)type
(ALLEGRO_EVENT_TYPE
)Indicates the type of event.
表示事件的类型。
[...]
[...]
By examining the
type
field you can then access type-specific fields通过检查
type
字段,您可以访问特定于类型的字段
You can't do stuff that accesses event.keyboard
members if the event.type
is not a keyboard event, because then you're reading from an inactive union member.如果
event.type
不是键盘事件,则不能执行访问event.keyboard
成员的操作,因为那时您正在从非活动的联合成员中读取。 That is undefined behaviour, so speculation is not very useful - but in this case, it looks like you read some bit of a mouse coordinate as if it were a key, but it's not.那是未定义的行为,所以推测不是很有用 - 但在这种情况下,看起来你读取了一些鼠标坐标,就好像它是一个键一样,但事实并非如此。 Results due to UB are meaningless, but it seems that, in this case, they correlated with coordinates to make your code think Esc was pressed.
UB 导致的结果毫无意义,但似乎在这种情况下,它们与坐标相关,使您的代码认为 Esc 被按下。
Check you have a keyboard event type
before reading the keyboard
members:在阅读
keyboard
成员之前检查您是否有键盘事件type
:
if (event.type == ALLEGRO_EVENT_KEY_DOWN &&
event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
{
game_over = true;
}
You need to be extremely careful, anywhere you use a union
, to know any member is valid when you read from it.在使用
union
的任何地方都需要非常小心,以了解任何成员在读取时都是有效的。 About the only real way to be sure is to tag it with a type - and even that requires that you remember to check the type first!唯一真正确定的方法是用类型标记它 - 甚至这要求你记得先检查类型!
A superior way is std::variant
, which lets you check the currently held type or, if casting to it, throws if it doesn't hold that.一种更好的方法是
std::variant
,它可以让您检查当前持有的类型,或者,如果转换为它,则如果它不持有则抛出。 Of course, you can't use that here, unless someone creates a wrapper for ALLEGRO_EVENT
- which you might have time for!当然,你不能在这里使用它,除非有人为
ALLEGRO_EVENT
创建了一个包装器——你可能有时间! - but I mention it to replace union
s in your own code. - 但我提到它是为了替换您自己代码中的
union
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.