GDK / GTK可以同时识别两个按键吗?

时间:2013-04-22 03:17:04

标签: gtk gdk

因此,我正在努力开发平台式游戏,用C语言编写并使用GTK作为我的图形工具包。现在我有一个程序在屏幕上放置三个块。其中两个是平台,第三个可以通过按左/右箭头键横向移动。 (我还没画出任何精灵,所以现在我的游戏中的英雄是一个蓝色的矩形)。我也通过按下'z'键来实现跳跃,你可以在平台上跳跃和降落。

然而,在跳跃时横向移动非常困难。我相信这是因为我的程序无法识别同时按下两个键,因此您必须释放左箭头或右箭头,按z,然后释放z并再次按向右或向左箭头以在空中横向移动。我希望能够向左或向右按​​住并同时按下z让英雄横向跳跃。

GDK reference manual指的是'gdk / gdkkeysyms.h'(在我的系统中位于/usr/include/gtk-3.0/gdk/gdkkeysyms.h),以获取GDK密钥代码列表,但是没有给出同时使用两个键的任何指导。 GTK / GDK可以识别出同时按下两个键的事件(GDK,GTK,无论哪个,我对两者之间的线条感到朦胧,但我想这是另一个问题的话题......)?你会怎么样? (对于单个键,您可以通过执行类似

的操作获得代码
key = event->keyval;

但我真的不知道两个键会是什么样子。)

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

键盘不起作用:每个键生成一个单独的中断,这将产生一个单独的窗口系统事件,所以你必须自己保持状态。

某些键实际上是特殊的,并且充当其他键的修饰符:Control,Shift,Alt,是修饰符,因此被区别对待 - 即如果它们被按下,它们的状态将被分别记录到事件数据结构中按下的实际按键。然而,他们也会产生单独的关键事件。

您可以简单地记录按键,然后检查状态是否得到维护,例如:

static gboolean is_a_pressed = FALSE;
static gboolean is_b_pressed = FALSE;

static gboolean on_key_press (GtkWidget *w, GdkEvent *e)
{
  /* acquire key A */
  if (e->key.symbol == GDK_KEY_a)
    is_a_pressed = TRUE;

  /* acquire key B */
  if (e->key.symbol == GDK_KEY_b)
    is_b_pressed = TRUE;

  /* both keys have been pressed */
  if (is_a_pressed && is_b_pressed)
    do_something_amazing ();

  /* let the event propagate further */
  return GDK_EVENT_PROPAGATE;
}

static gboolean on_key_release (GtkWidget *w, GdkEvent *e)
{
  /* release key A */
  if (e->key.symbol == GDK_KEY_a)
    is_a_pressed = FALSE;

  /* release key B */
  if (e->key.symbol == GDK_KEY_b)
    is_b_pressed = FALSE;

  return GDK_EVENT_PROPAGATE;
}

答案 1 :(得分:1)

有两种情况需要注意。

某些特殊键称为修饰键,这些键会导致在event->state中设置修饰符位,因此您可以检查if (event->state & GDK_CONTROL_MASK)

只有少数常用修饰符以这种方式设置标志。对于其他按键,您需要自己跟踪单独的按下和释放事件,这将允许您确定当另一个按键到达时是否仍按下一个按键。 小部件信号是按键事件和按键释放事件。

可能有其他因素给您带来麻烦,一个好方法是创建一个小型单文件独立可编译测试用例来显示问题。您可以通过制作测试用例来解决问题,但如果没有,测试用例将帮助其他人帮助您。 (因为他们可以用它来重现问题。)