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

https://download.csdn.net/download/weixin_46836491/86694132?spm=1001.2014.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 UP      1  //下
#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;
}

嵌入式Linux开发-在6818开发板显示2048游戏相关推荐

  1. 《嵌入式Linux与物联网软件开发——C语言内核深度解析》一第1章 C语言与内存1.1 引言...

    本节书摘来自异步社区<嵌入式Linux与物联网软件开发--C语言内核深度解析>一书中的第1章,第1.1节,作者朱有鹏 , 张先凤,更多章节内容可以访问云栖社区"华章计算机&quo ...

  2. 《嵌入式Linux与物联网软件开发——C语言内核深度解析》一2.4 位运算构建特定二进制数...

    本节书摘来自异步社区<嵌入式Linux与物联网软件开发--C语言内核深度解析>一书中的第2章,第2.4节,作者朱有鹏 , 张先凤,更多章节内容可以访问云栖社区"异步社区" ...

  3. 嵌入式Linux与物联网软件开发:C语言内核深度解析

    嵌入式Linux与物联网软件开发:C语言内核深度解析     1.C语言与内存         1.引言         2.计算机程序运行的目的         3.位.半字.字的概念和内存位宽   ...

  4. 嵌入式 Linux 与物联网软件开发 ——C 语言内核深度解析

    C 语言是嵌入式 Linux 领域的主要开发语言. 对于学习嵌入式.单片机.Linux 驱动开发等技术来说,C 语言是必须要过的一关.C 语言学习的特点是入门容易.深入理解难.精通更是难上加难.很多用 ...

  5. linux嵌入式主要学什么,学嵌入式linux,用什么开发板,请大家推荐一下

    搞个嵌入式linux培训班的课程来看下,就知道要学什么了 C语言基础.C++基础.数据结构.操作系统原理.Linux应用基础.电子电路基础 开课前一周:入学基础测试与辅导(C语言.C++.linux基 ...

  6. 嵌入式linux编程,嵌入式Linux学习笔记 - 嵌入式Linux基础知识和开发环境的构建_Linux编程_Linux公社-Linux系统门户网站...

    注:所有内容基于友善之臂Mini2440开发板 一.嵌入式Linux开发环境的构建 嵌入式开发一般分为三个步骤: 1.编译bootloader,烧到开发板 2.编译嵌入式Linux内核,烧到开发板 3 ...

  7. 【嵌入式Linux】第二部分 - 开发实践

    本部分主要专注构建从0到1的嵌入式Linux学习知识体系,主要设计环境配置,嵌入式Linux基础部分,Linux文件系统及系统移植,驱动开发等知识. 目前持续更新中,更新时间:2022年11月12日 ...

  8. 嵌入式 linux 应用 go 语言开发(开篇,缘起)

    go语言被称作互联网时代的c语言,用来开发嵌入式linux是一种享受. 希望能否带来开发工作效率的提升,产品质量稳定性方面的提升,产品功能上的增强. 物联网时代,就是要有所"变革" ...

  9. 嵌入式linux之go语言开发(六)几行代码实现终端的远程日志诊断

    日志是应用的镜子,可以发现应用中的问题,重要性不言而喻. 以往设备有问题了,是如何诊断的?我们是现场人员到现场,又是配合抓包,又是配合提供机器日志,效率极其低下. 如今都物联网时代了,能让数据跑路的还 ...

最新文章

  1. ffmpeg的中文学习文档
  2. 看看50万码农怎么评论:为什么程序员工资那么高但很少有人炫富?
  3. java文件解压文件_java 文件解压缩
  4. ​谁是信创担当 《2021中国信创生态市场研究报告》今日正式发布
  5. 变压器的同名端,以及判别方法
  6. 【ATT】【second】Decode Ways
  7. linux设置免密ssh,Linux终端设置免密登陆ssh(以 XShell 为例)
  8. [转载]如何让自己变得有趣
  9. 牛津词典 2018 年度词汇 ——「有毒」!
  10. 【bzoj5090】组题 分数规划
  11. [分享] 微信支付中商户对个人用户付款案例
  12. do while新用法--方便数据验证时跳出
  13. RHEL7中设置ssh
  14. win10重置进度条不动了_你好,我win10系统重置的进度条卡住了。一直在卡在17%近9个小时了。这要...
  15. Ds18b20的使用
  16. 如何优雅使用JDK8中的Stream对list集合中的某值求和
  17. winhex文件有写保护怎么修改也改变了该怎么办
  18. 小猿学python_小猿圈详解小白如何学习Python网络爬虫
  19. c#.net连接access数据库
  20. 2018回顾录——花信之年

热门文章

  1. (Java) [USACO07DEC]Bookshelf B
  2. 【考研复试】遥感主要知识点汇总
  3. HTML学生个人网站作业设计:游戏网站设计——原神首页 1页 带轮播图
  4. 台式电脑怎么调分辨率_电脑分辨率不能调整怎么办 电脑分辨率调多少最好
  5. Python获取当前时间日期
  6. 用友汽车通过科创板注册:预计年营收超6亿 拟募资5.6亿
  7. 老大老二打架,怎么倒霉的总是老三?快手抖音PK陌陌暴跌!
  8. php 三元运算符 为空,PHP三元运算符vs空合并运算符
  9. 女生直接问你你真棒什么意思_你的意思在哪里?
  10. Tomcat启动时没有加载war工程