代码如下:
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <sys/mman.h> #include <stdlib.h> #include <linux/input.h> #include <time.h> #include <math.h> #define LCD_WIDTH 800 //屏幕宽度 #define LCD_HEIGHT 480 //屏幕高度 #define ITEM_NUM 4 // 创建4行4列的矩阵 #define ITEM_WIDTH 100 // 图片宽100 #define ITEM_HEIGHT 100 // 图片高100 #define BLANK_SIZE 5 //宏 #define MATRIX_X0 (LCD_WIDTH - (ITEM_WIDTH + BLANK_SIZE)*ITEM_NUM)/2 #define MATRIX_Y0 (LCD_HEIGHT - (ITEM_HEIGHT + BLANK_SIZE)*ITEM_NUM)/2 void bmp_display(int x0, int y0,const char *bmp_file); int *plcd = NULL; int matrix_2048_bak[4][4]; int matrix_2048[4][4] = { 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; void print_matrix_2048() { int i,j; for (i = 0; i < 4; i++){ for (j = 0; j < 4 ; j++){ printf("%d " ,matrix_2048[i][j]); } printf("\n"); } } int is_change(){ int i, j ; for (i = 0; i < 4; i++){ for (j = 0; j < 4; j++){ if (matrix_2048[i][j] != matrix_2048_bak[i][j]){ return 1; } } } return 0; } void LCD_Draw_Point(int x, int y, int color){ if (x >= 0 && x < 800 && y >= 0 && y < 480){ *(plcd + 800*y + x) = color; } } //LCD_Draw_JuXing: 在屏幕点(x0,y0)处画一个长为w,高为h的矩形 void LCD_Draw_JuXing(int x0, int y0, int w, int h ,int color) { //假设矩形内任意点的坐标为(x,y) int x, y; for (y = y0; y < y0 + h; y++){ for (x = x0; x < x0 + w; x++){ LCD_Draw_Point(x, y, color); } } } //产生2 4 8 void LCD_Draw_Matrix() { int i, j; int x0, y0; //每个棋子矩形左上顶点的坐标 for (i = 0; i < ITEM_NUM; i++){ for (j = 0; j < ITEM_NUM ; j++){ y0 = MATRIX_Y0 + (ITEM_HEIGHT + BLANK_SIZE)*i; x0 = MATRIX_X0 + (ITEM_WIDTH + BLANK_SIZE)*j; if (matrix_2048[i][j] == 0){ LCD_Draw_JuXing(x0, y0, ITEM_WIDTH, ITEM_HEIGHT,0x00FFFFFF); } else{ char filename[32]; sprintf(filename, "m%d.bmp", matrix_2048[i][j]); bmp_display(x0, y0, filename); } } } } //放图片 void bmp_display(int x0, int y0,const char *bmp_file) { int fd; unsigned char buf[4]; int ret; fd = open(bmp_file, O_RDONLY); if (fd == -1){ printf("failed to open %s\n", bmp_file); return ; } lseek(fd, 0 ,SEEK_SET); read(fd, buf, 2); if (buf[0] == 0x42 && buf[1] == 0x4d ){ printf("BMP file\n"); } else{ printf("Not BMP file, GOOD BYE\n"); close(fd); return ; } int width,height; int depth; lseek(fd, 0x12, SEEK_SET); read(fd, buf, 4); width = (buf[0]) | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); lseek(fd, 0x16, SEEK_SET); read(fd, buf, 4); height = (buf[0]) | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); printf("%d X %d\n", width, height); lseek(fd, 0x1c, SEEK_SET); read(fd, buf, 2); depth = (buf[0]) | (buf[1] << 8); if (depth != 24 && depth != 32){ printf("Not Support\n"); close(fd); return ; } int bytes_per_line = abs(width) * (depth / 8); int laizi = 0; if (bytes_per_line % 4 != 0){ laizi = 4 - bytes_per_line % 4; } int bytes_line = bytes_per_line + laizi; int size = bytes_line * abs(height); unsigned char *p = malloc(size); lseek(fd, 54, SEEK_SET); read(fd, p, size); unsigned char b ,g, r ,a; int color; int i = 0; int x; int y; for (y = 0; y < abs(height); y++) { for (x = 0 ;x < abs(width); x++ ){ b = p[i++]; g = p[i++]; r = p[i++]; if (depth == 32){ a = p[i++]; } else{ a = 0; } color = (a << 24) | (r << 16) | (g << 8) | (b); LCD_Draw_Point( width > 0 ? x0 + x : x0 + abs(width) - 1 -x, height > 0 ? y0 + height - 1 - y : y0 + y, color); } i = i + laizi; } free(p); close(fd); } int get_zero_num() { int n = 0; int i, j; for (i = 0; i < ITEM_NUM ;i++){ for (j = 0; j < ITEM_NUM; j++){ if (matrix_2048[i][j] == 0){ n++; } } } return n; } //随机生成数字 void fill_random(void) { int zero_num = get_zero_num(); //获取数组中值为0的个数 int pos; //随机的位置的编号,应该要在[0, zero_num) pos = random() % zero_num ; // => pos =>[0,zero_num) int i,j; int n = 0; //第几个0 for (i = 0; i < ITEM_NUM; i++){ for (j = 0; j < ITEM_NUM; j++){ if (matrix_2048[i][j] == 0){ if (n == pos){ matrix_2048[i][j] = 2;//a[index]; return ; } n++; } } } } //清零 void get_zero(){ for (int i = 0; i < ITEM_NUM ; i++) { for (int j = 0; j < ITEM_NUM; j++) { matrix_2048[i][j] = 0; } } } /* void brush_lcd(int color) { int i,j; for(i = 0; i < 100; i++) { for(j = 0; j < 100; j++) { LCD_Draw_Point(j, i, color); } } } */ #define MOVE_UP 1 #define MOVE_DOWN 2 #define MOVE_LEFT 3 #define MOVE_RIGHT 4 //#define SHUA_XIN 5 //屏幕滑动 int get_finger_movemenet(void) { int fd = open("/dev/input/event0", O_RDONLY); int res; if (fd == -1) { printf("open /dev/event0 failed\n"); return -1; } int flag; int x1 = -1, y1 = -1; // 接触时候的坐标点 int x2, y2; // 离开后的坐标点 struct input_event ev; while( 1 ){ res = read( fd , &ev, sizeof(ev) ); if( res != sizeof(ev) ) continue; if( ev.type == EV_ABS && ev.code == ABS_X ) { if( x1 == -1 ) x1 = ev.value; x2 = ev.value; } if (ev.type == EV_ABS && ev.code == ABS_Y) { if (y1 == -1) y1 = ev.value; y2 = ev.value; } //实现重新开始游戏 if(x2>=0&&y2>=0&&x2<=120*800/1024&&y2<=200*479/599){ for(int i=0;i<4;i++){ for(int j=0;j<4;j++){ matrix_2048[i][j]=0; } } fill_random(); fill_random(); LCD_Draw_Matrix(); } //if(x2>=0&&y2>=500*479/599&&x2<=120*800/1024&&y2<=480*479/599){ //show_bmp("jieshao.bmp",0,0); //sleep(3); //bangzhu(0,0,"jieshao.bmp"); //} if( (ev.type == EV_ABS && ev.code == ABS_PRESSURE && ev.value == 0 ) || ( ev.type == EV_KEY && ev.code == BTN_TOUCH && ev.value == 0 ) ) { printf("x2 = %d\ty2 = %d\n",x2,y2); printf("flag = %d\n",flag); printf("\n\n\n\n"); if( flag ) return 0; printf("x1 = %d\ty1 = %d\nx2 = %d\ty2 = %d\n",x1,y1,x2,y2); int opposite_x = abs(x2-x1); // 左右 int opposite_y = abs(y2-y1); // 上下 printf("opposite_x = %d\topposite_y = %d\n",opposite_x,opposite_y); if( x2 >= 830 && y2 < 80 && opposite_x <= 40 && opposite_y <= 32 ) { flag = 1; return 0; } if( opposite_x <= 40 && opposite_y <= 32 ) { x1 = -1; y1 = -1; continue; } // if( x2 <= 100 && y2 <=100 ) { // return SHUA_XIN; // } if( opposite_x > 2 * opposite_y ){ // 左右移动 if( x2 > x1 ){ // 方块向右边移动 close(fd); return MOVE_RIGHT; } else{ // 方块向左边移动 close(fd); return MOVE_LEFT; } } else if( opposite_x < 2* opposite_y ){ // 上下移动 if( y2 > y1 ){ // 方块向下移动 close(fd); return MOVE_DOWN; } else{ // 方块向上移动 close(fd); return MOVE_UP; } } else x1 = -1, y1 = -1; } } close(fd); } //实现上下左右 void move_left(void) { int i, j; int x, y; for (i = 0; i < ITEM_NUM; i++) { for (x = 0; x < ITEM_NUM; ){ if (matrix_2048[i][x] != 0){ for (y = x + 1; y < ITEM_NUM; y++){ if (matrix_2048[i][y] != 0){ if (matrix_2048[i][x] == matrix_2048[i][y]){ matrix_2048[i][x] += matrix_2048[i][y]; matrix_2048[i][y] = 0; x = y + 1; break; } else{ x = y; } } } if (y >= ITEM_NUM){ break; } } else{ x++; } } x = 0; for (y = 0 ; y < ITEM_NUM; y++){ if (matrix_2048[i][y] != 0){ if (x != y){ matrix_2048[i][x] = matrix_2048[i][y]; matrix_2048[i][y] = 0; } x++; } } } } void move_right(void) { int i, j; int x, y; for (i = 0; i < ITEM_NUM; i++){ for (x = ITEM_NUM; x >0; ){ if (matrix_2048[i][x] != 0) { for (y = x-1; y>=0; y--){ if (matrix_2048[i][y] != 0){ if (matrix_2048[i][x] == matrix_2048[i][y]){ matrix_2048[i][x] += matrix_2048[i][y]; matrix_2048[i][y] = 0; x = y - 1; break; } else{ x = y; } } } if (y<0){ break; } } else{ x--; } } x = ITEM_NUM-1; for (y = ITEM_NUM-1 ; y >= 0; y--){ if (matrix_2048[i][y] != 0){ if (x != y){ matrix_2048[i][x] = matrix_2048[i][y]; matrix_2048[i][y] = 0; } x--; } } } } void move_down(void) { int i, j; int x, y; for (i = 0; i < ITEM_NUM; i++){ for (x = 0; x < ITEM_NUM; ){ if (matrix_2048[x][i] != 0){ for (y = x + 1; y < ITEM_NUM; y++){ if (matrix_2048[y][i] != 0){ if (matrix_2048[x][i] == matrix_2048[y][i]){ matrix_2048[x][i] += matrix_2048[y][i]; matrix_2048[y][i] = 0; x = y + 1; break; } else{ x = y; } } } if (y >= ITEM_NUM){ break; } } else{ x++; } } x = 0; for (y = 0; y < ITEM_NUM; y++){ if (matrix_2048[y][i] != 0){ if (x != y){ matrix_2048[x][i] = matrix_2048[y][i]; matrix_2048[y][i] = 0; } x++; } } } } void move_up(void) { int i, j; int x, y; for (i = 0; i < ITEM_NUM; i++) { for (x = ITEM_NUM; x >=0; ) { if (matrix_2048[x][i] != 0){ for (y = x - 1; y >= 0; y--){ if (matrix_2048[y][i] != 0){ if (matrix_2048[x][i] == matrix_2048[y][i]){ matrix_2048[x][i] += matrix_2048[y][i]; matrix_2048[y][i] = 0; x = y -1; break; } else { x = y; } } } if (y<0){ break; } } else{ x--; } } x = ITEM_NUM-1; for (y = ITEM_NUM-1 ; y >= 0; y--){ if (matrix_2048[y][i] != 0) { if (x != y){ matrix_2048[x][i] = matrix_2048[y][i]; matrix_2048[y][i] = 0; } x--; } } } } //重新游戏 //void shuaxin(){ //get_zero(); //} //游戏结束 int is_gameover(void) { int x,y; for(y=0;y<ITEM_NUM;y++){ for(x=0;x<ITEM_NUM;x++){ if(matrix_2048[x][y]==0){ return 0; } if(x<ITEM_NUM-1 && matrix_2048[x][y]==matrix_2048[x+1][y]){ return 0; } if(y<ITEM_NUM-1 && matrix_2048[x][y]==matrix_2048[x][y+1]){ return 0; } } } return 1; } //根据手指滑动方向变换矩阵 void change_matrix(int mv) { if (mv == MOVE_LEFT){ move_left(); } else if (mv == MOVE_RIGHT){ move_right(); } else if (mv == MOVE_UP){ move_down(); } else if (mv == MOVE_DOWN){ move_up(); } //else if (mv == SHUA_XIN){ // shuaxin(); //} } int * p = NULL ; void draw_point(int x,int y,int color) { if(x>=0 && x<800 && y>=0 && y<480 ) { *(p+800*y+x) = color ; } } /* 函数功能:在屏幕的任意一个位置 显示任意一张 任意大小的bmp图片 函数参数: @pathname : 要显示的图片 的路径名 @x : 在屏幕X轴值为x的地方开始显示 @y : 在屏幕Y轴值为y的地方开始显示 */ void show_bmp (char * pathname ,int x ,int y) { int fd = open(pathname,O_RDONLY); if(fd == -1) { perror("open error\n"); return ; } int fd1 = open("/dev/fb0",O_RDWR); if(fd1 == -1) { perror("open error\n"); return ; } printf("open success\n"); p = mmap(NULL,800*480*4,PROT_READ | PROT_WRITE,MAP_SHARED ,fd1,0); if(p == NULL ) { perror("mmap error\n"); return ; } int width,height; short depth; unsigned char buf[4] ; //读取宽度 lseek(fd,0x12,SEEK_SET); read(fd,buf,4); width = buf[3]<<24 | buf[2]<< 16 | buf[1] << 8 | buf[0]; //读取高度 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]; //打印信息 printf("width = %d height = %d depth = %d \n",width,height,depth); //像素数组 int line_valid_bytes = abs(width) * depth / 8 ; //一行本有的有效字节 int laizi=0;//填充字节 if( (line_valid_bytes % 4) !=0 ) { laizi = 4 - line_valid_bytes%4; } int line_bytes = line_valid_bytes + laizi ;//一行所有的字节数 int total_bytes = line_bytes * abs(height) ; //整个像素数组的大小 unsigned char * p1 = malloc(total_bytes); lseek(fd,54,SEEK_SET); read(fd,p1,total_bytes); //调用draw_point 函数 。 unsigned char a ,r ,g, b ; int i = 0;//用来做指针运动的 int x0=0,y0=0; //用来循环计数 int color ; for(y0=0;y0<abs(height);y0++)//画满每一列 { for(x0=0;x0<abs(width);x0++)//画满每一行 { //现在开始一个字节一个字节写入颜色 // i++ 先用后加 // ++i 先加后用 b = p1[i++]; g = p1[i++]; r = p1[i++]; if(depth == 32){ a=p1[i++]; } if(depth == 24){ a = 0; } color = a << 24 | r << 16 | g << 8 | b ; draw_point(width>0?x+x0:abs(width)+x-1-x0, height>0? y+height-1-y0 : y+y0,color); } i = i +laizi ;//每一行后面的癞子数 跳过去。 } free(p1); close(fd1); munmap(p,800*480*4); close(fd); } //开始 int start(int x0, int y0,const char *bmp_file) { show_bmp("start.bmp",0,0); int fd4 = open ("/dev/input/event0",O_RDWR); if(fd4 == -1 ){ perror("open error\n"); return -1; } struct input_event ev4; int x4,y4; int x_start,y_start,x_stop,y_stop; while(1){ int r4 =read(fd4,&ev4,sizeof(ev4)); if(r4 != sizeof(ev4)){ perror("read ev error\n"); return -1; } if(ev4.type == EV_ABS && ev4.code ==ABS_X){ x4 = ev4.value ; } if(ev4.type == EV_ABS && ev4.code ==ABS_Y){ y4 = ev4.value ; } if( ev4.type == EV_KEY && ev4.code == BTN_TOUCH && ev4.value != 0){ printf("down(%d,%d)",x4,y4); x_start = x4; y_start = y4 ; } if( ev4.type == EV_KEY && ev4.code == BTN_TOUCH && ev4.value == 0){ printf("up(%d,%d)",x4,y4); x_stop = x4; y_stop = y4; break; } } if( abs(x_start - x_stop) - abs(y_start - y_stop) > 0 && abs(x_start - x_stop) > 30 ){ if(x_stop - x_start > 0 ){ return 4 ; } else return 3; } } //帮助 int bangzhu(int x0, int y0,const char *bmp_file) { show_bmp("jieshao.bmp",0,0); int fd4 = open ("/dev/input/event0",O_RDWR); if(fd4 == -1 ){ perror("open error\n"); return -1; } struct input_event ev4; int x4,y4; int x_start,y_start,x_stop,y_stop; while(1){ int r4 =read(fd4,&ev4,sizeof(ev4)); if(r4 != sizeof(ev4)){ perror("read ev error\n"); return -1; } if(ev4.type == EV_ABS && ev4.code ==ABS_X){ x4 = ev4.value ; } if(ev4.type == EV_ABS && ev4.code ==ABS_Y){ y4 = ev4.value ; } if( ev4.type == EV_KEY && ev4.code == BTN_TOUCH && ev4.value != 0){ printf("down(%d,%d)",x4,y4); x_start = x4; y_start = y4 ; } if( ev4.type == EV_KEY && ev4.code == BTN_TOUCH && ev4.value == 0){ printf("up(%d,%d)",x4,y4); x_stop = x4; y_stop = y4; break; } } if( abs(x_start - x_stop) - abs(y_start - y_stop) > 0 && abs(x_start - x_stop) > 30 ){ if(x_stop - x_start > 0 ){ return 4 ; } else return 3; } } //计分 /* unsigned char num[10][16] = { {0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00}, {0x00,0x00,0x00,0x08,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00}, {0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x02,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00}, {0x00,0x00,0x00,0x3C,0x42,0x42,0x02,0x04,0x18,0x04,0x02,0x42,0x42,0x3C,0x00,0x00}, {0x00,0x00,0x00,0x04,0x0C,0x0C,0x14,0x24,0x24,0x44,0x7F,0x04,0x04,0x1F,0x00,0x00}, {0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x78,0x44,0x02,0x02,0x42,0x44,0x38,0x00,0x00}, {0x00,0x00,0x00,0x18,0x24,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x22,0x1C,0x00,0x00}, {0x00,0x00,0x00,0x7E,0x42,0x04,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x00,0x00}, {0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00}, {0x00,0x00,0x00,0x38,0x44,0x42,0x42,0x42,0x46,0x3A,0x02,0x02,0x24,0x18,0x00,0x00}, }; void show_word(char *word, int x, int y, int wordsieze, int width, int color) { int perbyte = width / 8; int i,j; int x0,y0; for(i = 0; i < wordsieze; i++) { for(j = 7; j >= 0; j-- ) { if(word[i] & (1 << j)) { x0 = (i % perbyte) * 8 + (7 - j); y0 = i / perbyte; LCD_Draw_Point(x0 + x, y0 + y, color); } } } } void show_num(int num1, int x0, int y0, int numsize, int color) { if(num1 / 100) //��ʾֻ�а� ʮ ��λ������ { //��ʾ��λ ���� 250 show_word(num[num1 / 100], x0, y0, sizeof(num[num1 / 100]), numsize, color); //��ʾʮλ show_word(num[num1 % 100 / 10],x0 + numsize + 2, y0, sizeof(num[num1 % 100 / 10]), numsize, color); //��ʾ��λ show_word(num[num1 % 10], x0 + 2 *(numsize + 2), y0, sizeof(num[num1 % 10]),numsize, color); } } int get_sum() { int s = 0; int i, j; for (i = 0; i < ITEM_NUM ; i++) { for (j = 0; j < ITEM_NUM; j++) { s+=matrix_2048[i][j]; } } return s; } */ int main() { start(0,0,"start.bmp"); int fd = open("/dev/fb0", O_RDWR); if (fd == -1){ printf("failed to open /dev/fb0\n"); return -1; } printf("open /dev/fb0 successfully\n"); //2. 操作文件 plcd = mmap(NULL, 800*480*4, PROT_WRITE, MAP_SHARED, fd, 0); if (plcd == MAP_FAILED){ printf("failed to mmap\n"); return -1; } srandom( time(NULL)) ;//设置随机数种子 LCD_Draw_JuXing(0, 0, LCD_WIDTH, LCD_HEIGHT, 0x00BBFFFF); fill_random(); fill_random(); show_bmp("shuaxin.bmp",0,30); show_bmp("help.bmp",0,400); LCD_Draw_Matrix(); while (1){ //计分 //int sum; //sum = get_sum(); //show_num(100+sum, 50, 230, 8, 0x00FF0000); //printf("sum=%d\n",sum); //滑动 int mv = get_finger_movemenet(); printf("mv = %d\n", mv); change_matrix(mv); fill_random(); LCD_Draw_Matrix(); print_matrix_2048(); if (is_gameover()){ show_bmp("restart.bmp",110,0); sleep(2); start(0,0,"start.bmp"); get_zero(); int xu = get_zero_num(); srandom(time(NULL)) ;//������������� LCD_Draw_JuXing(0, 0, LCD_WIDTH, LCD_HEIGHT, 0x00BBFFFF); fill_random(); fill_random(); show_bmp("shuaxin.bmp",0,30); show_bmp("help.bmp",0,400); LCD_Draw_Matrix(); //LCD_Draw_JuXing(0, 0, LCD_WIDTH, LCD_HEIGHT, 0x00BBFFFF); //show_bmp("shuaxin.bmp",0,30); } } //3.关闭文件 munmap(plcd, 800*480*4); close(fd); }
bmp图片大家自己换一下