我这里实现的是基本的贪吃蛇游戏的功能,即蛇可以被自由的操控,吃到食物会变长,撞倒墙或者自己会死亡。
首先介绍一下需要用到的gtk2.0中的一些函数
添加计时器
guint gtk_timeout_add (guint32 interval, GtkFunction function, gpointer data);此函数可以在gtk_main()循环中每隔interval 的时间 调用function。
下面是我的贪吃蛇程序中的使用。每隔200ms 调用draw 函数来刷新界面
*((gint*)user_data) = gtk_timeout_add (200, draw, NULL);
void gtk_timeout_remove (guint timeout_handler_id);删除计时器可以实现蛇的暂停
如
gtk_timeout_remove (*((gint*)user_data));
可以 删除我上面添加的计时器,蛇就可以暂停运动了。
接下来是 添加按键响应,这样就可以用键盘来操作蛇的运动
在文件开头添加这些代码,把键盘上的上下左右 空格 输入 定义为便于识别的名字
#define UP_KEY 0xff52
#define DOWN_KEY 0xff54
#define LEFT_KEY 0xff51
#define RIGHT_KEY 0xff53
#define SPACE_KEY 32
#define ENTER_KEY 0xff0d
void key_press (GtkWidget *widget,
GdkEventKey *event,
gpointer user_data)
在main 函数里添加消息事件(ptimer 是我我新建的计时器,传进这个计时器指针,就可以用键盘来控制蛇的运动与否)
g_signal_connect (window, "key-press-event", G_CALLBACK(key_press), (gpointer)&ptimer);
还有画蛇及食物的函数
gint draw (gpointer data)
{
if (move(NULL) == 1)
{
return 0;
}
g_print ("IN draw head.next = %p\n", head->next);
GdkGC *gc_blue;
GdkGC *gc_red;
GdkGC *gc_white;
gint i;
gint j;
GdkColor color;
//gc_blue = gdk_gc_new(GDK_DRAWABLE(widget->window));
//gc_blue = gdk_gc_new(GDK_DRAWABLE(window->window));
gc_blue = gdk_gc_new(drawareo->window);
color.red = 0;
color.green = 0;
color.blue = 65535;
gdk_gc_set_rgb_fg_color (gc_blue, &color);
//gc_red = gdk_gc_new (GDK_DRAWABLE(widget->window));
//gc_red = gdk_gc_new (GDK_DRAWABLE (window->window));
gc_red = gdk_gc_new (drawareo->window);
color.red = 65535;
color.green = 0;
color.blue = 0;
gdk_gc_set_rgb_fg_color (gc_red, &color);
//gc_white = gdk_gc_new (GDK_DRAWABLE(widget->window));
//gc_white = gdk_gc_new (GDK_DRAWABLE (window->window));
gc_white = gdk_gc_new (drawareo->window);
color.red = 65535;
color.green = 65535;
gdk_gc_set_rgb_fg_color (gc_white, &color);
gdk_draw_rectangle (drawareo->window, gc_white, TRUE, 0, 0, 25*EVERY, 25*EVERY);
//两次 遍历,保证先出现食物
for (i = 0; i < LINE; i++)
{
for (j = 0; j < LINE; j++)
{
if (grid[i][j] == IS_FOOD)
gdk_draw_arc (drawareo->window, gc_red, TRUE, i*EVERY, j*EVERY, EVERY, EVERY, 0, 64*360);
}
}
for (i = 0; i < LINE; i++)
{
for (j = 0; j < LINE; j++)
{
if (grid[i][j] == IS_SNAKE)
gdk_draw_rectangle (drawareo->window, gc_blue, TRUE, i*EVERY, j*EVERY, EVERY, EVERY);
}
}
/*释放*/
if (gc_white)
g_object_unref (G_OBJECT (gc_white));
if (gc_blue)
g_object_unref (G_OBJECT (gc_blue));
if (gc_red)
g_object_unref (G_OBJECT (gc_red));
return 1;
}
我画方为蛇,画圆为食物。
通过添加计时器,程序会在某个时间间隔内调用draw 重新绘制蛇和食物,在draw里我调用了自己写的一个move函数,move函数控制蛇的运动,调用一次便可以使蛇运动一步。我们还需要蛇的数据结构,蛇的一些基本操作(包括食物)。