在这里插入图片描述

使用cairo库进行游戏画面绘制
界面分为游戏人物、路、障碍物,分别定义成结构体,记录坐标,状态,颜色等信息
游戏人物结构体

typedef struct _MAN{
	gint x;
	gint y;
	ManStatus status;
}Man;

对于画面的绘制,没有使用多线程,而是使用单次和循环计时器进行绘制
使用单次定时器绘制开始界面

gboolean start_window(GtkWidget *widget){
	cairo_t *cr;
	cr = gdk_cairo_create (widget->window);
	//background
	cairo_set_source_rgb(cr,0.6,0,0.7);
	cairo_move_to(cr,0, 0);
	cairo_line_to(cr,X_WIDTH,0);
	cairo_line_to(cr,X_WIDTH,X_HEIGHT);
	cairo_line_to(cr,0,X_HEIGHT);
	cairo_stroke_preserve(cr);//save line path,cairo_fill can fill
	cairo_fill(cr);

	//game reference
	//char info[1000] = {'\0'};
	//sprintf(info,"Ctrl to start\nspace to jump\n p to pause/continue\n");
	cairo_set_source_rgb(cr,0.0,0.7,0.3);
	cairo_set_font_size(cr,24);
	cairo_move_to(cr,30, 40);
	cairo_show_text(cr,"Ctrl to start");
	cairo_move_to(cr,30, 90);
	cairo_show_text(cr,"Space to jump");
	cairo_move_to(cr,20, 130);
	cairo_show_text(cr,"p to pause/continue");
	cairo_stroke(cr);

	cairo_destroy(cr);
	//run only once
	return false;
}

游戏分数、时间、速度等信息的绘制

gint score;//游戏分数
gint timeElapse;//游戏时间
gint gameSpeed;//游戏速度


	//time
	char strTime[10] = {'\0'};
	cairo_set_source_rgb(cr,0.4,0.4,0.7);
	cairo_set_font_size(cr,14);
	cairo_move_to(cr,20, 30);
	sprintf(strTime,"Time:%d",timeElapse);
	cairo_show_text(cr,strTime);
	cairo_stroke(cr);

使用定时器实时移动障碍物坐标

gboolean move_obstacle(){
	for(int i = 0;i<5;i++){
		obstacles[i].x -= gameSpeed;
		//if obstacle go end,move it as farest obstacle
		if(obstacles[i].x<0){
			int xMax = 0;
			for(int j =0;j<5;j++){
				if(obstacles[j].x>xMax){
					xMax = obstacles[j].x;
				}
			}
			obstacles[i].x = xMax + rand()%50 +100;
			obstacles[i].r = (float)(rand()%100)/100;
			obstacles[i].g = (float)(rand()%100)/100;
			obstacles[i].b = (float)(rand()%100)/100;
			
			score++;
		}
	}
	if(hit_check()){
		game_over();
	}
	return true;
}

通过按键Ctrl开始游戏,space跳跃,P暂停/继续游戏

void my_key_press(GtkWidget* widget,GdkEventKey *event,gpointer data){

		switch(event->keyval){
		case GDK_KEY_Control_L:
		case GDK_KEY_Control_R:
			game_start();
			break;
		case GDK_KEY_space:
			g_thread_create(man_jump,(void*)&man_0,FALSE,NULL);
			break;
		case GDK_KEY_p:
		case GDK_KEY_P:
			game_pause_continue();
			break;
		}
}

对于按键键值,在gdkkeysyms.h有详细定义

#define GDK_Delete 0xffff
#define GDK_Multi_key 0xff20
#define GDK_Codeinput 0xff37
#define GDK_SingleCandidate 0xff3c
#define GDK_MultipleCandidate 0xff3d
#define GDK_PreviousCandidate 0xff3e
#define GDK_Kanji 0xff21
#define GDK_Muhenkan 0xff22
#define GDK_Henkan_Mode 0xff23
#define GDK_Henkan 0xff23
#define GDK_Romaji 0xff24
#define GDK_Hiragana 0xff25
#define GDK_Katakana 0xff26
#define GDK_Hiragana_Katakana 0xff27
...

编译参数的设置:
使用以下命令获得g++编译gtk程序的参数

pkg-config --cflags --libs gtk+-2.0

另外,使用到g_thread_init函数,因此额外的链接库参数

-lgthread-2.0

游戏有闪烁,使用双缓冲技术可以消除闪烁

源码下载
https://download.csdn.net/download/m0_60352504/87089350

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐