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