学校安排我们去粤嵌实习,本人也是刚刚从实习回来,不过比起说是实习感觉更像是短时间的培训。以下代码是我们完成的项目其中的一个五子棋游戏,代码也是在网上搜索到后加以学习修改的,如果有什么不对的地方,还请见谅。
开发板我们使用的是粤嵌的6818开发板,因为使用的是ARM的处理器,所以将代码编写完成后我们是下载了一个Linux系统的虚拟机,在Linux系统中使用“arm-linux-gcc XXX.c -o XXX”指令生成一个能被ARM处理器读取的文件,然后再用SecureCRT下载到6818开发板中运行。
因为我们整个项目没有做文件的封装,我们将所有代码都整合在了一个文件中运行,所以库文件的调用其实并不需要调用这么多。
游戏中加入了背景音乐,需要用到madplay文件,如果没有madplay需要自行下载到/usr/bin路径下,madplay其实是一个开源的MP3播放器,对于音乐的播放暂停继续等操作可以直接使用它提供的指令。
代码中涉及到了显示屏和触碰屏的功能,这里就不继续一一讲述了,代码中也添加了许多注释,希望这些对你能有帮助。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int *p = NULL; //避免野指针,造成程序崩溃。
int lcd_fd = -1;//全局声明显示屏lcd_fd
int cpp_fd = -1;//全局声明触碰屏cpp_fd
int t_x,t_y; //触摸屏坐标
int wide, height;//图片的宽度(19~22),高度(23~26)
#define MMAP_SIZE 800*480*4
struct input_event ts;//定义一个结构体变量
void lcd_init()
{
//打开lcd
lcd_fd = open("/dev/fb0",O_RDWR);
if(lcd_fd < 0) //打开失败
{
perror("显示屏文件打开失败\n");
return;
}
//进行内存映射
p = mmap(NULL,800*480*4,PROT_READ | PROT_WRITE,MAP_SHARED,lcd_fd,0);
if(p == NULL)
{
perror("内存映射失败\n");
return;
}
}
//触碰屏文件打开
void cpp_init()
{
//打开触摸屏文件
cpp_fd = open("/dev/input/event0",O_RDWR);
if(cpp_fd < 0)
{
perror("触碰屏文件打开失败\n");
return;
}
}
//图标位置显示(输入坐标和图片地址,输出图片长宽,显示图片)
void show(int x0,int y0,char* path_name) // x0,y0图片起始坐标,path_name 图片路径
{
//打开cpp
int bmp_fd = open(path_name,O_RDWR);
if(bmp_fd < 0) //打开失败
{
perror("图片打开失败\n");
return;
}
//偏移54个字节
// lseek(bmp_fd,54,SEEK_SET);
lseek(bmp_fd,18,SEEK_SET);
read(bmp_fd,&wide,4);
read(bmp_fd,&height,4);
//printf("wide:%d height:%d\n",wide,height);
//读取图片数据
//偏移54个字节
lseek(bmp_fd,54,SEEK_SET);
char bmp_buf[wide*height*3];
read(bmp_fd,bmp_buf,wide*height*3);
int x,y,color,i=0;
char r,g,b;
for(y=0;y266 && t_y>360 &&t_x<532 &&t_y<480)//开始游戏
{
again:
//画出棋盘和相关按钮
draw_background(0xffffff);
show(0,0,"./data/checkerboard.bmp");
show(500,0,"./data/what.bmp");
show(700,380,"./data/huitui.bmp");
show(480,400,"./data/gameagain.bmp");
show(720,0,"./data/surrender.bmp");
checkerboard();
//黑棋先下
draw_round1(600,140,30,0x000000);
draw_round2(600,140,30,0x000000);
int num=0;//记录下子数
int sum1=0,sum2=0;//记录连子数
while (cppgn() == 0)
{
//返回主界面
if(t_x<800 && t_y>380 &&t_x>700 &&t_y<480)
{
chess_again();
goto nothing;
}
//重开
else if(t_x<560 && t_y>380 &&t_x>480 &&t_y<480)
{
chess_again();
goto again;
}
//投降
else if(t_x<800 && t_y>0 &&t_x>720 &&t_y<80)
{
//判断谁投降,另一个胜利
if(num%2==0)
{
draw_taiji();
show(50,120,"./data/bai.bmp");
victory2++;
break;
}
else if (num%2==1)
{
draw_taiji();
show(650,120,"./data/hei.bmp");
victory1++;
break;
}
}
//循环交替下子
else
{
if(num%2==0)
{
num=chess(0x000000,0xE0E0E0,num);
sum1=AWin(sum1);
//连子数为5,胜利,退出循环
if(sum1==5)
{
draw_taiji();
show(650,120,"./data/hei.bmp");
victory1++;
break;
}
}
else if(num%2==1)
{
num=chess(0xE0E0E0,0x000000,num);
sum2=BWin(sum2);
if(sum2==5)
{
draw_taiji();
show(50,120,"./data/bai.bmp");
victory2++;
break;
}
}
}
}
//清空数组,棋盘清理
chess_again();
click_one:
//返回主界面
if(cppgn() == 0)
{
if(t_x<150 && t_y>380 &&t_x>0 &&t_y<480)
{
goto nothing;
}
//退出游戏
else if(t_x<800 && t_y>0 &&t_x>700 &&t_y<100)
{
goto tuichu;
}
//重开
else if(t_x<100 && t_y>0 &&t_x>0 &t_y<100)
{
//返回棋盘位置
goto again;
}
//排行榜
else if(t_x<800 && t_y>400 &&t_x>600 &&t_y<480)
{
//画出排行榜界面
draw_background(0xffffff);
show(300,0,"./data/ban.bmp");
show(760,0,"./data/backstart.bmp");
//画出每个人的胜利次数
leaderboard(victory1,victory2);
click_two:
if(cppgn() == 0)
{
//重开
if(t_x<100 && t_y>380 &&t_x>0 &&t_y<480)
goto again;
//返回主界面
else if(t_x<800 && t_y>0 &&t_x>700 &&t_y<70)
goto nothing;
//点击其他区域重新获取点击
else
goto click_two;
}
}
else
{
//点击其他区域再次获取点击
goto click_one;
}
}
}
else if(t_x >= 0 && t_x <= 100 + 0 & t_y >= 0 && t_y <= 100 + 0)
{
tuichu:
system("killall -SIGKILL madplay");
return 0;
}
}
}
}
int main()
{
dakai();
}