admin管理员组文章数量:1621658
学校安排我们去粤嵌实习,本人也是刚刚从实习回来,不过比起说是实习感觉更像是短时间的培训。以下代码是我们完成的项目其中的一个五子棋游戏,代码也是在网上搜索到后加以学习修改的,如果有什么不对的地方,还请见谅。
开发板我们使用的是粤嵌的6818开发板,因为使用的是ARM的处理器,所以将代码编写完成后我们是下载了一个Linux系统的虚拟机,在Linux系统中使用“arm-linux-gcc XXX.c -o XXX”指令生成一个能被ARM处理器读取的文件,然后再用SecureCRT下载到6818开发板中运行。
因为我们整个项目没有做文件的封装,我们将所有代码都整合在了一个文件中运行,所以库文件的调用其实并不需要调用这么多。
游戏中加入了背景音乐,需要用到madplay文件,如果没有madplay需要自行下载到/usr/bin路径下,madplay其实是一个开源的MP3播放器,对于音乐的播放暂停继续等操作可以直接使用它提供的指令。
代码中涉及到了显示屏和触碰屏的功能,这里就不继续一一讲述了,代码中也添加了许多注释,希望这些对你能有帮助。
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/input.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <math.h>
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;y<height;y++)
{
for(x=0;x<wide;x++)
{
b = bmp_buf[i++];
g = bmp_buf[i++];
r = bmp_buf[i++];
color = b | g << 8 | r << 16;
*(p+800*(height-1-y+y0)+x+x0) = color;
}
}
close(bmp_fd);
}
//图片触碰屏功能(无输入,输出触碰屏触屏位置,运行一次可输出一次)
int cppgn()
{
while(1)
{
//获取结构体成员的值
read(cpp_fd,&ts,sizeof(ts));
//判断是否为触摸屏事件
if(ts.type == EV_ABS)
{
if(ts.code == ABS_X) //X轴事件
{
//x = ts.value; //蓝色版本
t_x = ts.value*800/1024; //黑色版本
}
if(ts.code == ABS_Y) //Y轴事件
{
//y = ts.value; //蓝色版本
t_y = ts.value*480/600; //黑色版本
}
}
//判断是否松手
if(ts.type == EV_KEY && ts.code == BTN_TOUCH && ts.value == 0)
{
printf("(x:%d,y:%d)\n",t_x,t_y);
return 0;
}
}
}
int *lcd_fp=NULL;
struct fb_var_screeninfo lcd_info;
FILE *abs_screen ;
//数组棋盘
int sheet[16][16]={0};
//设置全屏背景颜色
void draw_background(int color)
{
printf("进入全屏背景\n");
for(int y = 0;y < 480;y++)
{
for(int x=0;x< 800;x++)
{
*(p + 800*y + x) = color; //颜色
}
}
}
//画左半圆,x、y为圆心
void draw_round1(int x,int y,int n,int color)
{
for(int i=0;i<=x;i++)
{
for(int j=0;j<480;j++)
{
int dx=x-i;
int dy=y-j;
if(dx*dx+dy*dy<=n*n)
{
*(p + 800*j + i) = color; //颜色
}
}
}
}
//画右半圆,x、y为圆心
void draw_round2(int x,int y,int n,int color)
{
for(int i=x;i<=800;i++)
{
for(int j=0;j<480;j++)
{
int dx=x-i;
int dy=y-j;
if(dx*dx+dy*dy<=n*n)
{
*(p + 800*j + i) = color; //颜色
}
}
}
}
//结算界面
void draw_taiji()
{
//设置底色为黄色
draw_background(0xffcc00);
//设置大圆
draw_round1(400,240,200,0xffffff);
draw_round2(400,240,200,0x000000);
//设置小半圆
draw_round1(400,140,100,0x000000);
draw_round2(400,340,100,0xffffff);
//设置最小圆
draw_round1(400,140,30,0xffffff);
draw_round2(400,140,30,0xffffff);
draw_round1(400,340,30,0x000000);
draw_round2(400,340,30,0x000000);
show(0,380,"./data/back.bmp");
show(700,0,"./data/end.bmp");
show(650,430,"./data/paihan.bmp");
show(0,0,"./data/again.bmp");
}
//画棋盘
void checkerboard()
{
//竖向
for(int i=10;i<480;i=i+30)
{
for(int j=10;j<460;j++)
{
*(p + 800*j + i) = 0x00000000;
}
}
//横向
for(int i=10;i<460;i++)
{
for(int j=10;j<480;j=j+30)
{
*(p + 800*j + i) = 0x00000000;
}
}
}
//排行榜
void leaderboard(int victory1,int victory2)
{
show(0,380,"./data/huitui.bmp");
show(0,70,"./data/num.bmp");
int m=0,n=0;
//循环画胜利次数个圆
for(int i=1;i<=victory1;i++)
{
draw_round1(i*100,130+m,30,0x000000);
draw_round2(i*100,130+m,30,0x000000);
//每画7个圆y轴加40
if(i%7==0)
m=m+40;
}
for(int j=1;j<=victory2;j++)
{
draw_round1(j*100,330+n,30,0xE0E0E0);
draw_round2(j*100,330+n,30,0xE0E0E0);
if(j%7==0)
n=n+40;
}
}
//下子
int chess(int color1,int color2,int num)
{
for(int i=10;i<480;i=i+30)
{
for(int j=10;j<480;j=j+30)
{
if(abs(t_x-i)<15&& abs(t_y-j)<15)
{
int x=i/30;
int y=j/30;
if(sheet[x][y]==0)
{
draw_round1(i,j,10,color1);
draw_round2(i,j,10,color1);
draw_round1(600,140,30,color2);
draw_round2(600,140,30,color2);
if(color1==0x000000)
{
sheet[x][y]=1;
num++;
}
else if(color1==0xE0E0E0)
{
sheet[x][y]=2;
num++;
}
}
}
}
}
return num;
}
//判断A是否连成五子
int AWin(int sum1)
{
//遍历判断五子
for(int i=0;i<16;i++)
{
for(int j=0;j<16;j++)
{
//当发现子时寻找周围连成线的四子判断是否相等
if(sheet[i][j]==1)
{
//横
for(int k=1;k<5;k++)
{
if(sheet[i][j]!=sheet[i][j+k])
{
sum1=0;
break;
}
else
sum1=k+1;
if(sum1==5)
return sum1;
}
//竖
for(int k=1;k<5;k++)
{
if(sheet[i][j]!=sheet[i+k][j])
{
sum1=0;
break;
}
else
sum1=k+1;
if(sum1==5)
return sum1;
}
//左斜
for(int k=1;k<5;k++)
{
if(sheet[i][j]!=sheet[i-k][j+k])
{
sum1=0;
break;
}
else
sum1=k+1;
if(sum1==5)
return sum1;
}
//右斜
for(int k=1;k<5;k++)
{
if(sheet[i][j]!=sheet[i+k][j+k])
{
sum1=0;
break;
}
else
sum1=k+1;
if(sum1==5)
return sum1;
}
}
}
}
return sum1;
}
//判断B是否连成五子
int BWin(int sum2)
{
//遍历判断五子
for(int i=0;i<16;i++)
{
for(int j=0;j<16;j++)
{
//当发现子时寻找周围连成线的四子判断是否相等
if(sheet[i][j]==2)
{
//横
for(int k=1;k<5;k++)
{
if(sheet[i][j]!=sheet[i][j+k])
{
sum2=0;
break;
}
else
sum2=k+1;
if(sum2==5)
return sum2;
}
//竖
for(int k=1;k<5;k++)
{
if(sheet[i][j]!=sheet[i+k][j])
{
sum2=0;
break;
}
else
sum2=k+1;
if(sum2==5)
return sum2;
}
//左斜
for(int k=1;k<5;k++)
{
if(sheet[i][j]!=sheet[i-k][j+k])
{
sum2=0;
break;
}
else
sum2=k+1;
if(sum2==5)
return sum2;
}
//右斜
for(int k=1;k<5;k++)
{
if(sheet[i][j]!=sheet[i+k][j+k])
{
sum2=0;
break;
}
else
sum2=k+1;
if(sum2==5)
return sum2;
}
}
}
}
return sum2;
}
//数组重新置为空
void chess_again()
{
for(int i=0;i<16;i++)
{
for(int j=0;j<16;j++)
sheet[i][j]=0;
}
}
//五子棋游戏驱动
int dakai()
{
printf("游戏运行\n");
//播放背景音乐
system("madplay bgm.mp3 -r &");
//读取胜利次数
int victory1 = 0;
int victory2 = 0;
nothing:
//主界面
show(0,0,"./data/start.bmp");
show(0 ,0 ,"fanhuianjian.bmp");
while (1)
{
if(cppgn() == 0)
{
if(t_x>266 && 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();
}
版权声明:本文标题:6818开发板五子棋游戏 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1728849933a1176545.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论