Key Valueを確認する


プログラム動作中に、キーボードのキーを叩いた時の応答を確認してみる。

#include <gtk/gtk.h>

static gboolean cb_key_press(GtkWidget *widget, GdkEventKey * event, gpointer user_data)
{
  //keyval,state,stringをキーごとに標準出力からモニター
  g_print("keyval=%d static=%d string=%s\n", event->keyval, event->state, event->string);
  return FALSE;
}

int main(int argc, char** argv)
{
  GtkWidget *window;
  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "Key Value");
  gtk_widget_set_size_request(window, 300, 200);

  //key-press-eventを使う
  g_signal_connect(G_OBJECT(window), "key-press-event", G_CALLBACK(cb_key_press), NULL);
  g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

  gtk_widget_show_all(window);
  gtk_main();

  return 0;
}

 

keyvalの値が、キーごとにモニターされる。この値をメモしておく。


キーの信号を使う


キーボード各キーのkeyvalが分かった所で、 キーボードを叩いたタイミングで、標準出力に表示させてみる。

#include <gtk/gtk.h>

static gboolean cb_key_press(GtkWidget *widget, GdkEventKey * event, gpointer user_data)
{
  //←キーを叩いた時
  if( event->keyval == 65361 ){
    g_print("left\n");
  }
  //↑キーを叩いた時
  if( event->keyval == 65362 ){
    g_print("up\n");
  }
  //→キーを叩いた時
  if( event->keyval == 65363 ){
    g_print("right\n");
  }
  //↓キーを叩いた時
  if( event->keyval == 65364 ){
    g_print("down\n");
  }
  //矢印以外のキーを叩いた時
  if( event->keyval < 123 ){
    g_print( "%s\n", event->string );
  }

  return FALSE;
}

int main(int argc, char** argv)
{
  GtkWidget *window;
  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "Key Value");
  gtk_widget_set_size_request(window, 300, 200);

  g_signal_connect(G_OBJECT(window), "key-press-event", G_CALLBACK(cb_key_press), NULL);
  g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

  gtk_widget_show_all(window);
  gtk_main();

  return 0;
}

サンプルでは矢印キーからはそれぞれleft、right、up、downの文字列、 その他のキーからは文字をそのまま出力させるようにしてみた。


Cairoを使って絵を動かしてみる


再びGDKのCairoを使い、図形(円)を矢印方向へ動かしてみる。

#include <gtk/gtk.h>
#include <gdk/gdk.h>

GtkWidget *window;
cairo_t *cr;
gdouble x = 20.0;
gdouble y = 20.0;
gint i = 0;

static gboolean cb_expose_event(GtkWidget *widget, gpointer data)
{
  //初期位置(20, 20)に円を描く
  cr = gdk_cairo_create(gtk_widget_get_window(widget));
  cairo_set_line_width(cr, 0.0);
  cairo_set_source_rgb(cr, 0.95, 0.95, 0.95);
  cairo_arc(cr, x, y, 20.0, 0.0, 2.0*3.14);
  cairo_stroke_preserve(cr);
  cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
  cairo_fill(cr);
  cairo_destroy(cr);
  return TRUE;
}

static gboolean cb_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
  //移動前の位置を背景色で塗りつぶす
  cr = gdk_cairo_create(gtk_widget_get_window(widget));
  cairo_set_line_width(cr, 1.0);
  cairo_set_source_rgb(cr, 0.95, 0.95, 0.95);
  cairo_arc(cr, x, y, 20.0, 0.0, 2.0*3.14);
  cairo_stroke_preserve(cr);
  cairo_set_source_rgb(cr, 0.95, 0.95, 0.95);
  cairo_fill(cr);
  cairo_destroy(cr);

  //ウィンドウの左端でなければ←キーで左に移動
  if( event->keyval == 65361 && x > 20.0 ){
    x -= 40.0;
  }
  //ウィンドウの上端でなければ↑キーで上に移動
  if( event->keyval == 65362 && y > 20.0 ){
    y -= 40.0;
  }
  //ウィンドウの右端でなければ→キーで右に移動
  if( event->keyval == 65363 && x < 300.0 ){
    x += 40.0;
  }
  //ウィンドウの下端でなければ↓キーで下に移動
  if( event->keyval == 65364 && y < 220.0 ){
    y += 40.0;
  }
  //移動先(x, y)に円を描く
  cr = gdk_cairo_create(gtk_widget_get_window(widget));
  cairo_set_line_width(cr, 0.0);
  cairo_set_source_rgb(cr, 0.95, 0.95, 0.95);
  cairo_arc(cr, x, y, 20.0, 0.0, 2.0*3.14);
  cairo_stroke_preserve(cr);
  cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
  cairo_fill(cr);
  cairo_destroy(cr);
  //移動先の座標を標準出力で表示
  g_print( "x:%f y:%f\n", x, y );
  return FALSE;
}

int main(int argc, char** argv)
{
  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "Key Value");
  gtk_widget_set_size_request(window, 320, 240);

  //初期位置の座標を標準出力で表示
  g_print( "x:%f y:%f\n", x, y );
  //初期位置に円を描く
  g_signal_connect(G_OBJECT(window), "draw", G_CALLBACK(cb_expose_event), NULL);
  //キー操作で円の位置を動かす
  g_signal_connect(G_OBJECT(window), "key-press-event", G_CALLBACK(cb_key_press), NULL);
  g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

  gtk_widget_show_all(window);
  gtk_main();

  return 0;
}

初期位置は(20,20)である。

 

→キーでx方向に40移動し、座標は(60,20)になる。

 

↓キーでy方向に40移動し、座標は(60,60)になる。

 

8章のアニメーションとの合わせ技で、ゲームが作れそうである。 少なくとも人工知能無しであれば、リバーシ(オセロ)くらいはできそうに思える。 もっと技を増やせば、より高度なゲームを作ることができるであろう。


前章  | 目次 |  次章



トップ



/