1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 嵌入式Linux开发-在6818开发板显示2048游戏

嵌入式Linux开发-在6818开发板显示2048游戏

时间:2022-05-01 11:35:21

相关推荐

嵌入式Linux开发-在6818开发板显示2048游戏

该项目只是一个原始版本,图片已经删除,我已经上传完整的项目资源zip,如有需要请自行下载!!!

/download/weixin_46836491/86694132?spm=1001..3001.5503

完成图:

点击左上角

随机清除4个不为0的数

点击左下角重置游戏

代码如下:

#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <string.h>//字符串函数的头文件#include <sys/mman.h>#include <stdio.h>#include <stdlib.h>#include <linux/input.h>#include <time.h> /*宏定义*/#define LCD_PATH "/dev/fb0" //语法高亮#define TOUCH_PATH "/dev/input/event0"#define DWON 0 //上#define UP1 //下#define LEFT 2 //左#define RIGHT 3 //右#define EXIT 4 //退出游戏#define RE_START 5//重新开始游戏#define Remove 6//消除//...可以实现其他的按键功能/*全局变量*/int* plcd = NULL;//指向帧缓冲的映射区域的首地址 初始化的时候指向为空int fb_fd = -1;int x = -1,y = -1;int matrix[4][4]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};int OLD_matrix[4][4];/*函数声明*/void Init_Lcd(void);void UNinit_Lcd(void);void LCD_Draw_Point(int x,int y,int color);int Bmp_display(char *bmp_file,int x0,int y0);void get_xy(int *x,int *y);void Init_Game_view(void);int Get_Zero_num(void);//获取二维数字有多少个0元素int Rand_Fill_Num(void);//随机位置填充随机数字int Usr_Control_touch(void);int IS_Win(void);int IS_Failed(void);void Save_old_matrix(void);int Judge_matrix(void);void Display_matrix(void);void matrix_right(void);void matrix_left(void);void matrix_down(void);void matrix_up(void);void GAME_INIT(void);void Game_Remove(void);int Rand_Fill_Num2(void);int Get_One_num(void);int main(){srand(time(NULL));//1.打开屏幕Init_Lcd();//2.显示开机图片Bmp_display("Begin.bmp",0, 0);Bmp_display("play.bmp",240,380);//3.判断用户是否按下了开始按键while(1){get_xy(&x, &y);if(x>=0 && x<=800 && y>=300 && y<=480){//Bmp_display("7.bmp",0, s0);break;}}x = -1,y=-1;InitGame://4.进入游戏界面Init_Game_view();//5.开始游戏while(1){int direction = Usr_Control_touch();//保存以前的数组Save_old_matrix();if(direction == RIGHT){//棋盘向右移动matrix_right();}else if(direction == LEFT){matrix_left();}else if(direction == UP){matrix_up();}else if(direction==DWON){matrix_down();}else if(direction==RE_START){GAME_INIT();goto InitGame;}else if(direction==Remove){Game_Remove();}x = -1,y = -1;//坐标重置//在随机的位置填充随机数字之前我们需要判断是否需要填充if(Judge_matrix()){Rand_Fill_Num();}Display_matrix();//判断if(IS_Win()==1){Bmp_display("shengli.bmp",0,0);//询问用户是否重新开始游戏while(1){get_xy(&x, &y);if(x>=280 && x<=450 && y>=350 && y<=600){break;}}x = -1,y=-1;GAME_INIT();goto InitGame;break;}else if(IS_Failed()==1){Bmp_display("shibai.bmp",0, 0);//嘲讽用户一波 询问是否重新开始游戏while(1){get_xy(&x, &y);if(x>=280 && x<=450 && y>=350 && y<=600){break;}}x = -1,y=-1;GAME_INIT();goto InitGame;break;}}//Bmp_display("2.bmp", 0, 0);UNinit_Lcd();}//重新开始void GAME_INIT(){UNinit_Lcd();srand(time(NULL));Init_Lcd();int b[4][4] = {0};int x = -1,y = -1;memcpy(matrix, b, sizeof(matrix));}//随机清除4个void Game_Remove(){UNinit_Lcd();srand(time(NULL));Init_Lcd();Rand_Fill_Num2();Rand_Fill_Num2();Rand_Fill_Num2();Rand_Fill_Num2();}//初始化屏幕 打开屏幕 然后映射void Init_Lcd(void){//1.打开屏幕//1.打开文件int fd = open(LCD_PATH,O_RDWR);//文件描述符 代表 一个已经打开文件if(-1 == fd) // fd == -1 <==> fd = -1 -1 = fd =>编译错误{perror("open LCD fail");//打印错误return ;}fb_fd = fd;//2.映射plcd = mmap(NULL,480*800*4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);if(MAP_FAILED == plcd){perror("mmap fail");return ;}}//关闭屏幕void UNinit_Lcd(void){munmap(plcd,480*800*4);plcd = NULL;close(fb_fd);}//把屏幕上任意的x y的像素点显示成color颜色void LCD_Draw_Point(int x,int y,int color){if(x>=0&&x<800&&y>=0&&y<480)//防止传入的参数异常*(plcd+x+y*800) = color;}/*解析显示一张bmp图片的bmp_file:图片文件的路径名 比如:1.bmp /home/2.bmp x0,y0 在屏幕上显示的起始坐标*/int Bmp_display(char *bmp_file,int x0,int y0){//1.打开bmp图片int fd = open(bmp_file,O_RDONLY);if(-1==fd){printf("open %s fail\n",bmp_file);perror("--->");return -1;}//2.判断到底是不是一张bmp图片unsigned char buf[4];read(fd,buf,2);if(buf[0]!= 0x42 || buf[1]!= 0x4d)//若果不是B M{printf("NOT BMP\n");goto ERROR_END;}//3.获取bmp图片的属性 宽 高 色深int width,height;short depth;lseek(fd,0x12,SEEK_SET);read(fd,buf,4);width=(buf[3]<<24)|(buf[2]<<16)|(buf[1]<<8)|(buf[0]);lseek(fd,0x16,SEEK_SET);read(fd,buf,4);height=(buf[3]<<24)|(buf[2]<<16)|(buf[1]<<8)|(buf[0]);lseek(fd,0x1c,SEEK_SET);read(fd,buf,2);depth=(buf[1]<<8)|(buf[0]);//只支持色深为24和32的if(!(depth == 24 || depth == 32)){printf("NOT Support!\n");goto ERROR_END;}printf("%s:%d*%d depth=%d\n",bmp_file,width,height,depth);//4.获取像素数组int line_valid_bytes = abs(width)*depth/8;//一行有效字节数int line_bytes;//一行总字节数=有效字节数+赖子数 int laizi = 0;if(line_valid_bytes%4)//判断是否有赖子 不能被4整除{laizi = 4-line_valid_bytes%4;//差多少就补多少个赖子 要满足4的倍数}line_bytes = line_valid_bytes + laizi;int total_bytes = line_bytes*abs(height);//整个像素数组的大小//是不是需要一个地方来存放读出来的这个像素数组呢??//unsigned char piexl[total_bytes];//也可以向系统申请一块动态内存 unsigned char *piexl = (unsigned char *)malloc(total_bytes);lseek(fd,54,SEEK_SET);read(fd,piexl,total_bytes);//5.在屏幕上一一显示这些像素点//读像素点字节--->ARGB--->在屏幕上进行显示unsigned char a,r,g,b;int color;int i = 0;int x,y;for(y=0;y<abs(height);y++){for(x=0;x<abs(width);x++){//a r g b 0xargb 小端模式 b g r ab = piexl[i++];g = piexl[i++];r = piexl[i++];if(depth == 32){a = piexl[i++];}else{a = 0;//不透明}color=(a<<24)|(r<<16)|(g<<8)|(b);//printf("%x\n",color);//在屏幕对应的位置显示LCD_Draw_Point(width>0?x0+x:x0+abs(width)-x-1, height>0?y0+abs(height)-y-1:y0+y,color);}//每一行的末尾 有可能填充几个赖子i += laizi;}free(piexl);close(fd);ERROR_END:close(fd);return -2;}/*获取用户的输入:x轴的值 y轴的值*/void get_xy(int *x,int *y){//1.打开触摸屏int fd = open(TOUCH_PATH,O_RDONLY);if(-1 == fd){perror("open touch fail");return ;}//2.获取用户输入//获取屏幕信息struct input_absinfo absI;ioctl(fd,EVIOCGABS(ABS_X),&absI); //获取屏幕的x轴信息 最小~最大坐标printf("x:%d ~ %d\n",absI.minimum,absI.maximum);ioctl(fd,EVIOCGABS(ABS_Y),&absI);//y轴信息printf("y:%d ~ %d\n",absI.minimum,absI.maximum);ioctl(fd,EVIOCGABS(ABS_PRESSURE),&absI);//屏幕的压力的最小~最大printf("pres:%d ~ %d\n",absI.minimum,absI.maximum);struct input_event ev;int flag_x = 0,flag_y = 0;while(1){int res = read(fd,&ev,sizeof(ev));//sizeof 求变量所占的字节数(空间) 读一个结构体大小//假设我读出来的字节数跟ev所占的空间不一样 那么就是读取失败if(res!=sizeof(ev)){continue;}if(ev.type == EV_ABS && ev.code == ABS_X)//获取X轴坐标{*x = ev.value*(1.0*800/1024);flag_x = 1;if(flag_y)break;}if(ev.type == EV_ABS && ev.code == ABS_Y)//获取Y轴坐标{*y = ev.value*(1.0*480/600);flag_y = 1;if(flag_x)break;}}//3.关闭触摸屏close(fd);}/*根据二维数组的内容更新游戏棋盘*/void Display_matrix(void){char bmp_name[64]={0};//保存游戏区域格子需要显示的图片的名字int i,j;for(i=0;i<4;i++)//遍历二维数组的每一个元素{for(j=0;j<4;j++){if(matrix[i][j])//假设不为0 则显示对应的图片 为0则显示一张空白图片{memset(bmp_name,0,64);//将数组清空sprintf(bmp_name,"9090/digit_%d.bmp",matrix[i][j]);//相当于把color_x80_4.bmp-->bmp_nameBmp_display(bmp_name,100+j*(80+10),65+i*(80+10));}else{//显示一张空白图片Bmp_display("play1.bmp",100+j*(80+10),65+i*(80+10));}}}}/*显示游戏界面*/void Init_Game_view(void){//0.显示游戏界面的背景Bmp_display("7.bmp",0, 0);//1.显示四个按键Bmp_display("xx.bmp",450,170);Bmp_display("xx.bmp",660,170);Bmp_display("xx.bmp",550,58);Bmp_display("xx.bmp",550,295);Bmp_display("shuaxin1.bmp",0,430);Bmp_display("futou1.bmp",0,0);//3.更新棋盘//在棋盘的随机两个位置填充随机数字Rand_Fill_Num();Rand_Fill_Num();//随机位置填充随机数字Display_matrix();}int Get_Zero_num(void)//获取二维数字有多少个0元素{int i,j,count=0;for(i=0;i<4;i++)//遍历二维数组的每一个元素{for(j=0;j<4;j++){if(matrix[i][j]==0){count++;}}}return count;}//获取不为0的数int Get_One_num(void)//获取二维数字有多少个0元素{int i,j,count=0;for(i=0;i<4;i++)//遍历二维数组的每一个元素{for(j=0;j<4;j++){if(matrix[i][j]!=0){count++;}}}return count;}int Rand_Fill_Num(void)//随机位置填充随机数字{//随机位置int pos_k = rand()%Get_Zero_num()+1;//1~Kint i,j,count=0;int num[] = {2,2,2,2,4,4,8};//模拟概率//遍历到填充位置for(i=0;i<4;i++)//遍历二维数组的每一个为0元素{for(j=0;j<4;j++){if(matrix[i][j]==0){count++;if(count == pos_k){//填充int n = rand()%7;//0~6matrix[i][j]=num[n];/*以上代码可以简化为matrix[i][j]=num[rand()%7];*/}}}}}int Rand_Fill_Num2(void)//随机位置填充随机数字{//随机位置int pos_k = rand()%Get_One_num()+1;//1~Kint i,j,count=0;int num[] = {0,0,0,0,0,0,0};//模拟概率//遍历到填充位置for(i=0;i<4;i++)//遍历二维数组的每一个不为0元素{for(j=0;j<4;j++){if(matrix[i][j]!=0){count++;if(count == pos_k){//填充int n = rand()%7;//0~6matrix[i][j]=num[n];/*以上代码可以简化为matrix[i][j]=num[rand()%7];*/}}}}}int Usr_Control_touch(void){while(1){get_xy(&x,&y);//这个函数返回之后 就是获取了x yif(x>440&&y>160&&x<550&&y<300){//左按钮printf("x:%d y:%d\n",x,y);Bmp_display("bjn.bmp",450,170);usleep(50000);Bmp_display("xx.bmp",450,170);return LEFT;}else if(x>550&&y>300&&x<660&&y<430){printf("x:%d y:%d\n",x,y);Bmp_display("bjn.bmp",550,295);usleep(50000);Bmp_display("xx.bmp",550,295);//下按钮return DWON;}else if(x>660&&y>188&&x<792&&y<298){printf("x:%d y:%d\n",x,y);Bmp_display("bjn.bmp",660,170);usleep(50000);Bmp_display("xx.bmp",660,170);//右按钮return RIGHT;}else if(x>550&&y>58&&x<662&&y<188){printf("x:%d y:%d\n",x,y);Bmp_display("bjn.bmp",550,58);usleep(50000);Bmp_display("xx.bmp",550,58);//上按钮return UP;}else if(x>0&&y>410&&x<100&&y<480){printf("x:%d y:%d\n",x,y);Bmp_display("shuaxin1.bmp",0,430);usleep(50000);Bmp_display("shuaxin2.bmp",0,430);//上按钮return RE_START;}else if(x>0&&y>0&&x<100&&y<100){printf("x:%d y:%d\n",x,y);Bmp_display("futou1.bmp",0,0);usleep(50000);Bmp_display("futou2.bmp",0,0);return Remove;printf("x:%d y:%d\n",x,y);}}}void matrix_left(void){//改变棋盘的 改变的二维数组 int i, j;//i为矩阵行下标,j为矩阵列下标int value, save_zero;for(i = 0; i < 4; i++){value = 0;save_zero= 0;for(j = 0; j < 4 ; j++){if (matrix[i][j] == 0)continue;if (value == 0)value = matrix[i][j];else{if (value == matrix[i][j]){matrix[i][save_zero++] = value * 2;value = 0;} else {matrix[i][save_zero++] = value;value = matrix[i][j];}}matrix[i][j] = 0;}if (value != 0)matrix[i][save_zero] = value;}}void matrix_right(void){int i, j;//i为矩阵行下标,j为矩阵列下标int value;int save_zero;for (i = 0; i < 4; i++){value = 0;save_zero = 4 -1;for (j = 4 - 1; j >= 0 ; j--){if(matrix[i][j] == 0){continue;}if(value == 0){value = matrix[i][j];}else{if(value == matrix[i][j]){matrix[i][save_zero--] = 2 * value;value = 0;}else{matrix[i][save_zero--] = value;value = matrix[i][j];}}matrix[i][j] = 0;}if(value != 0){matrix[i][save_zero] = value;}}}void matrix_up(void){int i, j;//i为矩阵行下标,j为矩阵列下标int value;int save_zero;for(j = 0; j < 4; j++){value = 0;save_zero= 0;for(i = 0; i < 4 ; i++){if(matrix[i][j] == 0){continue;}if(value == 0){value = matrix[i][j];}else{if(value == matrix[i][j]){matrix[save_zero++][j] =2 * value;value = 0;}else{matrix[save_zero++][j] = value;value = matrix[i][j];}}matrix[i][j] = 0;}if(value != 0){matrix[save_zero][j] = value;}}}void matrix_down(void){int i, j;//i为矩阵行下标,j为矩阵列下标int value;int save_zero;for(j = 0; j < 4; j++){value = 0;save_zero = 4 - 1;for(i = 4 - 1; i >= 0 ; i--){if(matrix[i][j] == 0){continue;}if(value == 0){value = matrix[i][j];}else{if(value == matrix[i][j]){matrix[save_zero--][j] = 2 * value;value = 0;}else{matrix[save_zero--][j] = value;value = matrix[i][j];}}matrix[i][j] = 0;}if(value != 0){matrix[save_zero][j] = value;}}}/*成功返回1 没有失败返回0*/int IS_Win(void){int i,j;for(i=0;i<4;i++){for(j=0;j<4;j++){if(matrix[i][j] == 32){return 1;}}}return 0;}/*失败返回1 没有失败返回0*/int IS_Failed(void){int i, j;if(Get_Zero_num() != 0){return 0;}for(i = 0; i < 4; i++){for(j = 0; j < 4 ; j++){if (j != 4 -1){if (matrix[i][j] == matrix[i][j+1]){return 0;}}if (i != 4 - 1){if (matrix[i][j] == matrix[i+1][j]){return 0;}}}}return 1;//棋盘满了}/*保存原来的数组*/void Save_old_matrix(void){int i,j;for(i=0;i<4;i++){for(j=0;j<4;j++){OLD_matrix[i][j] = matrix[i][j];}}}/*相同返回0 不相同返回1*/int Judge_matrix(void){int i,j;for(i=0;i<4;i++){for(j=0;j<4;j++){if(OLD_matrix[i][j] != matrix[i][j]){return 1;}}}return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。