成品展示
链接:https://pan.baidu.com/s/1FXLM08DA93aOpTk2h2xVNw?pwd=rxmb
提取码:rxmb
基础功能实现
线程管理
- 实现
showtime()
函数,用于显示当前时间 -
#include "header.h" #include "font.h" void show_font(struct LcdDevice *lcd, char *buf_time) { // 打开字体 font *f = fontLoad(FONT_PATH); // 字体大小的设置 fontSetSize(f, 30); // 创建一个画板(点阵图)宽是200个像素,高是50个像素 bitmap *bm_time = createBitmapWithInit(220, 25, 4, getColor(0, 0, 0, 0)); // 也可使用createBitmapWithInit函数,改变画板颜色 // 将字体写到点阵图上 0,0表示汉字在画板的左上角显示 fontPrint(f, bm_time, 0, 0, buf_time, getColor(0, 255, 255, 255), 0); // 把字体框输出到LCD屏幕上 参数0,0表示画板显示的坐标位置 show_font_to_lcd(lcd->mp, 0, 0, bm_time); // 关闭字体,关闭画板 fontUnload(f); destroyBitmap(bm_time); } // 初始化Lcd struct LcdDevice *init_lcd1(const char *device) { // 申请空间 struct LcdDevice *lcd = malloc(sizeof(struct LcdDevice)); if (lcd == NULL) { return NULL; } // 1打开设备 lcd->fd = open(device, O_RDWR); if (lcd->fd < 0) { perror("open lcd fail"); free(lcd); return NULL; } // 映射 lcd->mp = mmap(NULL, LCD_H * LCD_W * 4, PROT_READ | PROT_WRITE, MAP_SHARED, lcd->fd, 0); return lcd; } // 获取时间 char *get_time() { time_t rawtime; struct tm *timeinfo; char *buffer = (char *)malloc(sizeof(char) * 80); time(&rawtime); timeinfo = localtime(&rawtime); // 格式化时间到 buffer 字符串 snprintf(buffer, 80, "%04d-%02d-%02d %02d:%02d:%02d", timeinfo->tm_year + 1900, // 年份是从1900年开始计算的,所以要加1900 timeinfo->tm_mon + 1, // 月份是从0开始的,所以要加1 timeinfo->tm_mday, // 日期 timeinfo->tm_hour, // 小时 timeinfo->tm_min, // 分钟 timeinfo->tm_sec); // 秒 return buffer; } int showtime() { // 初始化Lcd struct LcdDevice *lcd = init_lcd1(LCD_DEV_PATH); if (lcd == (struct LcdDevice *)NULL) { printf("初始化LCD失败!\n"); return -1; } while (1) { char *buf_time = get_time(); show_font(lcd, buf_time); } return 0; }
触摸输入处理
- 实现
touch_xy()
函数,用于获取触摸屏的x和y坐标 -
#include "header.h" // 获取坐标的函数 void touch_xy(int *x, int *y) { // 定义结构体存放触摸屏数据 struct input_event touch; // 打开触摸屏 int touch_fd = open("/dev/input/event0", O_RDONLY); if (touch_fd == -1) { printf("open event0 error!\n"); } while (1) { // 读取数据 read(touch_fd, &touch, sizeof(touch)); if (touch.type == EV_ABS) // 绝对位移事件 { if (touch.code == ABS_X) // x轴 { *x = touch.value * 800 / 1024; // 黑色边框开发板触摸屏:1024*600 --->800*480 } if (touch.code == ABS_Y) // y轴 { *y = touch.value * 480 / 600; } } // 松开判定:松开一瞬间获取坐标值 if (touch.type == 1 && touch.code == 330 && touch.value == 0) { printf("( %d , %d )\n", *x, *y); break; } } // 关闭文件 close(touch_fd); }
图像显示
- 实现
all_bmp()
函数,用于显示BMP图像 -
#include "header.h" int all_bmp(char *pathname, int x, int y, int w, int h) { if(w + x > 800 || h + y > 480) { perror("要显示的图片不合法"); return 0; } int max_x = x + w; int max_y = y + h; int bmp_fd = open(pathname, O_RDONLY); if(bmp_fd == -1) { perror("图片打开失败"); return -1; } lseek(bmp_fd, 54, SEEK_SET); char bmp_buf[w * h * 3]; int m_x = (4 - w * 3 % 4) % 4; for(int i = 0; i < h; i++) { read(bmp_fd, &bmp_buf[i * w * 3], w * 3); lseek(bmp_fd, m_x, SEEK_CUR); } char new_buf[w * h * 4]; for(int i = 0, j = 0; i < w * h * 3; i += 3, j += 4) { new_buf[j + 3] = 0; new_buf[j] = bmp_buf[i]; new_buf[j + 1] = bmp_buf[i + 1]; new_buf[j + 2] = bmp_buf[i + 2]; } char lcd_buf[w * h * 4]; for(int i = 0; i < h; i++) { for(int j = 0; j < w * 4; j++) { lcd_buf[i * w * 4 + j] = new_buf[(h - i - 1) * w * 4 + j]; } } int lcd_fd = open("/dev/fb0", O_RDWR); if(lcd_fd == -1) { perror("显示屏打开失败"); return -1; } char *p = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, lcd_fd, 0); if(p == (void *)-1) { perror("内存映射失败"); return -2; } int k = 0; for(int i = y; i < max_y; i++) { for(int j = x * 4; j < max_x * 4; j++) { *(p + j + 800 * 4 * i) = lcd_buf[k++]; } } munmap(p, 800 * 480 * 4); close(bmp_fd); close(lcd_fd); return 0; } // 圆形扩散特效 int pic_circular_spread(char *pathname, int* pic_circular_spread_fd) { int ret=0; int line=0; int block=0; int i=0, j=0, k=0; int bmp_fd=0; char bmp_buf[480*800*3]; int mi_buf[480*800]; int temp_buf[480*800]; memset(mi_buf,0,sizeof(mi_buf)); memset(bmp_buf,0,sizeof(bmp_buf)); memset(temp_buf,0,sizeof(temp_buf)); bmp_fd = open(pathname, O_RDONLY);//1、打开BMP格式图片 if(bmp_fd == -1) { printf("pic_circular_spread(), open bmp failed\n"); return -1; } ret = lseek(bmp_fd, 54 , SEEK_SET);//2、跳过bmp图片的前54个位置 if(ret == -1) { perror("pic_circular_spread(), lseek bmp failed\n"); return -1; } ret = read(bmp_fd , bmp_buf , sizeof(bmp_buf)); //4、取读图片像素 if(ret == -1) { printf("pic_circular_spread(), read bmp failed\n"); return -1; } close(bmp_fd);//5、关闭图片 for(i=0, j=0 ; i<800*480 ; i++, j+=3)//6、24bits 转 32bits控制变量 { temp_buf[i] = bmp_buf[j+2]<<16 | bmp_buf[j+1]<<8 | bmp_buf[j] ; } for(line=0 ; line <=480 ;line++)//7、解决图片上下颠倒问题 { for(i=0; i<=800 ; i++) mi_buf[800*line + i] = temp_buf[ (479-line)*800 + i ]; } for(k=0; k<467; k+=3)//8、特殊动画“圆形扩散”效果算法 { for(i=0; i<480; i++) { for(j=0; j<800; j++) { if((j-400)*(j-400)+(i-240)*(i-240) <= k*k) { pic_circular_spread_fd[800*i+j] = mi_buf[800*i+j]; } } } } return 0; } /* 功能:切换BMP图片特效”向下飞入“。 参数: char *pathname:图片的路径。 int *pic_down_fd:被映射区的指针。 返回值:成功 0 失败 -1 */ int pic_down(char *pathname, int* pic_down_fd) { int ret=0; int line=0; int block=0; int i=0, j=0, k=0; int bmp_fd=0; char bmp_buf[480*800*3]; int mi_buf[480*800]; int temp_buf[480*800]; memset(mi_buf,0,sizeof(mi_buf)); memset(bmp_buf,0,sizeof(bmp_buf)); memset(temp_buf,0,sizeof(temp_buf)); bmp_fd = open(pathname , O_RDONLY);//1、打开BMP格式图片 if(bmp_fd == -1) { printf("pic_down(), open bmp failed\n"); return -1; } ret = lseek(bmp_fd, 54 , SEEK_SET);//2、跳过bmp图片的前54个位置 if(ret == -1) { perror("pic_down(), lseek bmp failed\n"); return -1; } ret = read(bmp_fd , bmp_buf , sizeof(bmp_buf)); //4、取读图片像素 if(ret == -1) { printf("pic_down(), read bmp failed\n"); return -1; } close(bmp_fd);//5、关闭图片 for(i=0, j=0 ; i<800*480 ; i++, j+=3)//6、24bits 转 32bits控制变量 { temp_buf[i] = bmp_buf[j+2]<<16 | bmp_buf[j+1]<<8 | bmp_buf[j] ; } for(line=0 ; line <=480 ;line++)//7、解决图片上下颠倒问题 { for(i=0; i<=800 ; i++) mi_buf[800*line + i] = temp_buf[ (479-line)*800 + i ]; } //8、特殊动画“向下飞入”效果算法 for(i=0; i<480; i++) { for(j=0; j<800; j++) { pic_down_fd[800*i+j] = mi_buf[800*i+j]; } usleep(1000); } return 0; } /* 功能:切换BMP图片特效”向上飞入“。 参数: char *pathname:图片的路径。 int *pic_up_fd:被映射区的指针。 返回值:成功 0 失败 -1 */ int pic_up(char *pathname, int* pic_up_fd) { int ret=0; int line=0; int block=0; int i=0, j=0, k=0; int bmp_fd=0; char bmp_buf[480*800*3]; int mi_buf[480*800]; int temp_buf[480*800]; memset(mi_buf,0,sizeof(mi_buf)); memset(bmp_buf,0,sizeof(bmp_buf)); memset(temp_buf,0,sizeof(temp_buf)); bmp_fd = open(pathname , O_RDONLY);//1、打开BMP格式图片 if(bmp_fd == -1) { printf("pic_up(), open bmp failed\n"); return -1; } ret = lseek(bmp_fd, 54 , SEEK_SET);//2、跳过bmp图片的前54个位置 if(ret == -1) { perror("pic_up(), lseek bmp failed\n"); return -1; } ret = read(bmp_fd , bmp_buf , sizeof(bmp_buf)); //4、取读图片像素 if(ret == -1) { printf("pic_up(), read bmp failed\n"); return -1; } close(bmp_fd);//5、关闭图片 for(i=0, j=0 ; i<800*480 ; i++, j+=3)//6、24bits 转 32bits控制变量 { temp_buf[i] = bmp_buf[j+2]<<16 | bmp_buf[j+1]<<8 | bmp_buf[j] ; } for(line=0 ; line <=480 ;line++)//7、解决图片上下颠倒问题 { for(i=0; i<=800 ; i++) mi_buf[800*line + i] = temp_buf[ (479-line)*800 + i ]; } //8、特殊动画“向上飞入”效果算法 for(i=479; i>=0; i--) { for(j=0; j<800; j++) { pic_up_fd[800*i+j] = mi_buf[800*i+j]; } usleep(500); } return 0; } /* 功能:切换BMP图片特效”向左飞入“。 参数: char *pathname:图片的路径。 int *pic_left_fd:被映射区的指针。 返回值:成功 0 失败 -1 */ int pic_left(char *pathname, int* pic_left_fd) { int ret=0; int line=0; int block=0; int i=0, j=0, k=0; int bmp_fd=0; char bmp_buf[480*800*3]; int mi_buf[480*800]; int temp_buf[480*800]; memset(mi_buf,0,sizeof(mi_buf)); memset(bmp_buf,0,sizeof(bmp_buf)); memset(temp_buf,0,sizeof(temp_buf)); bmp_fd = open(pathname , O_RDONLY);//1、打开BMP格式图片 if(bmp_fd == -1) { printf("pic_left(), open bmp failed\n"); return -1; } ret = lseek(bmp_fd, 54 , SEEK_SET);//2、跳过bmp图片的前54个位置 if(ret == -1) { perror("pic_left(), lseek bmp failed\n"); return -1; } ret = read(bmp_fd , bmp_buf , sizeof(bmp_buf)); //4、取读图片像素 if(ret == -1) { printf("pic_left(), read bmp failed\n"); return -1; } close(bmp_fd);//5、关闭图片 for(i=0, j=0 ; i<800*480 ; i++, j+=3)//6、24bits 转 32bits控制变量 { temp_buf[i] = bmp_buf[j+2]<<16 | bmp_buf[j+1]<<8 | bmp_buf[j] ; } for(line=0 ; line <=480 ;line++)//7、解决图片上下颠倒问题 { for(i=0; i<=800 ; i++) mi_buf[800*line + i] = temp_buf[ (479-line)*800 + i ]; } //8、特殊动画“向左飞入”效果算法 for(j=799; j>=0; j--) { for(i=0; i<480; i++) { pic_left_fd[800*i+j] = mi_buf[800*i+j]; } usleep(500); } return 0; } /* 功能:切换BMP图片特效”向右飞入“。 参数: char *pathname:图片的路径。 int *pic_right_fd:被映射区的指针。 返回值:成功 0 失败 -1 */ int pic_right(char *pathname, int* pic_right_fd) { int ret=0; int line=0; int block=0; int i=0, j=0, k=0; int bmp_fd=0; char bmp_buf[480*800*3]; int mi_buf[480*800]; int temp_buf[480*800]; memset(mi_buf,0,sizeof(mi_buf)); memset(bmp_buf,0,sizeof(bmp_buf)); memset(temp_buf,0,sizeof(temp_buf)); bmp_fd = open(pathname , O_RDONLY);//1、打开BMP格式图片 if(bmp_fd == -1) { printf("pic_right(), open bmp failed\n"); return -1; } ret = lseek(bmp_fd, 54 , SEEK_SET);//2、跳过bmp图片的前54个位置 if(ret == -1) { perror("pic_right(), lseek bmp failed\n"); return -1; } ret = read(bmp_fd , bmp_buf , sizeof(bmp_buf)); //4、取读图片像素 if(ret == -1) { printf("pic_right(), read bmp failed\n"); return -1; } close(bmp_fd);//5、关闭图片 for(i=0, j=0 ; i<800*480 ; i++, j+=3)//6、24bits 转 32bits控制变量 { temp_buf[i] = bmp_buf[j+2]<<16 | bmp_buf[j+1]<<8 | bmp_buf[j] ; } for(line=0 ; line <=480 ;line++)//7、解决图片上下颠倒问题 { for(i=0; i<=800 ; i++) mi_buf[800*line + i] = temp_buf[ (479-line)*800 + i ]; } //8、特殊动画“向右飞入”效果算法 for(j=0; j<800; j++) { for(i=0; i<480; i++) { pic_right_fd[800*i+j] = mi_buf[800*i+j]; } usleep(500); } return 0; }
用户界面开发
登录系统
- 实现注册功能(
log_keyboard()
函数) -
void log_keyboard() { int value = 0; int len = 0, x = 0, y = 0; char user[500] = {0}; char key[500] = {0}; // 初始化LCD LcdDevice *lcd = init_lcd(LCD_DEV_PATH); if (lcd == NULL) { printf("初始化LCD失败!\n"); return; } while (1) { touch_xy(&x, &y); // 退出主循环 if (x >= 639 && x <= 776 && y >= 5 && y <= 72) { printf("\n你选择了退出\n"); sigup_value=1; memset(key, 0, sizeof(key)); memset(user, 0, sizeof(user)); break; } //注册按钮 if (x >= 641 && x <= 800 && y >= 413 && y <= 480) { sigup_value=0; memset(key, 0, sizeof(key)); memset(user, 0, sizeof(user)); break; } // 选择输入账号 if (x >= 258 && x <= 560 && y >= 39 && y <= 89) { len = 0; printf("\n你选择了输入账号\n"); while (1) { x = 0; y = 0; touch_xy(&x, &y); // // 处理退出按钮 // if (x >= 646 && x <= 800 && y >= 16 && y <= 71) { // sigup_value=1; // break; // } // 处理其他区域的按钮 if (x >= 651 && x <= 767 && y >= 420 && y <= 462) { // 执行相关逻辑 } else { // 处理数字输入 if (x >= 245 && x <= 333 && y >= 190 && y <= 238) { user[len] = '1'; printf("user[%d]=%c\n", len, user[len]); // 显示数据 show_data(lcd, user, 261, 46, 295, 39); len++; } else if (x >= 353 && x <= 442 && y >= 190 && y <= 238) { user[len] = '2'; printf("user[%d]=%c\n", len, user[len]); // 显示数据 show_data(lcd, user, 261, 46, 295, 39); len++; } else if (x >= 460 && x <= 549 && y >= 190 && y <= 238) { user[len] = '3'; printf("user[%d]=%c\n", len, user[len]); // 显示数据 show_data(lcd, user, 261, 46, 295, 39); len++; } else if (x >= 245 && x <= 334 && y >= 251 && y <= 298) { user[len] = '4'; printf("user[%d]=%c\n", len, user[len]); // 显示数据 show_data(lcd,user, 261, 46, 295, 39); len++; } else if (x >= 353 && x <= 442 && y >= 250 && y <= 298) { user[len] = '5'; printf("user[%d]=%c\n", len, user[len]); show_data(lcd, user, 261, 46, 295, 39); len++; } else if (x >= 460 && x <= 549 && y >= 250 && y <= 298) { user[len] = '6'; printf("user[%d]=%c\n", len, user[len]); show_data(lcd, user, 261, 46, 295, 39); len++; } else if (x >= 245 && x <= 333 && y >= 310 && y <= 357) { user[len] = '7'; printf("user[%d]=%c\n", len, user[len]); // 显示数据 show_data(lcd, user, 261, 46, 295, 39); len++; } else if (x >= 353 && x <= 442 && y >= 310 && y <= 359) { user[len] = '8'; printf("user[%d]=%c\n", len, user[len]); // 显示数据 show_data(lcd, user, 261, 46, 295, 39); len++; } else if (x >= 460 && x <= 549 && y >= 310 && y <= 359) { user[len] = '9'; printf("user[%d]=%c\n", len, user[len]); // 显示数据 show_data(lcd,user, 261, 46, 295, 39); len++; } else if (x >= 353 && x <= 442 && y >= 371 && y <= 418) { user[len] = '0'; printf("user[%d]=%c\n", len, user[len]); // 显示数据 show_data(lcd, user, 261, 46, 295, 39); len++; } // 处理退格键 else if (x >= 245 && x <= 334 && y >= 370 && y <= 418) { printf("\n你按了退格键\n"); if (len > 0) { len--; user[len] = '\0'; // 显示数据 show_data(lcd, user, 261, 46, 295, 39); } } // 处理确认键 else if (x >= 461 && x <= 548 && y >= 371 && y <= 418) { printf("\n你按了确认键\n"); FILE *file = fopen("user.txt", "w"); if (file == NULL) { printf("无法打开文件\n"); } else { for (int i = 0; i < len; i++) { fprintf(file, "%c", user[i]); } fclose(file); } printf("数字已写入文件\n"); memset(user, 0, sizeof(user)); break; } } } } // 选择输入密码 else if (x >= 258 && x <= 560 && y >= 39 && y <= 160) { len = 0; printf("\n你选择了输入密码\n"); while (1) { x = 0; y = 0; touch_xy(&x, &y); // 处理确认按钮 if (x >= 650 && x <= 767 && y >= 22 && y <= 67) { break; } // 处理其他区域的按钮 else if (x >= 651 && x <= 767 && y >= 420 && y <= 462) { // 执行相关逻辑 } else { // 处理数字输入 if (x >= 245 && x <= 333 && y >= 190 && y <= 238) { key[len] = '1'; // 显示数据 show_data(lcd, key, 261, 120, 295, 36); printf("key[%d]=%c\n", len, key[len]); len++; } else if (x >= 353 && x <= 442 && y >= 190 && y <= 238) { key[len] = '2'; printf("key[%d]=%c\n", len, key[len]); // 显示数据 show_data(lcd, key, 261, 120, 295, 36); len++; } else if (x >= 460 && x <= 549 && y >= 190 && y <= 238) { key[len] = '3'; printf("key[%d]=%c\n", len, key[len]); // 显示数据 show_data(lcd, key, 261, 120, 295, 36); len++; } else if (x >= 245 && x <= 334 && y >= 251 && y <= 298) { key[len] = '4'; printf("key[%d]=%c\n", len, key[len]); // 显示数据 show_data(lcd, key, 261, 120, 295, 36); len++; } else if (x >= 353 && x <= 442 && y >= 250 && y <= 298) { key[len] = '5'; printf("key[%d]=%c\n", len, key[len]); // 显示数据 show_data(lcd, key, 261, 120, 295, 36); len++; } else if (x >= 460 && x <= 549 && y >= 250 && y <= 298) { key[len] = '6'; printf("key[%d]=%c\n", len, key[len]); // 显示数据 show_data(lcd, key, 261, 120, 295, 36); len++; } else if (x >= 245 && x <= 333 && y >= 310 && y <= 357) { key[len] = '7'; printf("key[%d]=%c\n", len, key[len]); // 显示数据 show_data(lcd, key, 261, 120, 295, 36); len++; } else if (x >= 353 && x <= 442 && y >= 310 && y <= 359) { key[len] = '8'; printf("key[%d]=%c\n", len, key[len]); // 显示数据 show_data(lcd, key, 261, 120, 295, 36); len++; } else if (x >= 460 && x <= 549 && y >= 310 && y <= 359) { key[len] = '9'; printf("key[%d]=%c\n", len, key[len]); // 显示数据 show_data(lcd, key, 261, 120, 295, 36); len++; } else if (x >= 353 && x <= 442 && y >= 371 && y <= 418) { key[len] = '0'; printf("key[%d]=%c\n", len, key[len]); // 显示数据 show_data(lcd, key, 261, 120, 295, 36); len++; } // 处理退格键 else if (x >= 245 && x <= 334 && y >= 370 && y <= 418) { printf("\n你按了退格键\n"); if (len > 0) { len--; key[len] = '\0'; // 显示数据 show_data(lcd, key, 261, 120, 295, 36); } } // 处理确认键 else if (x >= 461 && x <= 548 && y >= 371 && y <= 418) { printf("\n你按了确认键\n"); FILE *file = fopen("key.txt", "w"); if (file == NULL) { printf("无法打开文件\n"); } else { for (int i = 0; i < len; i++) { fprintf(file, "%c", key[i]); } fclose(file); } printf("数字已写入文件\n"); memset(key, 0, sizeof(key)); break; } } } } } bk: printf("\n"); // 清理资源 munmap(lcd->buffer, LCD_W * LCD_H * 4); free(lcd); }
- 实现登录功能(
log_in()
函数)与注册类似 - 创建用户数据和密码存储文件(user.txt和key.txt)
主菜单
- 设计并实现主菜单界面
-
#include <stdio.h> #include "header.h" int fifo_fd, fifo; int x, y; char key[52]; char password[52]; int n=0; // 用于线程的 showtime 函数 void* showtime_thread(void* arg) { while (1) { showtime(); } return NULL; } int main() { // 创建一个线程运行 showtime pthread_t thread; pthread_create(&thread, NULL, showtime_thread, NULL); while (1) { Begin: // 登录页面 all_bmp("./bmp/backgrand.bmp", 0, 0, 800, 480); touch_xy(&x, &y); if (x >= 491 && x <= 641 && y >= 418 && y <= 461) { all_bmp("./bmp/sigup.bmp", 0, 0, 800, 480); log_keyboard(); printf("sigup_value=%d\n",sigup_value); if(1==sigup_value) { goto Begin; } else { goto login; } } else if (x >= 163 && x <= 332 && y >= 415 && y <= 459) { login: all_bmp("./bmp/sigin.bmp", 0, 0, 800, 480); log_in(); if(1==login_value) { goto Begin; } //账号对比 FILE *file1 = fopen("user.txt", "r"); if (file1 == NULL) { printf("无法打开文件\n"); continue; } int len = 0; while (fscanf(file1, "%c", &user[len]) != EOF && len < sizeof(key)-1) { len++; } user[len] = '\0'; fclose(file1); printf("从文件读取的账号是: %s\n", user); printf("输入的账号是=%s\n", username); int value1 = strcmp(user, username); printf("value1=%d\n", value1); memset(user, 0, sizeof(user)); memset(username, 0, sizeof(username)); //密码对比 FILE *file = fopen("key.txt", "r"); if (file == NULL) { printf("无法打开文件\n"); continue; } len = 0; while (fscanf(file, "%c", &key[len]) != EOF && len < sizeof(key)-1) { len++; } key[len] = '\0'; fclose(file); printf("从文件读取的密码: %s\n", key); printf("输入的密码是=%s\n", password); int value2 = strcmp(key, password); printf("value2=%d\n", value2); memset(key, 0, sizeof(key)); memset(password, 0, sizeof(password)); if (value1 == 0&& value2 == 0) { printf("密码正确!\n"); while (1) { all_bmp("./bmp/view.bmp", 0, 0, 800, 480); touch_xy(&x, &y); if (x >= 49 && x <= 350 && y >= 39 && y <= 194) { printf("游戏区\n"); all_bmp("./picture/game_bg.bmp", 0, 0, 800, 480); sleep(1); if(0==n) { n=vip(); printf("n=%d\n",n); } while(n) { all_bmp("./picture/game_bg.bmp", 0, 0, 800, 480); touch_xy(&x, &y); if(x>=50&&x<=371&&y>=50&&y<=229) { printf("飞机大战\n"); game_loop(); printf("飞机大战游戏结束\n"); } else if(x>=430&&x<=751&&y>=50&&y<=229) { printf("2048\n"); start_2048_game(); printf("2048游戏结束\n"); } else if(x>=50&&x<=371&&y>=250&&y<=429) { printf("扫雷\n"); Minesweeper(); printf("扫雷游戏结束\n"); } else if(x>=429&&x<=749&&y>=250&&y<=427) { printf("五子棋\n"); wzq(); printf("五子棋游戏结束\n"); } else if(x>=695&&x<=800&&y>=436&&y<=480) { break; } } } else if (x >= 452 && x <= 746 && y >= 37 && y <= 194) { printf("音乐区\n"); run_music_player(); } else if (x >= 49 && x <= 347 && y >= 239 && y <= 393) { printf("视频区\n"); video(); } else if (x >= 453 && x <= 748 && y >= 239 && y <= 395) { printf("图片区\n"); imageshow(); } else if (x >= 352 && x <= 450 && y >= 424 && y <= 452) { printf("退出\n"); goto Begin; } } } else { printf("密码错误,显示错误信息\n"); all_bmp("./bmp/error.bmp", 280, 12, 239, 57); } } return 0; } }
功能区域
- 实现游戏区、音乐区、视频区和图片区的基本界面
while (1) { Begin: // 登录页面 all_bmp("./bmp/backgrand.bmp", 0, 0, 800, 480); touch_xy(&x, &y); if (x >= 491 && x <= 641 && y >= 418 && y <= 461) { all_bmp("./bmp/sigup.bmp", 0, 0, 800, 480); log_keyboard(); printf("sigup_value=%d\n",sigup_value); if(1==sigup_value) { goto Begin; } else { goto login; } } else if (x >= 163 && x <= 332 && y >= 415 && y <= 459) { login: all_bmp("./bmp/sigin.bmp", 0, 0, 800, 480); log_in(); if(1==login_value) { goto Begin; } //账号对比 FILE *file1 = fopen("user.txt", "r"); if (file1 == NULL) { printf("无法打开文件\n"); continue; } int len = 0; while (fscanf(file1, "%c", &user[len]) != EOF && len < sizeof(key)-1) { len++; } user[len] = '\0'; fclose(file1); printf("从文件读取的账号是: %s\n", user); printf("输入的账号是=%s\n", username); int value1 = strcmp(user, username); printf("value1=%d\n", value1); memset(user, 0, sizeof(user)); memset(username, 0, sizeof(username)); //密码对比 FILE *file = fopen("key.txt", "r"); if (file == NULL) { printf("无法打开文件\n"); continue; } len = 0; while (fscanf(file, "%c", &key[len]) != EOF && len < sizeof(key)-1) { len++; } key[len] = '\0'; fclose(file); printf("从文件读取的密码: %s\n", key); printf("输入的密码是=%s\n", password); int value2 = strcmp(key, password); printf("value2=%d\n", value2); memset(key, 0, sizeof(key)); memset(password, 0, sizeof(password)); if (value1 == 0&& value2 == 0) { printf("密码正确!\n"); while (1) { all_bmp("./bmp/view.bmp", 0, 0, 800, 480); touch_xy(&x, &y); if (x >= 49 && x <= 350 && y >= 39 && y <= 194) { printf("游戏区\n"); all_bmp("./picture/game_bg.bmp", 0, 0, 800, 480); sleep(1); if(0==n) { n=vip(); printf("n=%d\n",n); } while(n) { all_bmp("./picture/game_bg.bmp", 0, 0, 800, 480); touch_xy(&x, &y); if(x>=50&&x<=371&&y>=50&&y<=229) { printf("飞机大战\n"); game_loop(); printf("飞机大战游戏结束\n"); } else if(x>=430&&x<=751&&y>=50&&y<=229) { printf("2048\n"); start_2048_game(); printf("2048游戏结束\n"); } else if(x>=50&&x<=371&&y>=250&&y<=429) { printf("扫雷\n"); Minesweeper(); printf("扫雷游戏结束\n"); } else if(x>=429&&x<=749&&y>=250&&y<=427) { printf("五子棋\n"); wzq(); printf("五子棋游戏结束\n"); } else if(x>=695&&x<=800&&y>=436&&y<=480) { break; } } } else if (x >= 452 && x <= 746 && y >= 37 && y <= 194) { printf("音乐区\n"); run_music_player(); } else if (x >= 49 && x <= 347 && y >= 239 && y <= 393) { printf("视频区\n"); video(); } else if (x >= 453 && x <= 748 && y >= 239 && y <= 395) { printf("图片区\n"); imageshow(); } else if (x >= 352 && x <= 450 && y >= 424 && y <= 452) { printf("退出\n"); goto Begin; } } } else { printf("密码错误,显示错误信息\n"); all_bmp("./bmp/error.bmp", 280, 12, 239, 57); } } return 0; }
游戏模块开发
VIP验证
- 实现
vip()
函数,用于验证用户VIP状态 -
#include"header.h" int len=0; int vipkey=1; char cdk[10]="12345678"; char buycdk[10]={0}; int vip1=1; int vip() { // 初始化LCD LcdDevice *lcd = init_lcd(LCD_DEV_PATH); if (lcd == NULL) { printf("初始化LCD失败!\n"); return 0; } if(vipkey) { all_bmp("./bmp/buygame.bmp", 275, 165, 250, 150); while(1) { char nr[100]="请扫码购买cdk激活:"; char nr1[100]="已购买请点击二维码:"; show_data(lcd, nr, 240, 50, 300, 40); show_data(lcd, nr1, 240, 90, 300, 40); all_bmp("./bmp/buygame.bmp", 275, 165, 250, 150); touch_xy(&x, &y); if (x >= 275 && x <= 625 && y >= 165 && y <= 315) { all_bmp("./bmp/cdk.bmp", 0, 0, 800,480); while(1) { touch_xy(&x, &y); if (x >= 245 && x <= 333 && y >= 190 && y <= 238) { buycdk[len] = '1'; printf("buycdk[%d]=%c\n", len, buycdk[len]); // 显示数据 show_data(lcd, buycdk, 263, 83, 294, 41); len++; } else if (x >= 353 && x <= 442 && y >= 190 && y <= 238) { buycdk[len] = '2'; printf("buycdk[%d]=%c\n", len, buycdk[len]); // 显示数据 show_data(lcd, buycdk, 263, 83, 294, 41); len++; } else if (x >= 460 && x <= 549 && y >= 190 && y <= 238) { buycdk[len] = '3'; printf("buycdk[%d]=%c\n", len, buycdk[len]); // 显示数据 show_data(lcd, buycdk, 263, 83, 294, 41); len++; } else if (x >= 245 && x <= 334 && y >= 251 && y <= 298) { buycdk[len] = '4'; printf("buycdk[%d]=%c\n", len, buycdk[len]); // 显示数据 show_data(lcd, buycdk, 263, 83, 294, 41); len++; } else if (x >= 353 && x <= 442 && y >= 250 && y <= 298) { buycdk[len] = '5'; printf("buycdk[%d]=%c\n", len, buycdk[len]); // 显示数据 show_data(lcd, buycdk, 263, 83, 294, 41); len++; } else if (x >= 460 && x <= 549 && y >= 250 && y <= 298) { buycdk[len] = '6'; printf("buycdk[%d]=%c\n", len, buycdk[len]); // 显示数据 show_data(lcd, buycdk, 263, 83, 294, 41); len++; } else if (x >= 245 && x <= 333 && y >= 310 && y <= 357) { buycdk[len] = '7'; printf("buycdk[%d]=%c\n", len, buycdk[len]); // 显示数据 show_data(lcd, buycdk, 263, 83, 294, 41); len++; } else if (x >= 353 && x <= 442 && y >= 310 && y <= 359) { buycdk[len] = '8'; printf("buycdk[%d]=%c\n", len, buycdk[len]); show_data(lcd, buycdk, 263, 83, 294, 41); len++; } else if (x >= 460 && x <= 549 && y >= 310 && y <= 359) { buycdk[len] = '9'; printf("buycdk[%d]=%c\n", len, buycdk[len]); // 显示数据 show_data(lcd, buycdk, 263, 83, 294, 41); len++; } else if (x >= 353 && x <= 442 && y >= 371 && y <= 418) { buycdk[len] = '0'; printf("buycdk[%d]=%c\n", len, buycdk[len]); // 显示数据 show_data(lcd, buycdk, 263, 83, 294, 41); len++; } // 处理退格键 else if (x >= 245 && x <= 334 && y >= 370 && y <= 418) { printf("\n你按了退格键\n"); if (len > 0) { len--; buycdk[len] = '\0'; // 显示数据 show_data(lcd, buycdk, 261, 46, 295, 39); } } // 处理确认键 else if (x >= 461 && x <= 548 && y >= 371 && y <= 418) { printf("\n你按了确认键\n"); // sleep(3); buycdk[len] = '\0'; printf("buycdk=%s\n", buycdk); // sleep(3); printf("cdk=%s\n", cdk); // sleep(3); vipkey = strcmp(cdk, buycdk); printf("vipkey=%d\n", vipkey); // printf("buycdk: "); // for (int i = 0; i < len; i++) // { // printf("%c(%d) \n", buycdk[i], buycdk[i]); // sleep(1); // } // printf("\nbuycdk长度: %d\n", len); // printf("cdk: "); // for (int i = 0; i < 8; i++) // { // printf("%c(%d)\n ", cdk[i], cdk[i]); // sleep(1); // } // printf("\ncdk长度: %lu\n", strlen(cdk)); if(vipkey == 0) { printf("激活成功\n"); // 清理资源 memset(buycdk, 0, sizeof(buycdk)); munmap(lcd->buffer, LCD_W * LCD_H * 4); free(lcd); len=0; return 1; } else { printf("激活失败\n"); // 清理资源 memset(buycdk, 0, sizeof(buycdk)); munmap(lcd->buffer, LCD_W * LCD_H * 4); free(lcd); len=0; return 0; } } } } } } }
游戏实现
- 开发飞机大战游戏(
game_loop()
函数) -
#include <stdio.h> #include <sys/types.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/wait.h> #include <wait.h> #include <signal.h> #include "slide.h" #include "background.h" #include "own_side.h" #include "enemy.h" #define IPC_PATH ("./") #define IPC_CODE1 (20230826) #define IPC_CODE2 (20230904) #define IPC_CODE3 (20230905) int shmid; void game_loop() { // 创建System V IPC设施的key key_t key1 = ftok(IPC_PATH,IPC_CODE1); key_t key2 = ftok(IPC_PATH,IPC_CODE2); key_t key3 = ftok(IPC_PATH,IPC_CODE3); // 创建或打开一个共享内存 int shm_id1 = shmget(key1,128,IPC_CREAT|0600); int shm_id2 = shmget(key2,128,IPC_CREAT|0600); int shm_id3 = shmget(key3,128,IPC_CREAT|0600); // 映射共享内存 shm_px = shmat(shm_id1,NULL,0); shm_py = shmat(shm_id2,NULL,0); shm_p_num = shmat(shm_id3,NULL,0); //主界面 MAIN: Main_Interface(); while (1) { //主界面点击选择 if(direction()==0) { //退出 if(end_x>650 && end_x<800 &&end_y>0 &&end_y<150) { break; } //排行榜 else if(end_x>700 && end_x<800 &&end_y>360 &&end_y<480) { leaderboard(); while(direction()==0) { goto MAIN; } } //开始游戏 else if(end_x>70 && end_x<200 &&end_y>100 &&end_y<300) { again: Interface();//游戏界面 //创建两个进程,分别表示敌我双方 pid_t pid=fork(); //敌方 if(pid==0) { num=0; //循环创建敌机 while(1) { //最大同时生成6架敌机 pthread_t tid[6]; int MAX; //随机生成敌机数量 MAX=rand()%6+1; for (int i = 0; i < MAX; i++) { pthread_create(&tid[i], NULL, enemy_air, NULL); sleep(1.2); } //回收线程资源 for (int i = 0; i < MAX; i++) { pthread_join(tid[i], NULL); } //*shm_p_num =num; } } //我方 else { //飞机初始位置 draw_picture(0,190,"./picture/ourair.bmp"); while (real_time_location()) { *shm_py=end_y; *shm_px=end_x; //清除初始位置的飞机 draw_picture(0,190,"./picture/black.bmp"); int status; pid_t result = waitpid(pid, &status, WNOHANG);//非阻塞等待 //子进程未终止 if(result==0) { //游戏运行 if (end_x>0 && end_x<750 && end_y>0 && end_y<480) { //飞机与炮弹线程 our_air(); pthread_t tid; pthread_create(&tid,NULL,ball_track,NULL); pthread_join(tid,NULL); } //返回主界面 else if (end_x>750 && end_x<800 && end_y>0 && end_y<50) { kill(pid,SIGKILL); goto MAIN; } //暂停游戏 else if (end_x>750 && end_x<800 && end_y>400 && end_y<480) { draw_picture(350,140,"./picture/continue.bmp"); kill(pid, SIGSTOP); // 发送SIGSTOP信号暂停子进程 //获取到点击事件继续游戏 if(direction()==0) { kill(pid, SIGCONT); // 发送SIGUSR1信号唤醒子进程 draw_picture(0,0,"./picture/Interface.bmp"); } } } //子进程终止结束父进程 else if(result==pid) { //如果子进程结束游戏结束 if(WIFEXITED(status)) { char buf[4]; FILE* fd=fopen("./1.txt","a+"); snprintf(buf,sizeof(buf),"%.3d",*shm_p_num); fputs(buf,fd); fputc('\n',fd); fclose(fd); gameover(); } while(direction()==0) { //返回主界面 if(end_x>50 && end_x<=200) goto MAIN; else if(end_x>220 && end_x<=320) goto again; } } close_file(); } } } } } // 解除映射 shmdt(shm_px); shmdt(shm_py); // 关掉 shmctl(shm_id1,IPC_RMID,NULL); shmctl(shm_id2,IPC_RMID,NULL); return; }
- 开发2048游戏(
start_2048_game()
函数) -
#include "2048_yq.h" short map[4][4] = {0}; // 初始化游戏棋盘 // 游戏函数声明 void refresh_screen(); // 刷新整个屏幕 void join_numbers(char direction); // 数字整合 void add_number(); // 产生随机数字 void show_pic(int number, int x, int y); // 将单个图片放到目标位置 int touch_x; int touch_y; void start_2048_game(); void start_2048_game() { init_board(); // 初始化棋盘 add_number(); // 产生第一个随机数字 add_number(); // 产生第二个随机数字 refresh_screen(); // 刷新屏幕显示 while (1) { char direction = get_coordinates_and_direction(&touch_x, &touch_y); // 获取触摸屏方向 if (direction != NOT_MOVED) { join_numbers(direction); // 根据方向整合数字 } else if (touch_x >= COLUMN - 100 && touch_y >= ROW - 50) { // 点击退出区域,退出游戏 break; } } uninit_board(); // 释放资源,退出游戏 } void join_numbers(char direction) { char is_moved = 0; // 标志是否发生移动 switch (direction) { case UP: for (int i = 0; i < 4; i++) { int zero_point = 99; for (int j = 0; j < 4; j++) { if (map[j][i] == 0 && zero_point > j) { zero_point = j; } else if (zero_point != 99 && map[j][i] != 0) { map[zero_point][i] = map[j][i]; map[j][i] = 0; zero_point++; is_moved = 1; } } for (int j = 0; j < 3; j++) { if (map[j][i] == map[j + 1][i] && map[j][i] != 0) { map[j][i] *= 2; map[j + 1][i] = 0; j++; is_moved = 1; } } zero_point = 99; for (int j = 0; j < 4; j++) { if (map[j][i] == 0 && zero_point > j) { zero_point = j; } else if (zero_point != 99 && map[j][i] != 0) { map[zero_point][i] = map[j][i]; map[j][i] = 0; zero_point++; is_moved = 1; } } } break; case DOWN: for (int i = 0; i < 4; i++) { int zero_point = -99; for (int j = 3; j >= 0; j--) { if (map[j][i] == 0 && zero_point < j) { zero_point = j; } else if (zero_point != -99 && map[j][i] != 0) { map[zero_point][i] = map[j][i]; map[j][i] = 0; zero_point--; is_moved = 1; } } for (int j = 3; j > 0; j--) { if (map[j][i] == map[j - 1][i] && map[j][i] != 0) { map[j][i] *= 2; map[j - 1][i] = 0; j++; is_moved = 1; } } zero_point = -99; for (int j = 3; j >= 0; j--) { if (map[j][i] == 0 && zero_point < j) { zero_point = j; } else if (zero_point != -99 && map[j][i] != 0) { map[zero_point][i] = map[j][i]; map[j][i] = 0; zero_point--; is_moved = 1; } } } break; case LEFT: for (int j = 0; j < 4; j++) { int zero_point = 99; for (int i = 0; i < 4; i++) { if (map[j][i] == 0 && zero_point > i) { zero_point = i; } else if (zero_point != 99 && map[j][i] != 0) { map[j][zero_point] = map[j][i]; map[j][i] = 0; zero_point++; is_moved = 1; } } for (int i = 0; i < 3; i++) { if (map[j][i] == map[j][i + 1] && map[j][i] != 0) { map[j][i] *= 2; map[j][i + 1] = 0; i++; is_moved = 1; } } zero_point = 99; for (int i = 0; i < 4; i++) { if (map[j][i] == 0 && zero_point > i) { zero_point = i; } else if (zero_point != 99 && map[j][i] != 0) { map[j][zero_point] = map[j][i]; map[j][i] = 0; zero_point++; is_moved = 1; } } } break; case RIGHT: for (int j = 0; j < 4; j++) { int zero_point = -99; for (int i = 3; i >= 0; i--) { if (map[j][i] == 0 && zero_point < i) { zero_point = i; } else if (zero_point != -99 && map[j][i] != 0) { map[j][zero_point] = map[j][i]; map[j][i] = 0; zero_point--; is_moved = 1; } } for (int i = 3; i > 0; i--) { if (map[j][i] == map[j][i - 1] && map[j][i] != 0) { map[j][i] *= 2; map[j][i - 1] = 0; i++; is_moved = 1; } } zero_point = -99; for (int i = 3; i >= 0; i--) { if (map[j][i] == 0 && zero_point < i) { zero_point = i; } else if (zero_point != -99 && map[j][i] != 0) { map[j][zero_point] = map[j][i]; map[j][i] = 0; zero_point--; is_moved = 1; } } } break; } // 检查是否赢得比赛 for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (map[i][j] == 2048) { printf("赢了赢了赢了赢了赢了赢了赢了赢了\n"); refresh_screen(); show_pic_generic("./2048/win.bmp", 160, 0); sleep(3); return; } } } if (is_moved) { add_number(); refresh_screen(); } else { char is_lost = 1; for (int i = 0; i < 4; i++) { for (int j = 0; j < 3; j++) { if (map[i][j] == map[i][j + 1]) { is_lost = 0; break; } } if (!is_lost) break; } if (is_lost) { for (int j = 0; j < 4; j++) { for (int i = 0; i < 3; i++) { if (map[i][j] == map[i + 1][j]) { is_lost = 0; break; } } if (!is_lost) break; } } if (is_lost) { printf("输了输了输了输了输了输了输了输了\n"); refresh_screen(); show_pic_generic("./2048/lost.bmp", 213, 0); sleep(3); return; } } } void add_number() { char not_ok = 1; while (not_ok) { int x = rand() % 4; int y = rand() % 4; if (map[y][x] == 0) { map[y][x] = (rand() % 2 + 1) * 2; not_ok = 0; } } } void refresh_screen() { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { show_pic(map[j][i], i * COLUMN / 4, j * ROW / 4); printf("%d\t", map[i][j]); } printf("\n"); } show_pic_generic("./2048/exit.bmp", COLUMN - 100, ROW - 50); // 绘制退出按钮 } void show_pic(int number, int offset_x, int offset_y) { char img_path[20]; snprintf(img_path, sizeof(img_path), "./2048/%d.bmp", number); show_pic_generic(img_path, offset_x, offset_y); // 显示对应数字的图片 }
- 开发扫雷游戏(
Minesweeper()
函数) -
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <linux/fb.h> #include <stdlib.h> #include <linux/input.h> #include <time.h> #include "mines.h" #include "lcd.h" int Minesweeper() { int first = 1; char displayBoard[ROW][COL];//展示棋盘 char board[ROW][COL];//内部数据棋盘 //初始化屏幕 LCD_INIT(); //初始化游戏界面,并限制进入游戏区域 if(Initial()) { //第一次无条件开始游戏,first跟Restart不能替换位置,否则需要点两下 while (first || Restart()) { Creat_board(board);//初始化内部棋盘 Creat_board(displayBoard);//初始化展示棋盘 //设置背景板 DrawBackgournd(0xffffff); int X = -1;//初始化坐标 int Y = -1; //显示棋盘,最开始的时候无法结束游戏 Darw_board(0,board); //感应触摸屏幕将XY值修改成点击的坐标 Get_XY(&Y,&X); //获取到坐标之后开始进行游戏 Start_game(board,displayBoard,Y,X); //将frist置零,之后的循环条件都是判断Restart first = 0; } //游戏结束 DisplayBMPPicture(0,0,"./object/gameover.bmp"); sleep(1); //关闭屏幕 LCD_UNINIT(); return 0; } else { return 0; } }
- 开发五子棋游戏(
wzq()
函数) -
#include "LCD_Draw.h" #include "touch.h" #include "Judge.h" #include "menu.h" #include <string.h> const char *arr1[10]; int white_win_count = 0; int black_win_count = 0; int round1 = 0; typedef struct pathname { char str1[10]; // 封面路径 char str2[10]; // 棋盘右边的投降悔棋图片路径 char str3[10]; // 是否继续的图片路径 char str4[10]; // 白棋获胜 char str5[10]; // 黑棋获胜 char str6[10]; // 和棋4 char str7[10]; // 记录版 int count; } pathname; void game_continue(pathname path) { char arr[ROW][COL] = {0}; Arr_Init(arr); // 初始化字符数组 LCD_board_dispaly(); // LCD棋盘打印 Show_pictures(496, 0, "7.bmp"); // 打赢记录板子 LCD_Dispaly_Black_Recording_Board(black_win_count); LCD_Dispaly_white_Recording_Board(white_win_count); Show_pictures(496, 70, "2.bmp"); // 显示右边功能框 Touch_function(arr, "4.bmp", "5.bmp","6.bmp"); // 执行落子程序 } void game(pathname path) { char arr[ROW][COL] = {0}; Arr_Init(arr); // 初始化字符数组 LCD_board_dispaly(); // LCD棋盘打印 Show_pictures(496, 0, "7.bmp"); for (int i = 200; i >= 70; i--) { Show_pictures(496, i, "2.bmp"); // 显示右边功能框 } Touch_function(arr, "4.bmp", "5.bmp","6.bmp"); // 执行落子程序 loop1: // 打印是否继续游戏图片 Show_pictures(0, 0, "3.bmp"); if (Continue_or_quit()) { game_continue(path); if (round1 >= 5 || white_win_count >= 3 || black_win_count >= 3) { goto loop2; } goto loop1; } loop2: white_win_count = 0; black_win_count = 0; close(lcd_fd); // 关闭LCD_fd } void test(int *x, pathname path) { switch (*x = Select_Mode("1.bmp")) { case ONE: game(path); break; case TWO: printf("人机对战\n"); break; case ZERO: Show_End_Screen(); printf("退出游戏\n"); break; } } int wzq() { int x; pathname path; do { test(&x, path); } while (x); return 0; }
媒体功能实现
- 实现音乐播放器(
run_music_player()
函数) -
#include "header.h" int music_playing = 0; int i = 1; void run_music_player() { // 初始化LCD LcdDevice *lcd = init_lcd(LCD_DEV_PATH); if (lcd == NULL) { printf("初始化LCD失败!\n"); return; } int x, y; static int last_x = 0, last_y = 0; static unsigned long last_time = 0; unsigned long current_time; char buf[10000]; int current_position = 0; while (1) { music_menu: all_bmp("./music/music_bg.bmp", 0, 0, 800, 480); touch_xy(&x, &y); if (x > 0 && x < 800 && y > 47 && y < 109) i = 1; else if (x > 0 && x < 800 && y > 109 && y < 183) i = 2; else if (x > 0 && x < 800 && y > 183 && y < 258) i = 3; else if (x > 0 && x < 800 && y > 258 && y < 329) i = 4; else if (x > 0 && x < 800 && y > 329 && y < 398) i = 5; else if (x > 0 && x < 800 && y > 398 && y < 480) i = 6; else if (x > 711 && x < 800 && y > 0 && y < 45) { printf("退出\n"); system("killall -9 madplay"); return; } else continue; printf("播放第%d首音乐\n", i); snprintf(buf, sizeof(buf), "madplay ./music/%d.mp3 &", i); system(buf); break; } while (1) { touch_xy(&x, &y); all_bmp("./music/music.bmp", 0, 0, 800, 480); // // 显示图片 if(1==i) { all_bmp("./music/1.bmp", 28, 90, 353, 252); char a[]="美人鱼"; show_data(lcd, a, 86, 31, 270, 31); } else if(2==i) { all_bmp("./music/2.bmp", 28, 90, 353, 252); char a[]="江南"; show_data(lcd, a, 86, 31, 270, 31); } else if(3==i) { all_bmp("./music/3.bmp", 28, 90, 353, 252); char a[]="心墙"; show_data(lcd, a, 86, 31, 270, 31); } else if(4==i) { all_bmp("./music/4.bmp", 28, 90, 353, 252); char a[]="达尔文"; show_data(lcd, a, 86, 31, 270, 31); } else if(5==i) { all_bmp("./music/5.bmp", 28, 90, 353, 252); char a[]="愿与愁"; show_data(lcd, a, 86, 31, 270, 31); } else if(6==i) { all_bmp("./music/6.bmp", 28, 90, 353, 252); char a[]="Loving Strangers"; show_data(lcd, a, 86, 31, 270, 31); } // 音乐播放/暂停双击控制 if (x > 318 && x < 396 && y > 397 && y < 480) { current_time = time(NULL); if (abs(x - last_x) < 10 && abs(y - last_y) < 10 && current_time - last_time < 1) { static int is_playing = 1; if (is_playing) { printf("暂停音乐\n"); system("killall -19 madplay"); is_playing = 0; } else { printf("继续播放音乐\n"); system("killall -18 madplay"); is_playing = 1; } } last_x = x; last_y = y; last_time = current_time; } // 切换上一首音乐 else if (x > 134 && x < 215 && y > 384 && y < 480) { printf("切换上一首音乐\n"); system("killall -SIGKILL madplay"); if (--i == 0) i = 6; snprintf(buf, sizeof(buf), "madplay ./music/%d.mp3 &", i); system(buf); } // 切换下一首音乐 else if (x > 491 && x < 573 && y > 384 && y < 480) { printf("切换下一首音乐\n"); system("killall -SIGKILL madplay"); if (++i == 7) i = 1; snprintf(buf, sizeof(buf), "madplay ./music/%d.mp3 &", i); system(buf); } // 快进10秒 else if (x > 413 && x < 490 && y > 384 && y < 480) { printf("快进10秒\n"); system("killall -SIGKILL madplay"); snprintf(buf, sizeof(buf), "madplay ./music/%d.mp3 --start=%d &", i, current_position + 10); system(buf); } // 快退10秒 else if (x > 220 && x < 306 && y > 384 && y < 480) { printf("快退10秒\n"); system("killall -SIGKILL madplay"); snprintf(buf, sizeof(buf), "madplay ./music/%d.mp3 --start=%d &", i, current_position - 10); system(buf); } // 音量控制 else if (x > 658 && x < 731 && y > 384 && y < 480) { printf("音量+\n"); system("amixer sset 'Master' 10%+"); } else if (x > 575 && x < 654 && y > 384 && y < 480) { printf("音量-\n"); system("amixer sset 'Master' 10%-"); } // 返回歌单 else if (x > 731 && x < 800 && y > 411 && y < 480) { printf("歌单\n"); system("killall -SIGKILL madplay"); goto music_menu; } // 退出音乐播放 else if (x > 44 && x < 125 && y > 402 && y < 480) { printf("退出音乐播放\n"); system("killall -SIGKILL madplay"); all_bmp("./music/music_bg.bmp", 0, 0, 800, 480); break; // 清理资源 munmap(lcd->buffer, LCD_W * LCD_H * 4); free(lcd); } } }
- 实现视频播放功能(
video()
函数) -
#include "header.h" void video() { int Send_Cmd(char *cmd); char buf[10000]={0}; int x, y; int i = 1; // 0. 判断管道文件是否存在 if(access("/tmp/myfifo", F_OK) == -1) { printf("您没有创建管道文件\n"); printf("正在创建管道文件...\n"); sleep(1); // 1. 创建管道文件 fifo = mkfifo("/tmp/myfifo", 0777); if(fifo == -1) { perror("创建管道文件失败"); return; } } else { printf("您已创建管道文件,无需重复创建\n"); } // 2. 打开管道文件 fifo_fd = open("/tmp/myfifo", O_RDWR); if(fifo_fd == -1) { perror("打开管道文件失败"); return; } menu: printf("重新选择\n"); all_bmp("./video/menu.bmp", 0, 0, 800, 480); // 3. 播放视频 while(1) { touch_xy(&x, &y); if(x > 64 && x < 261 && y > 52 && y < 182) i = 1; else if(x > 319 && x < 517 && y > 53 && y < 182) i = 2; else if(x > 566 && x < 763 && y > 52 && y < 183) i = 3; else if(x > 51 && x < 259 && y > 274 && y < 402) i = 4; else if(x > 320 && x < 517 && y > 269 && y < 397) i = 5; else if(x > 572 && x < 769 && y > 269 && y < 396) i = 6; else if(x > 715 && x < 800 && y > 435 && y < 480) return; else continue; printf("播放第%d个视频\n", i); printf("i=%d\n",i); sprintf(buf, "mplayer -slave -quiet -loop 0 -input file=/tmp/myfifo -geometry 0:0 -zoom -x 800 -y 410 ./video/%d.mp4 &", i); system(buf); printf("i=%d\n",i); break; } printf("i=%d\n",i); sleep(3); // 4. 播放控制 while(1) { all_bmp("./video/backgrand.bmp", 0, 0, 800, 480); touch_xy(&x, &y); if(x > 378 && x < 440 && y > 410 && y < 480) { printf("暂停 继续!\n"); Send_Cmd("pause\n"); } else if(x > 126 && x < 175 && y > 410 && y < 480) { printf("音量+!\n"); Send_Cmd("volume +200\n"); } else if(x > 64 && x < 114 && y > 410 && y < 480) { printf("静音!\n"); } else if(x > 0 && x < 56 && y > 410 && y < 480) { printf("音量-!\n"); Send_Cmd("volume -200\n"); } else if(x > 467 && x < 528 && y > 400 && y < 480) { printf("快进!\n"); Send_Cmd("seek +10\n"); } else if(x > 286 && x < 347 && y > 410 && y < 480) { printf("快退!\n"); Send_Cmd("seek -10\n"); } else if(x > 198 && x < 248 && y > 410 && y < 480) { printf("上一个视频!\n"); system("killall -9 mplayer"); i--; if (i == 0) i = 6; sprintf(buf, "mplayer -slave -loop 0 -quiet -input file=/tmp/myfifo -geometry 0:0 -zoom -x 800 -y 410 ./video/%d.mp4 &", i); system(buf); } else if(x > 564 && x < 613 && y > 410 && y < 480) { printf("下一个视频!\n"); printf("i=%d\n",i); sleep(3); system("killall -9 mplayer"); i++; if (i == 7) i = 1; printf("i=%d\n",i); sprintf(buf, "mplayer -slave -loop 0 -quiet -input file=/tmp/myfifo -geometry 0:0 -zoom -x 800 -y 410 ./video/%d.mp4 &", i); system(buf); } else if(x > 645 && x < 710 && y > 410 && y < 480) { printf("菜单!\n"); system("killall -9 mplayer"); goto menu; } else if(x > 738 && x < 800 && y > 410 && y < 480) { printf("退出!\n"); system("killall -9 mplayer"); break; } } } //发送命令的函数 int Send_Cmd(char *cmd) // Send_Cmd("volume +10\n"); { //往管道文件中写指令 write(fifo_fd,cmd,strlen(cmd)); return 0; }
- 实现图片浏览功能(
imageshow()
函数) -
#include "header.h" #define SLIDE_COUNT_THRESHOLD 3 int first_x; int first_y; int imageshow() { int i = 1; int slide_right_count = 0; int slide_left_count = 0; int slide_up_count = 0; int slide_down_count = 0; bg: all_bmp("./image/bg.bmp", 0, 0, 800, 480); all_bmp("./image/7.bmp", 50, 40, 200, 120); all_bmp("./image/8.bmp", 300, 40, 200, 120); all_bmp("./image/9.bmp", 550, 40, 200, 120); all_bmp("./image/10.bmp", 50, 200, 200, 120); all_bmp("./image/11.bmp", 300, 200, 200, 120); all_bmp("./image/12.bmp", 550, 200, 200, 120); int x, y; touch_xy(&x, &y); // Print touch coordinates for debugging printf("Touch coordinates: x = %d, y = %d\n", x, y); if (50 <= x && x <= 250 && 40 <= y && y <= 160) { all_bmp("./image/1.bmp", 0, 0, 800, 480); printf("1\n"); } else if (300 <= x && x <= 500 && 40 <= y && y <= 160) { all_bmp("./image/2.bmp", 0, 0, 800, 480); printf("2\n"); } else if (550 <= x && x <= 750 && 40 <= y && y <= 160) { all_bmp("./image/3.bmp", 0, 0, 800, 480); printf("3\n"); } else if (50 <= x && x <= 250 && 200 <= y && y <= 320) { all_bmp("./image/4.bmp", 0, 0, 800, 480); printf("4\n"); } else if (300 <= x && x <= 500 && 200 <= y && y <= 320) { all_bmp("./image/5.bmp", 0, 0, 800, 480); printf("5\n"); } else if (550 <= x && x <= 750 && 200 <= y && y <= 320) { all_bmp("./image/6.bmp", 0, 0, 800, 480); printf("6\n"); } else if (695 <= x && x <= 786 && 400 <= y && y <= 436) { return 0; printf("返回\n"); } int file_fd = open("/dev/fb0", O_RDWR); if (file_fd == -1) { printf("open /dev/fb0 fail!\n"); return -1; } int *init_mmap_fd = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, file_fd, 0); if (init_mmap_fd == MAP_FAILED) { printf("mmap lcd fail!\n"); close(file_fd); return -1; } while (1) { int points = 0; double total_angle = 0.0; double distance = 0.0; long elapsed_time = 0; slip_xy(&points, &total_angle, &distance, &elapsed_time); // 滑动检测 printf("Distance: %f, Elapsed Time: %ld\n", distance, elapsed_time); if (distance < MIN_MOVE_DISTANCE) { continue; } double average_speed = distance / (elapsed_time / 1000000.0); // 改进的画圈检测逻辑 if (points >= MIN_POINTS && fabs(total_angle) > 1 * PI) { // 更加宽松的圆形度要求 if (average_speed < MAX_SPEED) { printf("画圈\n"); switch (i) { case 1: pic_circular_spread("./image/1.bmp", init_mmap_fd); break; case 2: pic_circular_spread("./image/2.bmp", init_mmap_fd); break; case 3: pic_circular_spread("./image/3.bmp", init_mmap_fd); break; case 4: pic_circular_spread("./image/4.bmp", init_mmap_fd); break; case 5: pic_circular_spread("./image/5.bmp", init_mmap_fd); break; case 6: pic_circular_spread("./image/6.bmp", init_mmap_fd); break; } i++; if (i > 6) { i = 1; } } } // 检测滑动动作 else if (end_x - first_x > 0 && (end_x - first_x) > abs(end_y - first_y)) { printf("右滑\n"); switch (i) { case 1: pic_right("./image/1.bmp", init_mmap_fd); break; case 2: pic_right("./image/2.bmp", init_mmap_fd); break; case 3: pic_right("./image/3.bmp", init_mmap_fd); break; case 4: pic_right("./image/4.bmp", init_mmap_fd); break; case 5: pic_right("./image/5.bmp", init_mmap_fd); break; case 6: pic_right("./image/6.bmp", init_mmap_fd); break; } slide_right_count++; slide_left_count = 0; slide_up_count = 0; slide_down_count = 0; if (slide_right_count >= SLIDE_COUNT_THRESHOLD) { slide_right_count = 0; goto bg; } i++; if (i > 6) { i = 1; } } else if (end_x - first_x < 0 && abs(end_x - first_x) > abs(end_y - first_y)) { printf("左滑\n"); switch (i) { case 1: pic_left("./image/1.bmp", init_mmap_fd); break; case 2: pic_left("./image/2.bmp", init_mmap_fd); break; case 3: pic_left("./image/3.bmp", init_mmap_fd); break; case 4: pic_left("./image/4.bmp", init_mmap_fd); break; case 5: pic_left("./image/5.bmp", init_mmap_fd); break; case 6: pic_left("./image/6.bmp", init_mmap_fd); break; } slide_left_count++; slide_right_count = 0; slide_up_count = 0; slide_down_count = 0; if (slide_left_count >= SLIDE_COUNT_THRESHOLD) { slide_left_count = 0; goto bg; } i++; if (i > 6) { i = 1; } } else if (end_y - first_y > 0 && (end_y - first_y) > abs(end_x - first_x)) { printf("下滑\n"); switch (i) { case 1: pic_down("./image/1.bmp", init_mmap_fd); break; case 2: pic_down("./image/2.bmp", init_mmap_fd); break; case 3: pic_down("./image/3.bmp", init_mmap_fd); break; case 4: pic_down("./image/4.bmp", init_mmap_fd); break; case 5: pic_down("./image/5.bmp", init_mmap_fd); break; case 6: pic_down("./image/6.bmp", init_mmap_fd); break; } slide_down_count++; slide_right_count = 0; slide_left_count = 0; slide_up_count = 0; if (slide_down_count >= SLIDE_COUNT_THRESHOLD) { slide_down_count = 0; goto bg; } i++; if (i > 6) { i = 1; } } else if (end_y - first_y < 0 && abs(end_y - first_y) > abs(end_x - first_x)) { printf("上滑\n"); switch (i) { case 1: pic_up("./image/1.bmp", init_mmap_fd); break; case 2: pic_up("./image/2.bmp", init_mmap_fd); break; case 3: pic_up("./image/3.bmp", init_mmap_fd); break; case 4: pic_up("./image/4.bmp", init_mmap_fd); break; case 5: pic_up("./image/5.bmp", init_mmap_fd); break; case 6: pic_up("./image/6.bmp", init_mmap_fd); break; } slide_up_count++; slide_right_count = 0; slide_left_count = 0; slide_down_count = 0; if (slide_up_count >= SLIDE_COUNT_THRESHOLD) { slide_up_count = 0; goto bg; } i++; if (i > 6) { i = 1; } } } munmap(init_mmap_fd, 800 * 480 * 4); close(file_fd); return 0; }
代码
-
- https://download.csdn.net/download/m0_64788786/89666116