📄 snake.c
字号:
/* snake - snake.c Copyright (c) 2003 by Linux_Lyb <linux_lyb@sohu.com> ____________________________________________________________________________ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. See the file COPYING in the doc/ directory for more information.*/#include <gdk/gdkkeysyms.h>#include <time.h>#include <stdlib.h>#include "snake.h" static GtkWidget *window = NULL;static GtkWidget *draw_area = NULL;static GdkPixmap *pixmap = NULL;GtkWidget *label;gchar text[64];guint timer = 0;gboolean playing = FALSE;gboolean pauseing = FALSE;She she;Dan dan;//游戏相关变量guint speed = 200;guint level = 1;guint dans = 35;guint live = 3;gboolean play_game (gpointer data);gint my_rand (gint min,gint max){ return rand() % max + min;}//进行蛇身体(不包括头部)的走动void she_zuo (){gint i; for (i=she.changdu;i>0;i--) { she.shengti[i].x = she.shengti[i-1].x; she.shengti[i].y = she.shengti[i-1].y; }}//设置标签的内容void set_label(){ sprintf (text,"egg: %d | live: %d | level: %d",dans,live,level); gtk_label_set_text (GTK_LABEL(label),text);}//画游戏画面void draw(){gint i;//clear all gdk_draw_rectangle (pixmap,window->style->white_gc,TRUE,0, 0, draw_area->allocation.width,draw_area->allocation.height);//draw snake for (i=0;i<=she.changdu;i++) { //g_print ("[%d]%d,%d->",i,she.shengti[i].x,she.shengti[i].y); gdk_draw_rectangle (pixmap,window->style->black_gc,TRUE,she.shengti[i].x * 10,she.shengti[i].y * 10, 10,10); } //draw egg gdk_draw_rectangle (pixmap,window->style->black_gc,TRUE,dan.x * 10,dan.y * 10, 10,10); gtk_widget_queue_draw (draw_area); }//初始化游戏void init_game(){gint i; //蛇的设定 she.changdu = 5; she.shengti[0].x = my_rand (5,20); she.shengti[0].y = my_rand (5,20); she.fangxiang = my_rand (0,4); she.live = TRUE; for (i=1;i<=she.changdu;i++) switch (she.fangxiang) { case SHE_SHANG: she.shengti[i].x = she.shengti[i-1].x; she.shengti[i].y = she.shengti[i-1].y - 1; break; case SHE_XIA: she.shengti[i].x = she.shengti[i-1].x; she.shengti[i].y = she.shengti[i-1].y + 1;; break; case SHE_ZUO: she.shengti[i].x = she.shengti[i-1].x - 1; she.shengti[i].y = she.shengti[i-1].y; break; case SHE_YOU: she.shengti[i].x = she.shengti[i-1].x + 1; she.shengti[i].y = she.shengti[i-1].y; break; default: break; } she.live = TRUE; //蛋的设定 dan.x = my_rand (0,20); dan.y = dan.x; dan.live = TRUE;}//游戏开始void game_start(){ if (timer == 0) timer = g_timeout_add (speed,play_game,NULL);}//暂停游戏void game_pause(GtkWidget *widget){ if (pauseing == FALSE) { if (timer != 0) g_source_remove (timer); timer = 0; gtk_button_set_label (GTK_BUTTON(widget)," Go "); pauseing = TRUE; } else { if (timer == 0) timer = g_timeout_add (speed,play_game,NULL); gtk_button_set_label (GTK_BUTTON(widget),"Pause"); pauseing = FALSE; }}//停止游戏void game_stop(){ playing = FALSE; if (timer != 0) g_source_remove (timer); timer = 0; }gboolean play_game (gpointer data){int i; if (playing == FALSE) { //如果游戏还没开始,初始化游戏并开始 init_game(); set_label(); playing = TRUE; return TRUE; } she_zuo(); switch (she.fangxiang) { case SHE_SHANG: she.shengti[0].y = she.shengti[0].y - 1; //判断是否有向自己身体走的情况,如果有就改变方向 //头部[0]和身体[2]的坐标(x或y)相同,就需要向反方向改变 if (she.shengti[0].y == she.shengti[2].y) { she.fangxiang = SHE_XIA; she.shengti[0].y = she.shengti[0].y + 2; } break; case SHE_XIA: she.shengti[0].y = she.shengti[0].y + 1; if (she.shengti[0].y == she.shengti[2].y) { she.fangxiang = SHE_SHANG; she.shengti[0].y = she.shengti[0].y - 2; } break; case SHE_ZUO: she.shengti[0].x = she.shengti[0].x - 1; if (she.shengti[0].x == she.shengti[2].x) { she.fangxiang = SHE_YOU; she.shengti[0].x = she.shengti[0].x + 2; } break; case SHE_YOU: she.shengti[0].x = she.shengti[0].x + 1; if (she.shengti[0].x == she.shengti[2].x) { she.fangxiang = SHE_ZUO; she.shengti[0].x = she.shengti[0].x - 2; } break; default: break; } //判断蛇的头部是否碰到了自己的身体,如果碰到了就去死! for (i=4;i<=she.changdu;i++) if (she.shengti[0].x == she.shengti[i].x && she.shengti[0].y == she.shengti[i].y) she.live = FALSE; //判断蛇是否碰到边界,如果碰到了就去死! if (she.shengti[0].x < 0 || she.shengti[0].y < 0 || she.shengti[0].x > 40 || she.shengti[0].y > 40) {she.live = FALSE;} //判断蛇是否死了 if (she.live == FALSE) { live = live - 1; if (live == 0) { //没命就GAME OVER speed = 200; level = 1; dans = 20; live = 3; game_stop(); gtk_label_set_text(GTK_LABEL(label)," - Game Over -"); return FALSE; } //还有命就继续 set_label(); init_game(); } //判断蛇是否吃到了蛋,如果吃到了就变长! if (she.shengti[0].x == dan.x && she.shengti[0].y == dan.y) { she.changdu = she.changdu + 1; she.shengti[she.changdu].x = she.shengti[she.changdu-1].x; she.shengti[she.changdu].y = she.shengti[she.changdu-1].y; //重新生成一个蛋 dan.x = my_rand (0,20); dan.y = dan.x; dans = dans - 1; //减少一个蛋 if (dans == 0) { //如果吃完全部的蛋,进入下一局,速度加快 level = level + 1; dans = 20; if (speed > 30) speed = speed - 20; game_stop(); game_start(); } set_label(); } draw(); return TRUE;}static gboolean configure_event (GtkWidget *widget,GdkEventConfigure *event,gpointer data){ if (pixmap) g_object_unref (pixmap); pixmap = gdk_pixmap_new (widget->window, widget->allocation.width,widget->allocation.height,-1); gdk_draw_rectangle (pixmap,widget->style->white_gc,TRUE,0, 0, widget->allocation.width,widget->allocation.height); return TRUE;}static gboolean expose_event(GtkWidget *widget,GdkEventExpose *event,gpointer data){gdk_draw_drawable (widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return TRUE;}//处理按钮事件void key_press (GtkWidget *widget,GdkEventKey *event){ if (playing == TRUE && event->type == GDK_KEY_PRESS) { switch (event->keyval) { case GDK_Up: she.fangxiang = SHE_SHANG; break; case GDK_Down: she.fangxiang = SHE_XIA; break; case GDK_Left: she.fangxiang = SHE_ZUO; break; case GDK_Right: she.fangxiang = SHE_YOU; break; default: break; } }}//退出游戏void quit_game(){ game_stop(); gtk_main_quit(); g_object_unref (pixmap);}void create_window(){GtkWidget *vbox,*hbox;GtkWidget *b_start,*b_pause; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW(window),"TanChiShe Ver 0.3"); //gtk_window_set_resizable (GTK_WINDOW(window),FALSE); gtk_widget_set_usize (window,408,448); gtk_window_set_position (GTK_WINDOW(window),GTK_WIN_POS_CENTER); //gtk_widget_realize (window); gtk_container_set_border_width (GTK_CONTAINER (window), 0); g_signal_connect (GTK_OBJECT(window),"destroy", G_CALLBACK (quit_game),&window); g_signal_connect (GTK_OBJECT(window),"key_press_event", G_CALLBACK (key_press),NULL); vbox = gtk_vbox_new (FALSE,0); gtk_container_add (GTK_CONTAINER(window),vbox); draw_area = gtk_drawing_area_new (); gtk_widget_set_usize (draw_area,400,400); //gtk_widget_set_size_request (draw_area,400,400); g_signal_connect (draw_area, "expose_event", G_CALLBACK (expose_event), NULL); g_signal_connect (draw_area,"configure_event", G_CALLBACK (configure_event), NULL); gtk_box_pack_start (GTK_BOX (vbox), draw_area, TRUE, TRUE, 0); hbox = gtk_hbox_new (FALSE,0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5); b_start = gtk_button_new_with_label ("Start"); gtk_box_pack_start (GTK_BOX (hbox), b_start, FALSE, FALSE, 0); g_signal_connect (b_start,"clicked", G_CALLBACK(game_start),NULL); b_pause = gtk_button_new_with_label ("Pause"); gtk_box_pack_start (GTK_BOX (hbox), b_pause, FALSE, FALSE, 0); g_signal_connect (b_pause,"clicked", G_CALLBACK(game_pause),b_pause); label = gtk_label_new (" - By Linux_Lyb ( linux_lyb@sohu.com )"); gtk_box_pack_start (GTK_BOX (hbox), label, TRUE,TRUE, 0); gtk_widget_show_all (window);}int main(int argc,char *argv[]){ srand (time(NULL)); gtk_init (&argc,&argv); create_window(); gtk_main(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -