Question

So I'm trying to work toward developing a platform style game, writing in C and using GTK as my graphical toolkit. Right now I have a program that places three blocks on the screen. Two of them are platforms, and the third can be moved laterally by pressing the left/right arrow keys. (I haven't drawn any sprites yet, so right now the hero of my game is a blue rectangle). I have also implemented jumping by pressing the 'z' key, and you can jump and land on the platforms.

However, moving laterally while jumping is pretty difficult. I believe this is because my program doesn't recognize two keys pressed simultaneously, so you have to release the left or right arrow, press z, and then release z and press the right or left arrow again to move laterally while in the air. I would like to be able to hold left or right and press z simultaneously to have the hero jump laterally.

The GDK reference manual refers you to 'gdk/gdkkeysyms.h' (which on my system is at /usr/include/gtk-3.0/gdk/gdkkeysyms.h) for the list of GDK key codes, but doesn't give any guidance on using two keys simultaneously. Can GTK/GDK recognize an event where two keys are pressed at the same time (GDK, GTK, whichever, I get hazy on where the line between the two is, but I suppose that's a topic for another question...)? How would you apply it? (For a single key you get the code by doing something like

key = event->keyval;

but I don't really know what this would look like for two keys).

Thanks for your help!

Was it helpful?

Solution 2

There are two cases to be aware of.

Some special keys are called modifier keys and these cause a modifier bit to be set in event->state so you might check if (event->state & GDK_CONTROL_MASK) for example.

Only a few common modifiers set a flag in this way. For other keys you will need to track the separate press and release events yourself, which will allow you to determine whether one key is still pressed when another arrives. The widget signals are key-press-event and key-release-event.

There could be other factors causing trouble for you, a good approach is to create a small single-file standalone compilable test case showing the problem. You may figure it out just by making the test case, but if not, a test case will help others help you. (Since they can use it to reproduce the issue.)

OTHER TIPS

keyboard do not work that way: each key generates a separate interrupt, which will generate a separate windowing system event, so you have to keep state yourself.

some keys are effectively special, and act as modifiers of other keys: Control, Shift, Alt, are modifiers, and thus are treated differently — i.e. if they are pressed, their state will be recorded into the event data structure separately from the actual key being pressed. nevertheless, they will generate separate key events as well.

you can simply keep record of a key press, and check later on if the state is maintained, for instance:

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;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top