⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snake.c

📁 简单的gtk+环境下的贪吃蛇游戏源码,供学习gtk+入门
💻 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 + -