LVGL|基于lvgl编写2048游戏(纯c语言实现)

LVGL(轻巧而多功能的图形库)是一个免费的开放源代码图形库,它提供创建具有易于使用的图形元素,精美的视觉效果和低内存占用的嵌入式GUI所需的一切。本游戏的视觉效果基于lvgl实现,lvgl中文教程(中文手册)http://lvgl.100ask.net

游戏说明

《2048》 是一款比较流行的数字游戏,最早于2014年3月20日发行。原版2048首先在GitHub上发布,原作者是Gabriele Cirulli,后被移植到各个平台。

这由20岁的Gabriele Cirulli开发的一款数字游戏。初衷就是觉得好玩,在将其开源版本放到GitHub上后,意外走红。
这款游戏的玩法很简单,每次可以选择上下左右滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢,系统也会在空白的地方乱数出现一个数字方块,相同数字的方块在靠拢、相撞时会相加。不断的叠加最终拼凑出2048这个数字就算成功。

实验成果

每次可以选择上下左右滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢,系统也会在空白的地方乱数出现一个数字方块,相同数字的方块在靠拢、相撞时会相加。不断的叠加最终拼凑出2048这个数字就算成功。
2048

游戏代码

实现代码比较简单,我使用一个结构体管理所有的数据结构,lvgl提供的事件管理器使我能很好的实现触摸事件处理部分;游戏界面一共有16个方格,我使用一个二维数组进行管理。详细代码如下所示,关于代码的详细讲解请查看我的下一篇文章介绍。

/*********************
 *      DEFINES
 *********************/
/* 大小 */
#define SIZE 4

/* 布局 */
#define LV_100ASK_2048_GAME_BOX_W			(260)
#define LV_100ASK_2048_GAME_BOX_H			(260)
#define LV_100ASK_2048_NUMBER_BOX_W			(55)
#define LV_100ASK_2048_NUMBER_BOX_H			(55)
#define LV_100ASK_2048_CURRENT_SCORE_W		(65)
#define LV_100ASK_2048_CURRENT_SCORE_H		(35)
#define LV_100ASK_2048_BEST_SCORE_W			(65)
#define LV_100ASK_2048_BEST_SCORE_H			(35)

/* 颜色 */
#define LV_100ASK_2048_GAME_BG_COLOR 		lv_color_hex(0xe8e5db) //LV_COLOR_MAKE(0xCD, 0xC1, 0xB4)
#define LV_100ASK_2048_GAME_BOX_COLOR 		lv_color_hex(0xBBADA0)
#define LV_100ASK_2048_NUMBER_BOX_COLOR 	lv_color_hex(0xCDC1B4)
#define LV_100ASK_2048_NUMBER_2_COLOR 		lv_color_hex(0xeee4da)
#define LV_100ASK_2048_NUMBER_4_COLOR 		lv_color_hex(0xeee1c9)
#define LV_100ASK_2048_NUMBER_8_COLOR 		lv_color_hex(0xf3b27a)
#define LV_100ASK_2048_NUMBER_16_COLOR 		lv_color_hex(0xf69664)
#define LV_100ASK_2048_NUMBER_32_COLOR 		lv_color_hex(0xf77c5f)
#define LV_100ASK_2048_NUMBER_64_COLOR 		lv_color_hex(0xf75f3b)
#define LV_100ASK_2048_NUMBER_128_COLOR 	lv_color_hex(0xedd073)
#define LV_100ASK_2048_NUMBER_256_COLOR 	lv_color_hex(0xEDCC61)
#define LV_100ASK_2048_NUMBER_512_COLOR 	lv_color_hex(0xEDCC61)
#define LV_100ASK_2048_NUMBER_1024_COLOR 	lv_color_hex(0xEDCC61)
#define LV_100ASK_2048_NUMBER_2048_COLOR 	lv_color_hex(0xEDC22E)


/**********************
 *      TYPEDEFS
 **********************/
typedef struct _lv_100ask_2048_game {
    
    
	lv_obj_t * bg;					/* 背景 */
	lv_obj_t * canvas_stage;		/* 游戏舞台 */
	lv_obj_t * label_best_score;	/* 展示最高分数 */
	lv_obj_t * label_current_score;	/* 展示当前分数 */
	lv_task_t * task_handle;		/* 任务句柄 */
									 
	uint8_t game_board[SIZE][SIZE];	/* 2048矩阵 */
	uint32_t current_score_value;	/* 当前分数 */
	bool play_game;					/* 游戏状态 */
} T_lv_100ask_2048_game, *PT_lv_100ask_2048_game;

/**********************
 *  STATIC VARIABLES
 
 **********************/
static PT_lv_100ask_2048_game g_pt_lv_100ask_2048_game;  // 数据结构体


/**********************
 *  STATIC PROTOTYPES
 **********************/
static void lv_100ask_game_2048_init(void);
static lv_obj_t * add_title(lv_obj_t * obj_space, const char * txt);
static void initBoard(lv_obj_t * parent, uint8_t board[SIZE][SIZE]);
static void initBoardNumber(uint8_t board[SIZE][SIZE]);
static void drawBoard(lv_obj_t * parent, char * number, \
							 uint16_t canvas_w, uint16_t canvas_h, \
							 uint16_t rect_dsc_x, uint16_t rect_dsc_y, \
							 lv_color_t rgb32);

static void addRandom(uint8_t board[SIZE][SIZE]);
static lv_color_t Num2Color(uint32_t num);
static uint8_t findTarget(uint8_t array[SIZE],uint8_t x,uint8_t stop);
static bool slideArray(uint8_t array[SIZE]);
static void rotateBoard(uint8_t board[SIZE][SIZE]);
static bool moveUp(uint8_t board[SIZE][SIZE]);
static bool moveLeft(uint8_t board[SIZE][SIZE]);
static bool moveDown(uint8_t board[SIZE][SIZE]);
static bool moveRight(uint8_t board[SIZE][SIZE]);
static bool findPairDown(uint8_t board[SIZE][SIZE]);
static uint8_t countEmpty(uint8_t board[SIZE][SIZE]);
static bool gameEnded(uint8_t board[SIZE][SIZE]);
static char* Int2String(int num, char *str);

// 事件
static void event_handler_play_2048(lv_obj_t * obj, lv_event_t event);
static void event_handler_2048_game_up(lv_obj_t * obj, lv_event_t event);
static void event_handler_2048_game_down(lv_obj_t * obj, lv_event_t event);
static void event_handler_2048_game_left(lv_obj_t * obj, lv_event_t event);
static void event_handler_2048_game_right(lv_obj_t * obj, lv_event_t event);



void lv_100ask_game_2048(void)
{
    
    
	/* 申请内存 */
	g_pt_lv_100ask_2048_game = (T_lv_100ask_2048_game *)malloc(sizeof(T_lv_100ask_2048_game));

	/* 初始化桌面背景 */
	g_pt_lv_100ask_2048_game->bg = lv_obj_create(lv_scr_act(), NULL);
	lv_obj_set_size(g_pt_lv_100ask_2048_game->bg, LV_HOR_RES, LV_VER_RES);
	lv_obj_set_y(g_pt_lv_100ask_2048_game->bg, 0);

	/* 初始化游戏舞台 */
	g_pt_lv_100ask_2048_game->canvas_stage = lv_obj_create(g_pt_lv_100ask_2048_game->bg, NULL);
    lv_obj_set_style_local_radius(g_pt_lv_100ask_2048_game->canvas_stage, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 0); // 设置圆角
    lv_obj_set_style_local_bg_color(g_pt_lv_100ask_2048_game->canvas_stage, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_100ASK_2048_GAME_BOX_COLOR); //设置颜色
	lv_obj_set_size(g_pt_lv_100ask_2048_game->canvas_stage, LV_100ASK_2048_GAME_BOX_W, LV_100ASK_2048_GAME_BOX_H);
	lv_obj_align(g_pt_lv_100ask_2048_game->canvas_stage, NULL, LV_ALIGN_IN_TOP_MID, 0, LV_100ASK_2048_NUMBER_BOX_H);

	/* 初始化主界面 */
	g_pt_lv_100ask_2048_game->play_game = true;
	g_pt_lv_100ask_2048_game->current_score_value = 0;
	lv_100ask_game_2048_init();


	/* 分配屏幕触摸事件处理 */
	lv_obj_set_click(lv_layer_top(), true);
	lv_obj_set_event_cb(lv_layer_top(), event_handler_play_2048);

	/* 创建app标题 */
	add_title(g_pt_lv_100ask_2048_game->bg, "2048 GAME");

}


// 添加标题
static lv_obj_t * add_title(lv_obj_t * obj_space, const char * txt)
{
    
    
    // 添加标题
	lv_obj_t * title = lv_label_create(obj_space, NULL);
	lv_obj_set_style_local_text_color(title, LV_OBJ_PART_MAIN, LV_STATE_PRESSED, LV_COLOR_WHITE);
	lv_obj_set_style_local_text_font(title, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, &lv_font_montserrat_32);
    lv_label_set_text(title, txt);
    lv_obj_align(title, NULL, LV_ALIGN_IN_TOP_MID, 0,
            LV_100SK_STM32F103_DEMO_TITLE_PAD);
    return title;
}


static void lv_100ask_game_2048_init(void)
{
    
    
	/* 游戏说明 */
	lv_obj_t * game_title = lv_label_create(g_pt_lv_100ask_2048_game->bg, NULL);
	lv_obj_set_style_local_text_font(game_title, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, &lv_font_montserrat_32);             // 设置文字大小
	lv_label_set_recolor(game_title, true); 					 /*Enable re-coloring by commands in the text*/
	lv_label_set_align(game_title, LV_ALIGN_IN_LEFT_MID);		 /*Center aligned lines*/
	lv_obj_align(game_title, g_pt_lv_100ask_2048_game->canvas_stage, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
	lv_label_set_text(game_title, "#776e65 2048# ");

	lv_obj_t * game_tutorial = lv_label_create(g_pt_lv_100ask_2048_game->bg, NULL);
	lv_label_set_align(game_tutorial, LV_ALIGN_OUT_TOP_LEFT);		 /*Center aligned lines*/
	lv_obj_align(game_tutorial, game_title, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
	lv_label_set_text(game_tutorial, "Join the tiles, \nget to 2048!\n");
	//lv_label_set_text(game_tutorial, "合并色块,得出更大的数字!");
	lv_obj_set_width(game_tutorial, 200);

	/* LOGO */
    LV_IMG_DECLARE(img_lv_100ask_demo_logo);
    lv_obj_t * logo = lv_img_create(g_pt_lv_100ask_2048_game->bg, NULL);
    lv_img_set_src(logo, &img_lv_100ask_demo_logo);
	lv_obj_align(logo, game_tutorial,  LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);  //(lv_obj_get_width(logo)/4)

	/* 公司信息 */
    lv_obj_t * label_logo = lv_label_create(g_pt_lv_100ask_2048_game->bg, NULL);
	lv_obj_set_style_local_text_font(label_logo, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, &lv_font_montserrat_10);             // 设置文字大小
    lv_label_set_text(label_logo,  "www.100ask.net\nwww.lvgl.100ask.net");
    lv_obj_align(label_logo, logo, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);

	/* 最高记录显示区域 */
	lv_obj_t * obj_best_source = lv_obj_create(g_pt_lv_100ask_2048_game->bg, NULL);
	lv_obj_set_size(obj_best_source, 65, 35);
	lv_obj_align(obj_best_source, g_pt_lv_100ask_2048_game->canvas_stage, LV_ALIGN_OUT_BOTTOM_RIGHT,0, 0);

	/* 最高记录标题 */
	lv_obj_t * best_source_tip_text  = lv_label_create(obj_best_source, NULL); /* 创建标签 */
	lv_label_set_text(best_source_tip_text, "BEST");
	lv_obj_align(best_source_tip_text, NULL, LV_ALIGN_IN_TOP_MID, 0, 0);  /* 居中 */

	/* 最高记录分数 */
	g_pt_lv_100ask_2048_game->label_best_score = lv_label_create(obj_best_source, NULL); /* 创建标签 */
	lv_label_set_text(g_pt_lv_100ask_2048_game->label_best_score, "4096");
	lv_obj_align(g_pt_lv_100ask_2048_game->label_best_score, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);  /* 居中 */

	/* 当前分数显示区域 */
	lv_obj_t * obj_current_source = lv_obj_create(g_pt_lv_100ask_2048_game->bg, NULL);
	lv_obj_set_size(obj_current_source, 65, 35);
	lv_obj_align(obj_current_source, obj_best_source, LV_ALIGN_OUT_BOTTOM_MID, 0, (lv_obj_get_height(obj_best_source)/2));

	/* 当前分提示 */
	lv_obj_t *  current_source_tip_text  = lv_label_create(obj_current_source, NULL); /* 创建标签 */
	lv_label_set_text(current_source_tip_text, "SORCE");
	lv_obj_align(current_source_tip_text, NULL, LV_ALIGN_IN_TOP_MID, 0, 0);           /* 居中 */

	/* 当前分数 */
	g_pt_lv_100ask_2048_game->label_current_score = lv_label_create(obj_current_source, NULL);         /* 创建标签 */
	lv_label_set_text(g_pt_lv_100ask_2048_game->label_current_score, "0");
	lv_obj_align(g_pt_lv_100ask_2048_game->label_current_score, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);   /* 当前画布居中 */

	/* 初始化游戏数字 */
	initBoardNumber(g_pt_lv_100ask_2048_game->game_board);

	/* 初始化游戏舞台中的每个方格块 */
	initBoard(g_pt_lv_100ask_2048_game->canvas_stage, g_pt_lv_100ask_2048_game->game_board);
}




static void initBoard(lv_obj_t * parent, uint8_t board[SIZE][SIZE])
{
    
    
	/* 清除之前所有的子对象 */
    lv_obj_clean(parent);

	/* 当前分数 */
	char str_current_score[8] = {
    
    0};
	lv_label_set_text(g_pt_lv_100ask_2048_game->label_current_score, Int2String(g_pt_lv_100ask_2048_game->current_score_value, str_current_score));

	for(int y = 0; y < SIZE; y++)
	{
    
    
		for(int x = 0; x < SIZE; x++)
		{
    
    
			if (board[x][y]!=0) {
    
    
				//sprintf(tmp_char, "%d", board[x][y]);
				char tmp_char[8];
				snprintf(tmp_char, 8, "%u", (uint32_t)1<<board[x][y]);
				drawBoard(parent, tmp_char,\
						  LV_100ASK_2048_NUMBER_BOX_W, LV_100ASK_2048_NUMBER_BOX_H, \
						  (8*(y+1))+(LV_100ASK_2048_NUMBER_BOX_W*(y+1-1)), (8*(x+1))+(LV_100ASK_2048_NUMBER_BOX_W*(x+1-1)), Num2Color((uint32_t)1<<board[x][y]));
			}
			else {
    
    
				drawBoard(parent, "",\
						  LV_100ASK_2048_NUMBER_BOX_W, LV_100ASK_2048_NUMBER_BOX_H, \
						  (8*(y+1))+(LV_100ASK_2048_NUMBER_BOX_W*(y+1-1)), (8*(x+1))+(LV_100ASK_2048_NUMBER_BOX_W*(x+1-1)), LV_100ASK_2048_NUMBER_BOX_COLOR);
			}
		}
	}
}


static void drawBoard(lv_obj_t * parent, char * number, \
							 uint16_t canvas_w, uint16_t canvas_h, \
							 uint16_t rect_dsc_x, uint16_t rect_dsc_y, \
							 lv_color_t rgb32)
{
    
    

    /* 创建方格块 */
    lv_obj_t * obj = lv_obj_create(parent, NULL);
    lv_obj_set_size(obj, canvas_w, canvas_h);
    lv_obj_set_style_local_bg_color(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, rgb32);
    lv_obj_set_style_local_bg_opa(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_COVER);
    lv_obj_set_style_local_radius(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 0); // 设置圆角
    lv_obj_set_style_local_border_opa(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_0); // 边框透明度
	lv_obj_set_style_local_text_font(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, &lv_font_montserrat_22); // 字体大小

	//lv_obj_set_event_cb(obj, event_handler_play_2048);  /* 分配事件处理 */
	//lv_obj_set_gesture_parent(obj, false);
	//lv_obj_set_click(obj, true);
	lv_obj_align(obj, NULL, LV_ALIGN_IN_TOP_LEFT, rect_dsc_x, rect_dsc_y);

	/* 数字 */
	lv_obj_t * icon  = lv_label_create(obj, NULL); /* 创建标签 */
	lv_label_set_text(icon, number);
	lv_obj_align(icon, NULL, LV_ALIGN_CENTER, 0, 0);  /* 当前画布居中 */

}



// 10进制
static char* Int2String(int num, char *str)
{
    
    
	int i = 0;//指示填充str
	if(num<0)//如果num为负数,将num变正
	{
    
    
		num = -num;
		str[i++] = '-';
	}
	//转换
	do
	{
    
    
		str[i++] = num%10+48;//取num最低位 字符0~9的ASCII码是48~57;简单来说数字0+48=48,ASCII码对应字符'0'
		num /= 10;//去掉最低位
	}while(num);//num不为0继续循环

	str[i] = '\0';

	//确定开始调整的位置
	int j = 0;
	if(str[0]=='-')//如果有负号,负号不用调整
	{
    
    
		j = 1;//从第二位开始调整
		++i;//由于有负号,所以交换的对称轴也要后移1位
	}
	//对称交换
	for(;j<i/2;j++)
	{
    
    
		//对称交换两端的值 其实就是省下中间变量交换a+b的值:a=a+b;b=a-b;a=a-b;
		str[j] = str[j] + str[i-1-j];
		str[i-1-j] = str[j] - str[i-1-j];
		str[j] = str[j] - str[i-1-j];
	}

	return str;//返回转换后的值
}


static void initBoardNumber(uint8_t board[SIZE][SIZE]) {
    
    
	uint8_t x,y;
	for (x=0;x<SIZE;x++) {
    
    
		for (y=0;y<SIZE;y++) {
    
    
			board[x][y]=0;
		}
	}

	/* 初始化两个随机位置的随机数 */
	addRandom(board);
	addRandom(board);

	g_pt_lv_100ask_2048_game->current_score_value = 0;
}


static void addRandom(uint8_t board[SIZE][SIZE]) {
    
    
	static bool initialized = false;
	uint8_t x,y;
	uint8_t r,len=0;
	uint8_t n,list[SIZE*SIZE][2];

	if (!initialized) {
    
    
		srand(time(NULL));
		initialized = true;
	}

	for (x=0;x<SIZE;x++) {
    
    
		for (y=0;y<SIZE;y++) {
    
    
			if (board[x][y]==0) {
    
    
				list[len][0]=x;
				list[len][1]=y;
				len++;
			}
		}
	}

	if (len>0) {
    
    
		r = rand()%len;
		x = list[r][0];
		y = list[r][1];
		n = (rand()%10)/9+1;
		board[x][y]=n;
	}
}


static lv_color_t Num2Color(uint32_t num){
    
    
	switch (num)
	{
    
    
	case 2:		return LV_100ASK_2048_NUMBER_2_COLOR;
	case 4:		return LV_100ASK_2048_NUMBER_4_COLOR;
	case 8:		return LV_100ASK_2048_NUMBER_8_COLOR;
	case 16:	return LV_100ASK_2048_NUMBER_16_COLOR;
	case 32:	return LV_100ASK_2048_NUMBER_32_COLOR;
	case 64:	return LV_100ASK_2048_NUMBER_64_COLOR;
	case 128:	return LV_100ASK_2048_NUMBER_128_COLOR;
	case 256:	return LV_100ASK_2048_NUMBER_256_COLOR;
	case 512:	return LV_100ASK_2048_NUMBER_512_COLOR;
	case 1024:	return LV_100ASK_2048_NUMBER_1024_COLOR;
	case 2048:	return LV_100ASK_2048_NUMBER_2048_COLOR;
	default:	return LV_100ASK_2048_NUMBER_2048_COLOR;
	}

}


static uint8_t findTarget(uint8_t array[SIZE],uint8_t x,uint8_t stop) {
    
    
	uint8_t t;
	// if the position is already on the first, don't evaluate
	if (x == 0) {
    
    
		return x;
	}
	for(t = (x - 1) ;; t--) {
    
    
		if (array[t]!=0) {
    
    
			if (array[t] != array[x]) {
    
    
				// merge is not possible, take next position
				return (t + 1);
			}
			return t;
		} else {
    
    
			// we should not slide further, return this one
			if (t == stop) {
    
    
				return t;
			}
		}
	}
	// we did not find a
	return x;
}

static bool slideArray(uint8_t array[SIZE]) {
    
    
	bool success = false;
	uint8_t x, t, stop = 0;

	for (x = 0; x < SIZE; x++) {
    
    
		if (array[x] != 0) {
    
    
			t = findTarget(array,x,stop);
			// if target is not original position, then move or merge
			if (t != x) {
    
    
				// if target is zero, this is a move
				if (array[t]==0) {
    
    
					array[t]=array[x];
				} else if (array[t]==array[x]) {
    
    
					// merge (increase power of two)
					array[t]++;
					// increase score
					g_pt_lv_100ask_2048_game->current_score_value+=(uint32_t)1<<array[t];
					// set stop to avoid double merge
					stop = t+1;
				}
				array[x]=0;
				success = true;
			}
		}
	}
	return success;
}


static void rotateBoard(uint8_t board[SIZE][SIZE]) {
    
    
	uint8_t i,j,n=SIZE;
	uint8_t tmp;
	for (i=0; i<n/2; i++) {
    
    
		for (j=i; j<n-i-1; j++) {
    
    
			tmp = board[i][j];
			board[i][j] = board[j][n-i-1];
			board[j][n-i-1] = board[n-i-1][n-j-1];
			board[n-i-1][n-j-1] = board[n-j-1][i];
			board[n-j-1][i] = tmp;
		}
	}
}


static bool moveUp(uint8_t board[SIZE][SIZE]) {
    
    
	bool success = false;
	uint8_t x;
	for (x=0;x<SIZE;x++) {
    
    
		success |= slideArray(board[x]);
	}
	return success;
}


static bool moveLeft(uint8_t board[SIZE][SIZE]) {
    
    
	bool success;
	rotateBoard(board);
	success = moveUp(board);
	rotateBoard(board);
	rotateBoard(board);
	rotateBoard(board);
	return success;
}


static bool moveDown(uint8_t board[SIZE][SIZE]) {
    
    
	bool success;
	rotateBoard(board);
	rotateBoard(board);
	success = moveUp(board);
	rotateBoard(board);
	rotateBoard(board);
	return success;
}


static bool moveRight(uint8_t board[SIZE][SIZE]) {
    
    
	bool success;
	rotateBoard(board);
	rotateBoard(board);
	rotateBoard(board);
	success = moveUp(board);
	rotateBoard(board);
	return success;
}


static bool findPairDown(uint8_t board[SIZE][SIZE]) {
    
    
	bool success = false;
	uint8_t x,y;
	for (x=0;x<SIZE;x++) {
    
    
		for (y=0;y<SIZE-1;y++) {
    
    
			if (board[x][y]==board[x][y+1]) return true;
		}
	}
	return success;
}


static uint8_t countEmpty(uint8_t board[SIZE][SIZE]) {
    
    
	uint8_t x,y;
	uint8_t count=0;
	for (x=0;x<SIZE;x++) {
    
    
		for (y=0;y<SIZE;y++) {
    
    
			if (board[x][y]==0) {
    
    
				count++;
			}
		}
	}
	return count;
}


static bool gameEnded(uint8_t board[SIZE][SIZE]) {
    
    
	bool ended = true;
	if (countEmpty(board)>0) return false;
	if (findPairDown(board)) return false;
	rotateBoard(board);
	if (findPairDown(board)) ended = false;
	rotateBoard(board);
	rotateBoard(board);
	rotateBoard(board);
	return ended;
}



/* 触摸屏检测 */
static void event_handler_play_2048(lv_obj_t * obj, lv_event_t event)
{
    
    
	if (event == LV_EVENT_GESTURE)
	{
    
    
		bool success = false;
		printf("		 GAME BEGIN!			\n\r");
		switch(lv_indev_get_gesture_dir(lv_indev_get_act()))
		{
    
    
			case LV_GESTURE_DIR_TOP:
				printf("LV_GESTURE_DIR_TOP.\n\r");
				success = moveLeft(g_pt_lv_100ask_2048_game->game_board); break;
			case LV_GESTURE_DIR_BOTTOM:
				printf("LV_GESTURE_DIR_BOTTOM.\n\r");
				success = moveRight(g_pt_lv_100ask_2048_game->game_board); break;
			case LV_GESTURE_DIR_RIGHT:
				printf("LV_GESTURE_DIR_RIGHT.\n\r");
				success = moveDown(g_pt_lv_100ask_2048_game->game_board); break;
			case LV_GESTURE_DIR_LEFT:
				printf("LV_GESTURE_DIR_LEFT.\n\r");
				success = moveUp(g_pt_lv_100ask_2048_game->game_board); break;
			default: success = false;
		}
		if (success)
		{
    
    
			initBoard(g_pt_lv_100ask_2048_game->canvas_stage, g_pt_lv_100ask_2048_game->game_board);
			addRandom(g_pt_lv_100ask_2048_game->game_board);
			initBoard(g_pt_lv_100ask_2048_game->canvas_stage, g_pt_lv_100ask_2048_game->game_board);
			if (gameEnded(g_pt_lv_100ask_2048_game->game_board))
			{
    
    
				printf("		 GAME OVER			\n");
				g_pt_lv_100ask_2048_game->play_game = false;
			}
		}
	}
}


/* 按键方式 */
static void event_handler_2048_game_up(lv_obj_t * obj, lv_event_t event)
{
    
    
	if (moveUp(g_pt_lv_100ask_2048_game->game_board))
	{
    
    
		initBoard(g_pt_lv_100ask_2048_game->canvas_stage, g_pt_lv_100ask_2048_game->game_board);
		addRandom(g_pt_lv_100ask_2048_game->game_board);
		initBoard(g_pt_lv_100ask_2048_game->canvas_stage, g_pt_lv_100ask_2048_game->game_board);
		if (gameEnded(g_pt_lv_100ask_2048_game->game_board)) {
    
    
			printf("         GAME OVER          \n");
		}
	}

}

static void event_handler_2048_game_down(lv_obj_t * obj, lv_event_t event)
{
    
    
	if (moveDown(g_pt_lv_100ask_2048_game->game_board))
	{
    
    
		initBoard(g_pt_lv_100ask_2048_game->canvas_stage, g_pt_lv_100ask_2048_game->game_board);
		addRandom(g_pt_lv_100ask_2048_game->game_board);
		initBoard(g_pt_lv_100ask_2048_game->canvas_stage, g_pt_lv_100ask_2048_game->game_board);
		if (gameEnded(g_pt_lv_100ask_2048_game->game_board)) {
    
    
			printf("         GAME OVER          \n");
		}
	}
}

static void event_handler_2048_game_left(lv_obj_t * obj, lv_event_t event)
{
    
    
	if (moveLeft(g_pt_lv_100ask_2048_game->game_board))
	{
    
    
		initBoard(g_pt_lv_100ask_2048_game->canvas_stage, g_pt_lv_100ask_2048_game->game_board);
		addRandom(g_pt_lv_100ask_2048_game->game_board);
		initBoard(g_pt_lv_100ask_2048_game->canvas_stage, g_pt_lv_100ask_2048_game->game_board);
		if (gameEnded(g_pt_lv_100ask_2048_game->game_board)) {
    
    
			printf("         GAME OVER          \n");
		}
	}
}

static void event_handler_2048_game_right(lv_obj_t * obj, lv_event_t event)
{
    
    
	if (moveRight(g_pt_lv_100ask_2048_game->game_board))
	{
    
    
		initBoard(g_pt_lv_100ask_2048_game->canvas_stage, g_pt_lv_100ask_2048_game->game_board);
		addRandom(g_pt_lv_100ask_2048_game->game_board);
		initBoard(g_pt_lv_100ask_2048_game->canvas_stage, g_pt_lv_100ask_2048_game->game_board);
		if (gameEnded(g_pt_lv_100ask_2048_game->game_board)) {
    
    
			printf("         GAME OVER          \n");
		}
	}
}

lvgl中文手册

lvgl部分我整理出了系列教程(实时更新),需要系统学习lvgl请前往站点进行学习:

http://lvgl.100ask.net

猜你喜欢

转载自blog.csdn.net/qq_35181236/article/details/115067017