我的娱乐系统世界

编程入门 行业动态 更新时间:2024-10-25 16:25:57

我的娱乐<a href=https://www.elefans.com/category/jswz/34/1770742.html style=系统世界"/>

我的娱乐系统世界

这是第一次写博客,保存最近做的一次项目,代码有点长。(可能会有bug,不喜勿喷,纯粹用于个人纪录)。
时间:2020年7月31日
内容:Linux,6818开发板,触摸屏,花样展示图片(轮播,百叶窗,缩放等),视频,音频,2048小游戏
解释都在代码里
//新增音乐相册(可以在相册里点击进入)
//将相册目录改成了缩略图,可点击跳转对应图片。

文章目录

  • 头文件
  • 主代码
  • 音频模块
  • 视频模块
  • 音乐相册
  • 2048

头文件

#ifndef MYIOHEAD_H_
#define MYIOHEAD_H_
#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <stdbool.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <dirent.h>
#include <linux/input.h>
#include <termio.h>
#include <bits/signum.h>
#include <signal.h>
#include <semaphore.h>#endif

头文件不长,是常用的几个。

主代码

#include "myiohead.h"//花样展示图片
int special_showbmp(char *bmppath)
{int bmpfd;int lcdfd;int i;int x,y;int w,h;//打开你要显示的w*h大小的bmpbmpfd=open(bmppath,O_RDWR);if(bmpfd==-1){perror("打开图片失败!\n");return -1;}//读取图片的宽和高lseek(bmpfd,18,SEEK_SET);read(bmpfd,&w,4);//读取宽read(bmpfd,&h,4);//读取高//定义一个数组,依据图片的大小char bmpbuf[w*h*3]; //char占1个字节//定义另外一个数组,存放转换得到的ARGB数据int lcdbuf[w*h]; //int占4字节//定义中间变量。临时存放数据int tempbuf[w*h];//打开lcd驱动lcdfd=open("/dev/fb0",O_RDWR);if(lcdfd==-1){perror("打开lcd失败!\n");return -1;}//映射得到lcd的首地址int *lcdmem=mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcdfd,0);if(lcdmem==NULL){perror("映射lcd失败!\n");return -1;}//跳过bmp图片头信息54字节,从55字节开始读取lseek(bmpfd,54,SEEK_SET);//读取bmp图片的RGB数据//每三个字节为一组,构成一个像素点的RGB数据read(bmpfd,bmpbuf,w*h*3); //bmpbuf[0] bmpbuf[1] bmpbuf[2]//    B            G       R	//bmpbuf[3] bmpbuf[4] bmpbuf[5]  //把三个字节--》转换成四个字节/*细节分析如下:lcdbuf[0]=0x00<<24|bmpbuf[0]<<16|bmpbuf[1]<<8|bmpbuf[2]lcdbuf[1]=0x00<<24|bmpbuf[3]<<16|bmpbuf[4]<<8|bmpbuf[5] */for(i=0; i<w*h; i++)lcdbuf[i]=0x00<<24|bmpbuf[3*i+2]<<16|bmpbuf[3*i+1]<<8|bmpbuf[3*i];//把颠倒的图片翻转过来/*细节分析如下:lcdbuf[0] --->lcdbuf[479*800]*/for(x=0; x<w; x++)for(y=0; y<h; y++)//lcdbuf[(h-1-y)*w+x]=lcdbuf[y*w+x];tempbuf[(h-1-y)*w+x]=lcdbuf[y*w+x];// //把转换后的数据写入lcd中// for(int i = 0;i < h;i++)// {// 	usleep(4000);// 	write(lcdfd,&tempbuf[w*i],w*4);// 	// *(lcdmem+(j*800)+i)=tempbuf[j*w+i];  // 	lseek(lcdfd,(800-w)*4,SEEK_CUR);             // }//把转换后的数据写入lcd中for (int j = 0; j < h; j++){usleep(4000);for(int i = 0,n = 0;i < w;i++){*(lcdmem+(j*800)+i)=tempbuf[j*w+i];  //n++;           }}//关闭close(bmpfd);close(lcdfd);return 0;
}//缩放图片
int zoom_showbmp(char *bmppath)
{int bmpfd;int lcdfd;int i;int x,y;int w,h;//打开你要显示的w*h大小的bmpbmpfd=open(bmppath,O_RDWR);if(bmpfd==-1){perror("打开图片失败!\n");return -1;}//读取图片的宽和高lseek(bmpfd,18,SEEK_SET);read(bmpfd,&w,4);//读取宽read(bmpfd,&h,4);//读取高//定义一个数组,依据图片的大小char bmpbuf[w*h*3]; //char占1个字节//定义另外一个数组,存放转换得到的ARGB数据int lcdbuf[w*h]; //int占4字节//定义中间变量。临时存放数据int tempbuf[w*h];//打开lcd驱动lcdfd=open("/dev/fb0",O_RDWR);if(lcdfd==-1){perror("打开lcd失败!\n");return -1;}//映射得到lcd的首地址int *lcdmem=mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcdfd,0);if(lcdmem==NULL){perror("映射lcd失败!\n");return -1;}//跳过bmp图片头信息54字节,从55字节开始读取lseek(bmpfd,54,SEEK_SET);//读取bmp图片的RGB数据//每三个字节为一组,构成一个像素点的RGB数据read(bmpfd,bmpbuf,w*h*3); //bmpbuf[0] bmpbuf[1] bmpbuf[2]//    B            G       R	//bmpbuf[3] bmpbuf[4] bmpbuf[5]  //把三个字节--》转换成四个字节/*细节分析如下:lcdbuf[0]=0x00<<24|bmpbuf[0]<<16|bmpbuf[1]<<8|bmpbuf[2]lcdbuf[1]=0x00<<24|bmpbuf[3]<<16|bmpbuf[4]<<8|bmpbuf[5] */for(i=0; i<w*h; i++)lcdbuf[i]=0x00<<24|bmpbuf[3*i+2]<<16|bmpbuf[3*i+1]<<8|bmpbuf[3*i];//把颠倒的图片翻转过来/*细节分析如下:lcdbuf[0] --->lcdbuf[479*800]*/for(x=0; x<w; x++)for(y=0; y<h; y++)//lcdbuf[(h-1-y)*w+x]=lcdbuf[y*w+x];tempbuf[(h-1-y)*w+x]=lcdbuf[y*w+x];// //把转换后的数据写入lcd中for (int j = 0,m = 0; j < (h/2); j++,m = m+2){for(int i = 0,n = 0;i < (w/2);i++,n = n+2){*(lcdmem+(j*800)+i)=tempbuf[m*w+n];             }}	//关闭close(bmpfd);close(lcdfd);return 0;
}//普通展示图片
int showbmp(char *bmppath)
{int bmpfd;int lcdfd;int i;int x,y;int w,h;//打开你要显示的w*h大小的bmpbmpfd=open(bmppath,O_RDWR);if(bmpfd==-1){perror("打开图片失败!\n");return -1;}//读取图片的宽和高lseek(bmpfd,18,SEEK_SET);read(bmpfd,&w,4);//读取宽read(bmpfd,&h,4);//读取高//定义一个数组,依据图片的大小char bmpbuf[w*h*3]; //char占1个字节//定义另外一个数组,存放转换得到的ARGB数据int lcdbuf[w*h]; //int占4字节//定义中间变量。临时存放数据int tempbuf[w*h];//打开lcd驱动lcdfd=open("/dev/fb0",O_RDWR);if(lcdfd==-1){perror("打开lcd失败!\n");return -1;}//映射得到lcd的首地址int *lcdmem=mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcdfd,0);if(lcdmem==NULL){perror("映射lcd失败!\n");return -1;}//跳过bmp图片头信息54字节,从55字节开始读取lseek(bmpfd,54,SEEK_SET);//读取bmp图片的RGB数据//每三个字节为一组,构成一个像素点的RGB数据read(bmpfd,bmpbuf,w*h*3); //bmpbuf[0] bmpbuf[1] bmpbuf[2]//    B            G       R	//bmpbuf[3] bmpbuf[4] bmpbuf[5]  //把三个字节--》转换成四个字节/*细节分析如下:lcdbuf[0]=0x00<<24|bmpbuf[0]<<16|bmpbuf[1]<<8|bmpbuf[2]lcdbuf[1]=0x00<<24|bmpbuf[3]<<16|bmpbuf[4]<<8|bmpbuf[5] */for(i=0; i<w*h; i++)lcdbuf[i]=0x00<<24|bmpbuf[3*i+2]<<16|bmpbuf[3*i+1]<<8|bmpbuf[3*i];//把颠倒的图片翻转过来/*细节分析如下:lcdbuf[0] --->lcdbuf[479*800]*/for(x=0; x<w; x++)for(y=0; y<h; y++)//lcdbuf[(h-1-y)*w+x]=lcdbuf[y*w+x];tempbuf[(h-1-y)*w+x]=lcdbuf[y*w+x];//把转换后的数据写入lcd中for (int j = 0; j < h; j++){for(int i = 0,n = 0;i < w;i++){*(lcdmem+(j*800)+i)=tempbuf[j*w+i];  //n++;           }}//关闭close(bmpfd);close(lcdfd);return 0;
}//定义一个结构体表示双向循环列表,为了省事把此双向链表类型定义为dlist
typedef struct doublelist
{char data[100];struct doublelist *next;struct doublelist *fnext;
}dlist;dlist * init_list()
{dlist *head = calloc(1,sizeof(dlist));// head->data = "1.bmp";//strcpy(head->data, "1.bmp");head->next = head;head->fnext = head;return head;
}//尾插
int insert_(char * newdata,dlist * head)
{dlist * p =head;while(p->next != head){p = p->next;}dlist *newnode = calloc(1,sizeof(dlist));//newnode->data = newdata;strcpy(newnode->data, newdata);newnode->next = head;p->next = newnode;head->fnext = newnode;newnode->fnext = p;
}//读取目录,获得图片名字
int read_dir(char *path,dlist * head)
{DIR * dir = opendir(path);if (NULL == dir){perror("打开目录失败!");exit(0);}struct dirent * rd = NULL;while((rd = readdir(dir)) != NULL) { //printf("d_name : %s\n", rd->d_name); if (rd->d_type == DT_REG){//printf("这是普通文件!\n");if (strstr(rd->d_name,".bmp") != 0){insert_(rd->d_name,head);}}// if (rd->d_type == DT_DIR)// {// 	printf("这是目录!\n");// 	system("cp *.txt ..");// 	system("cp *.txt abs");// }}return 0;
}//获取触摸屏坐标
int get_x_y(int *touch_x,int *touch_y)
{int flag = 0;int to = open ("/dev/input/event0",O_RDWR);if (-1 == to){perror("打开触摸屏的驱动失败!");exit(0);}struct input_event myevent;while(1){read(to,&myevent,sizeof(struct input_event));if (myevent.type == EV_ABS){if(myevent.code==ABS_X) //x坐标//由于新开发板的坐标范围跟800*480不一致,按比例修正//printf("你点击的坐标位置X坐标是:%d\n",myevent.value);{flag++;* touch_x = (myevent.value*800)/1024;}if(myevent.code==ABS_Y) //y坐标{flag++;* touch_y = (myevent.value*480)/600;}if (2 == flag){flag = 0;break;}}	}close(to);
}//获取滑动方向的触摸屏坐标
int yxget_x_y(int *touch_x,int *touch_x1,int *touch_y,int *touch_y1)
{int flag = 1;int to = open ("/dev/input/event0",O_RDWR);if (-1 == to){perror("打开触摸屏的驱动失败!");exit(0);}struct input_event myevent;int count = 1;while(1){   read(to,&myevent,sizeof(struct input_event));if (myevent.type == EV_ABS){   if(myevent.code==ABS_X) //x坐标//由于新开发板的坐标范围跟800*480不一致,按比例修正//printf("你点击的坐标位置X坐标是:%d\n",myevent.value);{   * touch_x1 = (myevent.value*800)/1024;if (count){* touch_x = (myevent.value*800)/1024;count = 0;}                        }if(myevent.code==ABS_Y) //y坐标{* touch_y1 = (myevent.value*480)/600;if (flag){* touch_y = (myevent.value*480)/600;flag = 0;}}}if(myevent.type==EV_KEY && myevent.code==BTN_TOUCH && myevent.value==0){//count = 0;//printf("x0=%d,y0=%d\n", *touch_x,*touch_y);//printf("x1=%d,y1=%d\n", *touch_x1,*touch_y1);break;}}close(to);
}//缩放图片--用于相册缩略图
int zoom1_showbmp(char *bmppath,int num)
{int bmpfd;int lcdfd;int w,h;//打开你要显示的w*h大小的bmpbmpfd=open(bmppath,O_RDWR);if(bmpfd==-1){perror("打开图片失败!\n");return -1;}//读取图片的宽和高lseek(bmpfd,18,SEEK_SET);read(bmpfd,&w,4);//读取宽read(bmpfd,&h,4);//读取高//定义一个数组,依据图片的大小char bmpbuf[w*h*3]; //char占1个字节//定义另外一个数组,存放转换得到的ARGB数据int lcdbuf[w*h]; //int占4字节//定义中间变量。临时存放数据int tempbuf[w*h];//打开lcd驱动lcdfd=open("/dev/fb0",O_RDWR);if(lcdfd==-1){perror("打开lcd失败!\n");return -1;}//映射得到lcd的首地址int *lcdmem=mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcdfd,0);if(lcdmem==NULL){perror("映射lcd失败!\n");return -1;}//跳过bmp图片头信息54字节,从55字节开始读取lseek(bmpfd,54,SEEK_SET);//读取bmp图片的RGB数据//每三个字节为一组,构成一个像素点的RGB数据read(bmpfd,bmpbuf,w*h*3); //bmpbuf[0] bmpbuf[1] bmpbuf[2]//    B            G       R	//bmpbuf[3] bmpbuf[4] bmpbuf[5]  //把三个字节--》转换成四个字节/*细节分析如下:lcdbuf[0]=0x00<<24|bmpbuf[0]<<16|bmpbuf[1]<<8|bmpbuf[2]lcdbuf[1]=0x00<<24|bmpbuf[3]<<16|bmpbuf[4]<<8|bmpbuf[5] */for(int i=0; i<w*h; i++)lcdbuf[i]=0x00<<24|bmpbuf[3*i+2]<<16|bmpbuf[3*i+1]<<8|bmpbuf[3*i];//把颠倒的图片翻转过来/*细节分析如下:lcdbuf[0] --->lcdbuf[479*800]*/for(int x=0; x<w; x++)for(int y=0; y<h; y++)//lcdbuf[(h-1-y)*w+x]=lcdbuf[y*w+x];tempbuf[(h-1-y)*w+x]=lcdbuf[y*w+x];/*//把转换后的数据写入lcd中,高缩小2倍,宽缩小2倍for (int j = 0,m = 0; j < (h/2); j++,m = m+2){for(int i = 0,n = 0;i < (w/2);i++,n = n+2){*(lcdmem+(j*800)+i)=tempbuf[m*w+n];             }}*/// //把转换后的数据写入lcd中,高缩小(h/160)倍,宽缩小w/160倍int a = (num%5)*160;int b = (num/5)*160;for (int j = 0,m = 0; j < (h/(h/160)); j = j-b+1,m = m+(h/160)){j = j+b;for(int i = 0,n = 0;i < (w/(w/160));i = i-a+1,n = n+(w/160)){i = i + a;*(lcdmem+(j*800)+i)=tempbuf[m*w+n];             }}	//关闭close(bmpfd);close(lcdfd);return 0;
}//登陆和注册
int denglu()
{char usename[100] = {0};char newname[100] = {0};char password[100] = {0};char newword[100] = {0};int *touch_x = calloc(1,1000);int *touch_y = calloc(1,1000);//打开保存注册名字的文件int fd = open("a.txt",O_RDWR);if (-1 == fd){perror("打开源文件失败");exit(0);}char  buf[1000] = {0};char  buff[1000] = {0};while(1){//注册账号和密码get_x_y(touch_x,touch_y);if ((*touch_x>322) &&(*touch_x<361) && (*touch_y>258) && (*touch_y<277) ){	printf("请输入你想注册的账号!(<=12位)\n");scanf("%s",newname);printf("请输入你想注册的密码!(<=12位)\n");scanf("%s",newword);lseek(fd,0,SEEK_SET);write(fd,newname,sizeof(newname));lseek(fd,12,SEEK_SET);write(fd,newword,sizeof(newword));lseek(fd,12,SEEK_SET);printf("注册成功,请重新登陆\n");continue;}else{for (int i = 0; i < 100; ++i){lseek(fd,24*i,SEEK_SET);read(fd,buf+i,12);//把注册名存到buf中lseek(fd,24*i+12,SEEK_SET);read(fd,buff+i,12);//把密码存到buff中}printf("请输入用户名!\n");//初始用户名我设置为chenwangxinscanf("%s",usename);printf("请输入密码!\n");//初始密码我设置为123456scanf("%s",password);if ((strcmp(usename,"chenwangxin") == 0) && (strcmp(password,"123456") == 0)){break;}int i = 0;while ((strcmp(usename,buf+i) != 0) || (strcmp(password,buff+i) != 0)){i++;if (i = 99){break;}}if ((strcmp(usename,buf+i) == 0) && (strcmp(password,buff+i) == 0)){break;}printf("用户名或密码错误,请重新输入!\n");}}}//我的相册
int myphoto()
{int *touch_x = calloc(1,1000);int *touch_y = calloc(1,1000);int *touch_x1 = calloc(1,1000);int *touch_y1 = calloc(1,1000);dlist *mydlist=init_list();read_dir("/myphoto/",mydlist);char a[500] = "/myphoto/";int page = 0;int count = 0;int num = 0;//计算总共有多少张图片dlist * p = mydlist;while(p->next != mydlist){p = p->next;count++;}p = mydlist;while(p->next != NULL){printf("点击底层中部进入音乐相册,顶层中部进入相册缩略图,点击可跳转对应对应图片。\n");yxget_x_y(touch_x,touch_x1,touch_y,touch_y1);//上一张if ((*touch_x<200) &&(*touch_y>360)){p = p->fnext;if (p == mydlist){p = p->fnext;}		bzero(a,500);strcpy(a,"/myphoto/");strcat(a,p->data);//showbmp(a);printf("a里面的内容%s\n",a  );special_showbmp(a);}//下一张if ((*touch_x>600) && (*touch_y>360)){p = p->next;if (p == mydlist){p = p->next;}bzero(a,500);strcpy(a,"/myphoto/");strcat(a,p->data);//showbmp(a);printf("a里面的内容%s\n",a  );special_showbmp(a);}//音乐相册if ((*touch_x>350) && (*touch_x<450) && (*touch_y>360)){system("./music_album");printf("退出音乐后要点击上/下一张回到相册后才能退出哦\n");bzero(touch_x,1000);bzero(touch_y,1000);// continue;}//显示目录,加载目录中的照片if ((*touch_x>300) &&(*touch_x<500) && (*touch_y<66)){//开头显示第一页缩略图int k = 0;page = 0;p = mydlist;while(p->next != mydlist && k<15){	k++;p = p->next;num++;bzero(a,500);strcpy(a,"/myphoto/");strcat(a,p->data);zoom1_showbmp(a,num-1);}num = 0;p = mydlist;while(1){//到while循环的顶部了yxget_x_y(touch_x,touch_x1,touch_y,touch_y1);//向左划,下一页缩略图if((*touch_x>*touch_x1)&&((*touch_x-*touch_x1)>=80)){	if (count<=15){printf("所有图片都在这里了噢。\n");continue;}if (page <= count/15){page++;}if (page > count/15){if (count%15 == 0){printf("这已经是最后一页了。\n");if (page > count/15){page--;}continue;}}					p = mydlist;for (int i = 0; i < 15*page; i++){p = p->next;}k = 0;		while(p->next != mydlist && k<15){	k++;p = p->next;num++;bzero(a,500);strcpy(a,"/myphoto/");strcat(a,p->data);zoom1_showbmp(a,num-1);}}num = 0;//向右划,上一页if( ((*touch_x1-*touch_x) >=80) && (*touch_x1>=*touch_x) ){	if (page==0){printf("当前已经是第一页了。\n");continue;}page--;		p = mydlist;for (int i = 0; i < 15*page; i++){p = p->next;}k = 0;		while(p->next != mydlist && k<15){	k++;p = p->next;num++;bzero(a,500);strcpy(a,"/myphoto/");strcat(a,p->data);zoom1_showbmp(a,num-1);}}num = 0;//跳转点击到的图片if( ((*touch_x1-*touch_x) <80) && (*touch_x1>=*touch_x) ){int h = (*touch_x1/160) + (*touch_y1/160)*5;p = mydlist->next;for (int i = 0; i < 15*page; i++){p = p->next;}for (int i = 0; i < h; i++){if (p->next != mydlist){p = p->next;}else{printf("当前位置没有对应图片,自动跳转到最后一张图片。\n");break;}}bzero(a,500);strcpy(a,"/myphoto/");strcat(a,p->data);special_showbmp(a);break;}//跳转点击到的图片if( ((*touch_x-*touch_x1) <80) && (*touch_x>=*touch_x1) ){int h = (*touch_x1/160) + (*touch_y1/160)*5;p = mydlist->next;for (int i = 0; i < 15*page; i++){p = p->next;}for (int i = 0; i < h; i++){if (p->next != mydlist){p = p->next;}else{printf("当前位置没有对应图片,自动跳转到最后一张图片。\n");break;}}bzero(a,500);strcpy(a,"/myphoto/");strcat(a,p->data);special_showbmp(a);break;}//到while循环的底部了}}//退出相册if ((*touch_x>742) && (*touch_y<36)){break;}}printf("退出了我的相册\n");
}//我的音乐
int mymusic()
{printf("左下方为上一首,右下方为上一首\n");printf("中间为暂停/播放,滑动快进/退\n");system("./mymusic");printf("退出了我的音乐\n");
}//我的视频
int myvideo()
{printf("左下方为上一集,右下方为上一集\n");printf("中间为暂停/播放,滑动快进/退\n");system("./myvideo");printf("退出了我的视频\n");
}int main(int argc, char const *argv[])
{int *touch_x = calloc(1,1000);int *touch_y = calloc(1,1000);showbmp("dl.bmp");printf("点击登陆或注册后登陆才能进入我的娱乐世界哦\n");//登陆和注册denglu();printf("登陆成功,欢迎进入我的娱乐世界!\n");showbmp("zjm.bmp");printf("使用相册和音视频播放器等应用时:左下角为播放上一张/首/个,右下角为播放下一张/首/个,左上角为退出当前应用\n");while(1){//打开相册get_x_y(touch_x,touch_y);if ((*touch_x>22) &&(*touch_x<96) && (*touch_y>144) && (*touch_y<222) ){special_showbmp("1.bmp");sleep(1);zoom_showbmp("3.bmp");myphoto();}showbmp("zjm.bmp");//打开音乐播放器if ((*touch_x>31) &&(*touch_x<102) && (*touch_y>23) && (*touch_y<98) ){showbmp("mymp3.bmp");printf("已经打开音乐播放器,请点击进行播放音乐!\n");mymusic();}showbmp("zjm.bmp");//打开视频播放器if ((*touch_x>129) &&(*touch_x<207) && (*touch_y>23) && (*touch_y<108) ){printf("已经打开视频播放器,请点击上/下一集进行播放视频!\n");showbmp("mymp3.bmp");myvideo();}showbmp("zjm.bmp");if ((*touch_x>119) &&(*touch_x<199) && (*touch_y>140) && (*touch_y<217) ){system("./yx1");}showbmp("zjm.bmp");}return 0;
}

上面的是主代码,2048代码,音频模块,视频模块,新增的音乐相册如下:
(2048还有待改善)

音频模块

//音频模块,下面的视频模块的思路也是一样的

//音频模块
#include "myiohead.h"//获取滑动方向的触摸屏坐标
int yxget_x_y(int *touch_x,int *touch_x1,int *touch_y,int *touch_y1)
{int flag = 1;int to = open ("/dev/input/event0",O_RDWR);if (-1 == to){perror("打开触摸屏的驱动失败!");exit(0);}struct input_event myevent;int count = 1;while(1){   read(to,&myevent,sizeof(struct input_event));if (myevent.type == EV_ABS){   if(myevent.code==ABS_X) //x坐标//由于新开发板的坐标范围跟800*480不一致,按比例修正//printf("你点击的坐标位置X坐标是:%d\n",myevent.value);{   * touch_x1 = (myevent.value*800)/1024;if (count){* touch_x = (myevent.value*800)/1024;count = 0;}                        }if(myevent.code==ABS_Y) //y坐标{* touch_y1 = (myevent.value*480)/600;if (flag){* touch_y = (myevent.value*480)/600;flag = 0;}}}if(myevent.type==EV_KEY && myevent.code==BTN_TOUCH && myevent.value==0){//count = 0;//printf("x0=%d,y0=%d\n", *touch_x,*touch_y);//printf("x1=%d,y1=%d\n", *touch_x1,*touch_y1);break;}}close(to);
}//定义一个结构体表示双向循环列表,为了省事把此双向链表类型定义为dlist
typedef struct doublelist
{char data[100];struct doublelist *next;struct doublelist *fnext;
}dlist;dlist * init_list()
{dlist *head = calloc(1,sizeof(dlist));// head->data = "1.bmp";strcpy(head->data, "1.bmp");head->next = head;head->fnext = head;return head;
}//尾插
int insert_(char * newdata,dlist * head)
{dlist * p =head;while(p->next != head){p = p->next;}dlist *newnode = calloc(1,sizeof(dlist));//newnode->data = newdata;strcpy(newnode->data, newdata);newnode->next = head;p->next = newnode;head->fnext = newnode;newnode->fnext = p;
}//读取目录,获得音乐名字
int read_dir(char *path,dlist * head)
{DIR * dir = opendir(path);if (NULL == dir){perror("打开目录失败!");exit(0);}struct dirent * rd = NULL;while((rd = readdir(dir)) != NULL) { //printf("d_name : %s\n", rd->d_name); if (rd->d_type == DT_REG){//printf("这是普通文件!\n");if (strstr(rd->d_name,".mp3") != 0){insert_(rd->d_name,head);}}// if (rd->d_type == DT_DIR)// {// 	printf("这是目录!\n");// 	system("cp *.txt ..");// 	system("cp *.txt abs");// }}return 0;
}void * task(void * n)//播放/暂停/快进/快退/上/下一首音乐
{int *touch_x1 = calloc(1,1000);int *touch_y1 = calloc(1,1000);int *touch_x = calloc(1,1000);int *touch_y = calloc(1,1000);dlist * mydlist = init_list();read_dir("/myword/2048bmp/",mydlist);char a[100] = {0};if (access("/root/myfifo",F_OK) == -1){int ret = mkfifo("/root/myfifo",0777);if (-1 == ret){perror("创建管道文件失败!");exit(0);}}int fd = open("/root/myfifo", O_RDWR);if (-1 == fd){perror("打开管道文件失败!");exit(0);}dlist * p =mydlist;int count = 0;int flag = 2;while(1){yxget_x_y(touch_x,touch_x1,touch_y,touch_y1);if ((*touch_x<200)&&(*touch_y>360))//上一首{if (count == 1){system("killall -9 mplayer");}p = p->fnext;if (p == mydlist){p = p->fnext;}bzero(a,100);strcpy(a,"mplayer -quiet -slave -input file=/root/myfifo /myword/2048bmp/");strcat(a,p->data);strcat(a," &");system(a);count = 1;flag = 1;}if ((*touch_x>600) && (*touch_y>360))//下一首{if (count == 1){system("killall -9 mplayer");}p = p->next;if (p == mydlist){p = p->next;}bzero(a,100);strcpy(a,"mplayer -quiet -slave -input file=/root/myfifo /myword/2048bmp/");strcat(a,p->data);strcat(a," &");system(a);count = 1;flag = 1;}if ((*touch_x>358) && (*touch_x<414) && (*touch_y>203) && (*touch_y<268)) //暂停/播放{if (flag == 1)//暂停{system("killall  -STOP  mplayer");flag = 0;}else if (flag == 0)//播放{system("killall  -CONT  mplayer");flag = 1;}}//快退5秒if((*touch_x>*touch_x1)&&((*touch_x-*touch_x1)>=80)){/// 写入的字节数一定要和实际一模一样,不然会出问题// 不能快进快退char msg[] = "seek -5\n";write (fd,msg,strlen(msg));		}//快进5sif((*touch_x1>*touch_x)&&((*touch_x1-*touch_x)>=80)){// 写入的字节数一定要和实际一模一样,不然会出问题// 不能快进快退char msg[] = "seek 5\n";write (fd,msg,strlen(msg));}if ((*touch_x>742) && (*touch_y<36)){system("killall -9 mplayer");raise(9);break;}}}int main(int argc, char const *argv[])
{pthread_t id;pthread_create(&id,NULL,task, NULL);pthread_join(id,NULL);return 0;
}

视频模块

视频模块(和音频大同小异)

//这里是视频模块
#include "myiohead.h"//获取滑动方向的触摸屏坐标
int yxget_x_y(int *touch_x,int *touch_x1,int *touch_y,int *touch_y1)
{int flag = 1;int to = open ("/dev/input/event0",O_RDWR);if (-1 == to){perror("打开触摸屏的驱动失败!");exit(0);}struct input_event myevent;int count = 1;while(1){   read(to,&myevent,sizeof(struct input_event));if (myevent.type == EV_ABS){   if(myevent.code==ABS_X) //x坐标//由于新开发板的坐标范围跟800*480不一致,按比例修正//printf("你点击的坐标位置X坐标是:%d\n",myevent.value);{   * touch_x1 = (myevent.value*800)/1024;if (count){* touch_x = (myevent.value*800)/1024;count = 0;}                        }if(myevent.code==ABS_Y) //y坐标{* touch_y1 = (myevent.value*480)/600;if (flag){* touch_y = (myevent.value*480)/600;flag = 0;}}}if(myevent.type==EV_KEY && myevent.code==BTN_TOUCH && myevent.value==0){//count = 0;//printf("x0=%d,y0=%d\n", *touch_x,*touch_y);//printf("x1=%d,y1=%d\n", *touch_x1,*touch_y1);break;}}close(to);
}//定义一个结构体表示双向循环列表,为了省事把此双向链表类型定义为dlist
typedef struct doublelist
{char data[100];struct doublelist *next;struct doublelist *fnext;
}dlist;dlist * init_list()
{dlist *head = calloc(1,sizeof(dlist));// head->data = "1.bmp";strcpy(head->data, "1.bmp");head->next = head;head->fnext = head;return head;
}//尾插
int insert_(char * newdata,dlist * head)
{dlist * p =head;while(p->next != head){p = p->next;}dlist *newnode = calloc(1,sizeof(dlist));//newnode->data = newdata;strcpy(newnode->data, newdata);newnode->next = head;p->next = newnode;head->fnext = newnode;newnode->fnext = p;
}//读取目录,获得音乐名字
int read_dir(char *path,dlist * head)
{DIR * dir = opendir(path);if (NULL == dir){perror("打开目录失败!");exit(0);}struct dirent * rd = NULL;while((rd = readdir(dir)) != NULL) { //printf("d_name : %s\n", rd->d_name); if (rd->d_type == DT_REG){//printf("这是普通文件!\n");if (strstr(rd->d_name,".avi") != 0){insert_(rd->d_name,head);}}// if (rd->d_type == DT_DIR)// {// 	printf("这是目录!\n");// 	system("cp *.txt ..");// 	system("cp *.txt abs");// }}return 0;
}void * task(void * n)//播放/暂停/快进/快退/上/下一个视频
{int *touch_x1 = calloc(1,1000);int *touch_y1 = calloc(1,1000);int *touch_x = calloc(1,1000);int *touch_y = calloc(1,1000);dlist * mydlist = init_list();read_dir("/myword/2048bmp/",mydlist);char a[100] = {0};if (access("/root/myfifo",F_OK) == -1){int ret = mkfifo("/root/myfifo",0777);if (-1 == ret){perror("创建管道文件失败!");exit(0);}}int fd = open("/root/myfifo", O_RDWR);if (-1 == fd){perror("打开管道文件失败!");exit(0);}dlist * p =mydlist;int count = 0;int flag = 2;while(1){yxget_x_y(touch_x,touch_x1,touch_y,touch_y1);if ((*touch_x<200)&&(*touch_y>360))//上一个{if (count == 1){system("killall -9 mplayer");}p = p->fnext;if (p == mydlist){p = p->fnext;}bzero(a,100);strcpy(a,"mplayer -quiet -slave -input file=/root/myfifo /myword/2048bmp/");strcat(a,p->data);strcat(a," &");system(a);count = 1;flag = 1;}if ((*touch_x>600) && (*touch_y>360))//下一个{if (count == 1){system("killall -9 mplayer");}p = p->next;if (p == mydlist){p = p->next;}bzero(a,100);strcpy(a,"mplayer -quiet -slave -input file=/root/myfifo /myword/2048bmp/");strcat(a,p->data);strcat(a," &");system(a);count = 1;flag = 1;}if ((*touch_x>358) && (*touch_x<414) && (*touch_y>203) && (*touch_y<268)) //暂停/播放{if (flag == 1)//暂停{system("killall  -STOP  mplayer");flag = 0;}else if (flag == 0)//播放{system("killall  -CONT  mplayer");flag = 1;}}//快退5秒if((*touch_x>*touch_x1)&&((*touch_x-*touch_x1)>=80)){/// 写入的字节数一定要和实际一模一样,不然会出问题// 不能快进快退char msg[] = "seek -5\n";write (fd,msg,strlen(msg));		}//快进5sif((*touch_x1>*touch_x)&&((*touch_x1-*touch_x)>=80)){// 写入的字节数一定要和实际一模一样,不然会出问题// 不能快进快退char msg[] = "seek 5\n";write (fd,msg,strlen(msg));}if ((*touch_x>742) && (*touch_y<36)){system("killall -9 mplayer");raise(9);break;}}}int main(int argc, char const *argv[])
{pthread_t id;pthread_create(&id,NULL,task, NULL);pthread_join(id,NULL);return 0;
}

音乐相册

音乐相册

//音乐相册
#include "myiohead.h"//获取触摸屏坐标
int get_x_y(int *touch_x,int *touch_y)
{int flag = 0;int to = open ("/dev/input/event0",O_RDWR);if (-1 == to){perror("打开触摸屏的驱动失败!");exit(0);}struct input_event myevent;while(1){read(to,&myevent,sizeof(struct input_event));if (myevent.type == EV_ABS){if(myevent.code==ABS_X) //x坐标//由于新开发板的坐标范围跟800*480不一致,按比例修正//printf("你点击的坐标位置X坐标是:%d\n",myevent.value);{flag++;* touch_x = (myevent.value*800)/1024;}if(myevent.code==ABS_Y) //y坐标{flag++;* touch_y = (myevent.value*480)/600;}if (2 == flag){flag = 0;break;}}   }close(to);
}//普通展示图片
int showbmp(char *bmppath)
{int bmpfd;int lcdfd;int w,h;int i;int x,y;//打开你要显示的w*h大小的bmpbmpfd=open(bmppath,O_RDWR);if(bmpfd==-1){perror("打开图片失败!\n");return -1;}//读取图片的宽和高lseek(bmpfd,18,SEEK_SET);read(bmpfd,&w,4);//读取宽read(bmpfd,&h,4);//读取高//定义一个数组,依据图片的大小char bmpbuf[w*h*3]; //char占1个字节//定义另外一个数组,存放转换得到的ARGB数据int lcdbuf[w*h]; //int占4字节//定义中间变量。临时存放数据int tempbuf[w*h];//打开lcd驱动lcdfd=open("/dev/fb0",O_RDWR);if(lcdfd==-1){perror("打开lcd失败!\n");return -1;}//映射得到lcd的首地址int *lcdmem=mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcdfd,0);if(lcdmem==NULL){perror("映射lcd失败!\n");return -1;}//跳过bmp图片头信息54字节,从55字节开始读取lseek(bmpfd,54,SEEK_SET);//读取bmp图片的RGB数据//每三个字节为一组,构成一个像素点的RGB数据read(bmpfd,bmpbuf,w*h*3); //bmpbuf[0] bmpbuf[1] bmpbuf[2]//    B            G       R	//bmpbuf[3] bmpbuf[4] bmpbuf[5]  //把三个字节--》转换成四个字节/*细节分析如下:lcdbuf[0]=0x00<<24|bmpbuf[0]<<16|bmpbuf[1]<<8|bmpbuf[2]lcdbuf[1]=0x00<<24|bmpbuf[3]<<16|bmpbuf[4]<<8|bmpbuf[5] */for(i=0; i<w*h; i++)lcdbuf[i]=0x00<<24|bmpbuf[3*i+2]<<16|bmpbuf[3*i+1]<<8|bmpbuf[3*i];//把颠倒的图片翻转过来/*细节分析如下:lcdbuf[0] --->lcdbuf[479*800]*/for(x=0; x<w; x++)for(y=0; y<h; y++)//lcdbuf[(h-1-y)*w+x]=lcdbuf[y*w+x];tempbuf[(h-1-y)*w+x]=lcdbuf[y*w+x];//把转换后的数据写入lcd中for (int j = 0; j < h; j++){for(int i = 0,n = 0;i < w;i++){*(lcdmem+(j*800)+i)=tempbuf[j*w+i];  //n++;           }}//关闭close(bmpfd);close(lcdfd);return 0;
}//定义一个结构体表示双向循环列表,为了省事把此双向链表类型定义为dlist
typedef struct doublelist
{char data[100];struct doublelist *next;struct doublelist *fnext;
}dlist;dlist * init_list()
{dlist *head = calloc(1,sizeof(dlist));// head->data = "1.bmp";strcpy(head->data, "1.bmp");head->next = head;head->fnext = head;return head;
}//尾插
int insert_(char * newdata,dlist * head)
{dlist * p =head;while(p->next != head){p = p->next;}dlist *newnode = calloc(1,sizeof(dlist));//newnode->data = newdata;strcpy(newnode->data, newdata);newnode->next = head;p->next = newnode;head->fnext = newnode;newnode->fnext = p;
}//读取目录,获得图片名字
int read_dir(char *path,dlist * head)
{DIR * dir = opendir(path);if (NULL == dir){perror("打开目录失败!");exit(0);}struct dirent * rd = NULL;while((rd = readdir(dir)) != NULL) { //printf("d_name : %s\n", rd->d_name); if (rd->d_type == DT_REG){//printf("这是普通文件!\n");if (strstr(rd->d_name,".bmp") != 0){insert_(rd->d_name,head);}}// if (rd->d_type == DT_DIR)// {// 	printf("这是目录!\n");// 	system("cp *.txt ..");// 	system("cp *.txt abs");// }}return 0;
}void * task(void * n)//循环播放相册
{dlist * mydlist = init_list();read_dir("/myphoto",mydlist);char a[100] = "/myphoto/";dlist * p =mydlist;while(p->next != NULL){p = p->next;if (p == mydlist){p = p->next;}bzero(a,100);strcpy(a,"/myphoto/");strcat(a,p->data);showbmp(a);sleep(1);}	
}void * task1(void * n)
{system("mplayer Apologize.mp3 &");
}int main(int argc, char const *argv[])
{pthread_t id;pthread_create(&id,NULL,task, NULL);pthread_t id1;pthread_create(&id1,NULL,task1, NULL);int *touch_x = calloc(1,1000);int *touch_y = calloc(1,1000);while(1){get_x_y(touch_x,touch_y);if ((*touch_x>742) && (*touch_y<36)){pthread_cancel(id);pthread_cancel(id1);system("killall -9 mplayer");raise(9);break;}	}return 0;
}

2048

下面是2048小游戏

#include "myiohead.h"int showbmp(int w,int h,char *bmppath)
{int bmpfd;int lcdfd;int i;int x,y;//定义一个数组,依据图片的大小char bmpbuf[w*h*3]; //char占1个字节//定义另外一个数组,存放转换得到的ARGB数据int lcdbuf[w*h]; //int占4字节//定义中间变量。临时存放数据int tempbuf[w*h];//打开你要显示的w*h大小的bmpbmpfd=open(bmppath,O_RDWR);if(bmpfd==-1){perror("打开图片失败!\n");return -1;}//打开lcd驱动lcdfd=open("/dev/fb0",O_RDWR);if(lcdfd==-1){perror("打开lcd失败!\n");return -1;}//映射得到lcd的首地址int *lcdmem=mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcdfd,0);if(lcdmem==NULL){perror("映射lcd失败!\n");return -1;}//跳过bmp图片头信息54字节,从55字节开始读取lseek(bmpfd,54,SEEK_SET);//读取bmp图片的RGB数据//每三个字节为一组,构成一个像素点的RGB数据read(bmpfd,bmpbuf,w*h*3); //bmpbuf[0] bmpbuf[1] bmpbuf[2]//    B            G       R  //bmpbuf[3] bmpbuf[4] bmpbuf[5]  //把三个字节--》转换成四个字节/*细节分析如下:lcdbuf[0]=0x00<<24|bmpbuf[0]<<16|bmpbuf[1]<<8|bmpbuf[2]lcdbuf[1]=0x00<<24|bmpbuf[3]<<16|bmpbuf[4]<<8|bmpbuf[5] */for(i=0; i<w*h; i++)lcdbuf[i]=0x00<<24|bmpbuf[3*i+2]<<16|bmpbuf[3*i+1]<<8|bmpbuf[3*i];//把颠倒的图片翻转过来/*细节分析如下:lcdbuf[0] --->lcdbuf[479*800]*/for(x=0; x<w; x++)for(y=0; y<h; y++)//lcdbuf[(h-1-y)*w+x]=lcdbuf[y*w+x];tempbuf[(h-1-y)*w+x]=lcdbuf[y*w+x];//把转换后的数据写入lcd中for (int j = 0; j < h; j++){for(int i = 0,n = 0;i < w;i++){*(lcdmem+(j*800)+i)=tempbuf[j*w+i];  //n++;           }}//关闭close(bmpfd);close(lcdfd);return 0;
}//2048数字图片的映射
int showyxbmp(int w,int h,int r,int s,char *bmppath)
{int bmpfd;int lcdfd;int i;int x,y;//定义一个数组,依据图片的大小char bmpbuf[w*h*3]; //char占1个字节//定义另外一个数组,存放转换得到的ARGB数据int lcdbuf[w*h]; //int占4字节//定义中间变量。临时存放数据int tempbuf[w*h];//打开你要显示的w*h大小的bmpbmpfd=open(bmppath,O_RDWR);if(bmpfd==-1){perror("打开图片失败!\n");return -1;}//打开lcd驱动lcdfd=open("/dev/fb0",O_RDWR);if(lcdfd==-1){perror("打开lcd失败!\n");return -1;}//映射得到lcd的首地址int *lcdmem=mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcdfd,0);if(lcdmem==NULL){perror("映射lcd失败!\n");return -1;}//跳过bmp图片头信息54字节,从55字节开始读取lseek(bmpfd,54,SEEK_SET);//读取bmp图片的RGB数据//每三个字节为一组,构成一个像素点的RGB数据read(bmpfd,bmpbuf,w*h*3); //bmpbuf[0] bmpbuf[1] bmpbuf[2]//    B            G       R  //bmpbuf[3] bmpbuf[4] bmpbuf[5]  //把三个字节--》转换成四个字节/*细节分析如下:lcdbuf[0]=0x00<<24|bmpbuf[0]<<16|bmpbuf[1]<<8|bmpbuf[2]lcdbuf[1]=0x00<<24|bmpbuf[3]<<16|bmpbuf[4]<<8|bmpbuf[5] */for(i=0; i<w*h; i++)lcdbuf[i]=0x00<<24|bmpbuf[3*i+2]<<16|bmpbuf[3*i+1]<<8|bmpbuf[3*i];//把颠倒的图片翻转过来/*细节分析如下:lcdbuf[0] --->lcdbuf[479*800]*/for(x=0; x<w; x++)for(y=0; y<h; y++)//lcdbuf[(h-1-y)*w+x]=lcdbuf[y*w+x];tempbuf[(h-1-y)*w+x]=lcdbuf[y*w+x];//把转换后的数据写入lcd中for (int j = 0; j < h; j++){for(int i = 0,n = 0;i < w;i++){//我的背景方格是360*360,也就是每个小格子为90*90*(lcdmem+((j*800)+(90*s)+(90*800*r))+i)=tempbuf[j*w+i]; //*(lcdmem+(j*800)+i)=tempbuf[j*w+i];            }}// //把转换后的数据写入lcd中// lseek(lcdfd,((90*s)+(r*90*800))*4,SEEK_SET);// for(int i = 0;i < h;i++)// {//  write(lcdfd,&tempbuf[w*i],w*4);//  lseek(lcdfd,(800-w)*4,SEEK_CUR);// }//关闭close(bmpfd);close(lcdfd);return 0;
}//获取触摸屏坐标
// int get_x_y(int *touch_x,int *touch_y)
// {
//     int flag = 0;//     int to = open ("/dev/input/event0",O_RDWR);//     if (-1 == to)
//     {
//         perror("打开触摸屏的驱动失败!");
//         exit(0);
//     }//     struct input_event myevent;
//     while(1)
//     {
//         read(to,&myevent,sizeof(struct input_event));
//         if (myevent.type == EV_ABS)
//         {
//             if(myevent.code==ABS_X) //x坐标
//             //由于新开发板的坐标范围跟800*480不一致,按比例修正
//             //printf("你点击的坐标位置X坐标是:%d\n",myevent.value);
//             {
//                 flag++;
//                 * touch_x = (myevent.value*800)/1024;
//             }//             if(myevent.code==ABS_Y) //y坐标
//             {
//                 flag++;
//                 * touch_y = (myevent.value*480)/600;
//             }//             if (2 == flag)
//             {
//                 flag = 0;
//                 break;
//             }//         }   
//     }
//     close(to);
// }//获取游戏滑动方向的触摸屏坐标
int yxget_x_y(int *touch_x,int *touch_x1,int *touch_y,int *touch_y1)
{int flag = 1;int to = open ("/dev/input/event0",O_RDWR);if (-1 == to){perror("打开触摸屏的驱动失败!");exit(0);}struct input_event myevent;int count = 1;while(1){   read(to,&myevent,sizeof(struct input_event));if (myevent.type == EV_ABS){   if(myevent.code==ABS_X) //x坐标//由于新开发板的坐标范围跟800*480不一致,按比例修正//printf("你点击的坐标位置X坐标是:%d\n",myevent.value);{   * touch_x1 = (myevent.value*800)/1024;if (count){* touch_x = (myevent.value*800)/1024;count = 0;}}if(myevent.code==ABS_Y) //y坐标{* touch_y1 = (myevent.value*480)/600;if (flag){* touch_y = (myevent.value*480)/600;flag = 0;}}}if(myevent.type==EV_KEY && myevent.code==BTN_TOUCH && myevent.value==0){//count = 0;//printf("x0=%d,y0=%d\n", *touch_x,*touch_y);//printf("x1=%d,y1=%d\n", *touch_x1,*touch_y1);break;}}close(to);
}int play_game()
{int *touch_x1 = calloc(1,1000);int *touch_y1 = calloc(1,1000);int *touch_x = calloc(1,1000);int *touch_y = calloc(1,1000);int ifmove = 0;showbmp(360,360,"2048.bmp");/* 了解到游戏初始化时出现的两个数一定会有个2,所以先随机生成一个2,其他均为0 */int n;n = rand() % 16;int board[4][4] = {0};for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {board[i][j] = (n-- == 0 ? 2 : 0);}}/* 前面已经生成了一个2,这里再生成一个随机的2或者4,概率之比9:1 */n = 0;for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {if (board[i][j] == 0){n = n+1;}          }}srand((unsigned int) time(0));n = rand() % n; /* 确定在何处空位置生成随机数 */for (int i = 0; i < 4; ++i) {       for (int j = 0; j < 4; ++j) {/* 定位待生成的位置 */if (board[i][j] == 0 && n-- == 0) {board[i][j] = (rand() % 10 ? 2 : 4); /* 生成数字2或4,生成概率为9:1 */}}}//展示初始画面for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {if (board[i][j] == 0){showyxbmp(80,80,i,j,"num0.bmp");} if (board[i][j] == 2){showyxbmp(80,80,i,j,"num2.bmp");}  if (board[i][j] == 4){showyxbmp(80,80,i,j,"num4.bmp");}       }}while(1){yxget_x_y(touch_x,touch_x1,touch_y,touch_y1);//printf("x是%d,x1是%d,y是%d,y1是%d\n", *touch_x,*touch_x1,*touch_y,*touch_y1);//向左划if((*touch_y1-*touch_y)<(*touch_x-*touch_x1)&&(*touch_y1-*touch_y)>(*touch_x1-*touch_x)){// printf("这里是左\n");ifmove = 1;for (int i = 0; i < 4; i++) {/* 变量i用来遍历行项的下标,并且在移动时所有行相互独立,互不影响 *//* 变量j为列下标,变量k为待比较(合并)项的下标,循环进入时k<j */for (int j = 3; j >= 0; j--) {int k = 0;if (board[i][j] == 0) /* 找出k后面第一个不为空的项,下标为j,之后分三种情况 */{continue; }if (j != 0){k = j-1;}else k = 0;while(board[i][k] == 0){board[i][k] = board[i][j];board[i][j] = 0;if (k != 0){k--;}elsebreak;}if (board[i][j] == 0) {continue;}if (board[i][j] == board[i][k] && j != 0){board[i][k] = 2*board[i][k];board[i][j] = 0;}if (board[i][j] != board[i][k] && board[i][k] != 0){if ((k+1) !=j){board[i][k+1] = board[i][j];board[i][j] = 0;}}if (board[i][j] != board[i][k] && board[i][k] == 0){board[i][k] = board[i][j];board[i][j] = 0;}}}}//向右划else if((*touch_x1-*touch_x)>(*touch_y1-*touch_y)&&(*touch_x1-*touch_x)>(*touch_y-*touch_y1)){   // printf("这里是右\n");ifmove = 1;for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {int k = 0;if (board[i][j] == 0) {continue;}if (j != 3){k = j+1;}elsek = 3;while(board[i][k] == 0 ){board[i][k] = board[i][j];board[i][j] = 0;if (k != 3){k++;}elsebreak;}if (board[i][j] == 0) {continue;}if (board[i][j] == board[i][k] && j !=3){board[i][k] = 2*board[i][k];board[i][j] = 0;}if (board[i][j] != board[i][k] && board[i][k] != 0){if ((k-1)!=j){board[i][k-1] = board[i][j];board[i][j] = 0;}}if (board[i][j] != board[i][k] && board[i][k] == 0){board[i][k] = board[i][j];board[i][j] = 0;}}}}//向上划else if((*touch_x1-*touch_x)>(*touch_y1-*touch_y)&&(*touch_x1-*touch_x)<(*touch_y-*touch_y1)){   // printf("这里是上\n");ifmove = 1;/* 仿照左移操作,区别仅仅是行列互换后遍历 */for (int j = 0; j < 4; j++) {for (int i = 3; i >= 0; i--) {   int k = 0;if (board[i][j] == 0) {continue;}if (i != 0){k = i-1;}else k = 0;while(board[k][j] == 0){board[k][j] = board[i][j];board[i][j] = 0;if (k != 0){k--;}else break;}if (board[i][j] == 0) {continue;}if (board[i][j] == board[k][j] && i != 0){board[k][j] = 2*board[i][j];board[i][j] = 0;}if (board[i][j] != board[k][i] && board[k][i] != 0){if ((k+1) !=i){board[k+1][j] = board[i][j];board[i][j] = 0;}}if (board[i][j] != board[k][i] && board[k][i] == 0){board[k][i] = board[i][j];board[i][j] = 0;}}}}//向下划else if((*touch_y1-*touch_y)>(*touch_x-*touch_x1)&&(*touch_y1-*touch_y)>(*touch_x1-*touch_x)){// printf("这里是下\n");ifmove = 1;/* 仿照左移操作,区别仅仅是行列互换后遍历,且j和k都反向遍历 */for (int j = 0; j < 4; j++) {for (int i = 0; i< 4; i++) {int k = 0;if (board[i][j] == 0) {continue;}if (i != 3){k = i+1;}elsek = 3;while(board[k][j] == 0){board[k][j] = board[i][j];board[i][j] = 0;if (k !=3){k++;}elsebreak;}if (board[i][j] == 0) {continue;}if (board[i][j] == board[k][j] && i !=3){board[k][j] = 2*board[i][j];board[i][j] = 0;}if (board[i][j] != board[k][i] && board[k][i] != 0){if ((k-1) !=i){board[k-1][j] = board[i][j];board[i][j] = 0;}}if (board[i][j] != board[k][i] && board[k][i] == 0){board[k][i] = board[i][j];board[i][j] = 0;}}}}if (ifmove == 1){/* 这里再生成一个随机的2或者4,概率之比9:1 */n = 0;for (int l = 0; l < 4; ++l) {for (int m = 0; m < 4; ++m) {if (board[l][m] == 0){n = n+1;}          }}srand((unsigned int) time(0));n = rand() % n; /* 确定在何处空位置生成随机数 */for (int l = 0; l < 4; ++l) {       for (int m = 0; m < 4; ++m) {/* 定位待生成的位置 */if (board[l][m] == 0 && n-- == 0) {board[l][m] = (rand() % 10 ? 2 : 4); /* 生成数字2或4,生成概率为9:1 */}}}}//从头开始打印for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {if (board[i][j] == 0){showyxbmp(80,80,i,j,"num0.bmp");} if (board[i][j] == 2){showyxbmp(80,80,i,j,"num2.bmp");}  if (board[i][j] == 4){showyxbmp(80,80,i,j,"num4.bmp");}  if (board[i][j] == 8){showyxbmp(80,80,i,j,"num8.bmp");} if (board[i][j] == 16){showyxbmp(80,80,i,j,"num16.bmp");} if (board[i][j] == 32){showyxbmp(80,80,i,j,"num32.bmp");} if (board[i][j] == 64){showyxbmp(80,80,i,j,"num64.bmp");} if (board[i][j] == 128){showyxbmp(80,80,i,j,"num128.bmp");} if (board[i][j] == 256){showyxbmp(80,80,i,j,"num256.bmp");} if (board[i][j] == 512){showyxbmp(80,80,i,j,"num512.bmp");}if (board[i][j] == 1024){showyxbmp(80,80,i,j,"num1024.bmp");}if (board[i][j] == 2048){showyxbmp(80,80,i,j,"num2048.bmp");}if (board[i][j] == 4096){showyxbmp(80,80,i,j,"num4096.bmp");}if (board[i][j] == 8192){showyxbmp(80,80,i,j,"num8192.bmp");} }     }int ifgameover = 0;for (int i = 0; i < 3; i++) {for (int j = 0; j < 4; j++) {/* 横向和纵向比较挨着的两个元素是否相等,若有相等则游戏不结束 */if (board[i][j] == board[i][j + 1] || board[j][i] == board[j + 1][i]) {break;}elseifgameover++;}}//printf("ganmeover%d\n", ifgameover);if (ifgameover == 11){break;}if ((*touch_x>742) && (*touch_y<36)){break;}}printf("您已退出了游戏。\n");
}int main(int argc, char const *argv[])
{// int *touch_x = calloc(1,1000);// int *touch_x1 = calloc(1,1000);// int *touch_y = calloc(1,1000);// int *touch_y1 = calloc(1,1000);// showbmp(800,480,"zjm.bmp");// // showyxbmp(80,80,2,3,"num2.bmp");// while(1)// {//     //打开2048小游戏//     yxget_x_y(touch_x,touch_x1,touch_y,touch_y1);//get_x_y(touch_x,touch_y);// if ((*touch_x>119) &&(*touch_x<199) && (*touch_y>140) && (*touch_y<217) )// {play_game();// }// if ((*touch_x>742) && (*touch_y<36))// {//     break;// }// }// printf("已回到主界面。\n");// showbmp(800,480,"zjm.bmp");// return 0;
}

2048 右移逻辑,先找到第一个不为空格的数a[ i ][ j ],然后用另一个数组,与a[i][j]对比各种情况;
eg:当a[i][j]与a[i][k]相等时,a【i】【k】= a【i】【j】,a【i】【j】= 0;若不相等,则a【i】【k-1】= a【i】【j】;还有各种细节,可以看代码,上下左右都是同一个逻辑。

更多推荐

我的娱乐系统世界

本文发布于:2024-03-08 10:34:44,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1720632.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:系统   世界

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!