嵌入式小项目:2048
先叠几层甲:
该项目中很多功能和函数的实现方法肯定有更简单更优化的,本文章里的方法属于比较笨的那种,仅供新手初学者以及博主自己参考,文章中提供的代码及源文件难免会有疏忽、bug,仅供参考、学习、交流;除了正常的讨论问题、建议外,还请各位大佬键盘之下给我留点面子qaq
关于屏幕的显示和触控、图片的显示,可以参考之前的文章:关于GEC6818屏幕的驱动方法(显示屏、触摸屏) 本文章默认已经成功驱动屏幕。
源码和图片素材会放到文章末尾,仅供参考。
2048算是一个很经典的小游戏了,逻辑简单,开发难度易上手,因此很适合作为熟悉Linux文件IO操作的例子。
我们先不写代码,先在ps里绘制好界面还有其他图片素材(
因为GEC6818的屏幕分辨率为480*800,因此将画布大小限制在该分辨率下进行编辑
PS中可以方便的查看鼠标所在位置的坐标,要事先记下每个按键的坐标位置、判定范围以留备用
至于PS怎么用那就不在本文讲解范围内了(
游戏界面
欢迎界面(
2048方块,以及分数的数字
文字也可以通过使用字符取模软件显示在屏幕上,但我认为不如直接显示图片简单效果好,因此这里就不做说明。
工程文件结构:
2048_imgs(用于存放图片素材)、main.c(主函数)、lcd.c(屏幕控制相关函数)、ts.c(触摸屏相关函数)、func.c(2048游戏相关函数)、chardata.c(用于存放各图片文件的路径等字符串,以及位置坐标等)
至于build.sh,里面是编译命令,也可以写Makefile,不过我觉得小工程用不上所以就没写,看自己习惯就好了~
路径、坐标参考(chardata.c):
int st_blocks[16]={0};//定义一个数组用于存储16个格子的状态
//定义三种事件响应的状态,默认为0(不响应)
int st_warn=0;//弹窗了吗?
int st_over=0;//游戏寄了吗?
int st_pause=0;//游戏暂停了吗?
int st_start=1;//欢迎页面是不是还没显示?
//定义文件路径
char *homebg="2048_imgs/home.bmp";//home界面
char *mainbg="2048_imgs/main.bmp";//主界面
char *warn_rest_img="2048_imgs/warn_rest.bmp";//询问弹窗
char *warn_over_img="2048_imgs/warn_over.bmp";//游戏结束弹窗
char *warn_pause_img="2048_imgs/pause.bmp";//游戏暂停弹窗
//2,4,8,16,32,64,128,256,512,1024,2048的图片
char *a2_img="2048_imgs/2.bmp";
char *a4_img="2048_imgs/4.bmp";
char *a8_img="2048_imgs/8.bmp";
char *a16_img="2048_imgs/16.bmp";
char *a32_img="2048_imgs/32.bmp";
char *a64_img="2048_imgs/64.bmp";
char *a128_img="2048_imgs/128.bmp";
char *a256_img="2048_imgs/256.bmp";
char *a512_img="2048_imgs/512.bmp";
char *a1024_img="2048_imgs/1024.bmp";
char *a2048_img="2048_imgs/2048.bmp";
//得分的0-9字符
char *s0="2048_imgs/n0.bmp";
char *s1="2048_imgs/n1.bmp";
char *s2="2048_imgs/n2.bmp";
char *s3="2048_imgs/n3.bmp";
char *s4="2048_imgs/n4.bmp";
char *s5="2048_imgs/n5.bmp";
char *s6="2048_imgs/n6.bmp";
char *s7="2048_imgs/n7.bmp";
char *s8="2048_imgs/n8.bmp";
char *s9="2048_imgs/n9.bmp";
//定义16*16每个格子的坐标值
int a1x=382,a1y=56;
int a2x=482,a2y=56;
int a3x=582,a3y=56;
int a4x=682,a4y=56;
int a5x=382,a5y=156;
int a6x=482,a6y=156;
int a7x=582,a7y=156;
int a8x=682,a8y=156;
int a9x=382,a9y=256;
int a10x=482,a10y=256;
int a11x=582,a11y=256;
int a12x=682,a12y=256;
int a13x=382,a13y=356;
int a14x=482,a14y=356;
int a15x=582,a15y=356;
int a16x=682,a16y=356;
//定义5位得分的字符位置
int num0x=230,num0y=28;
int num1x=199,num1y=28;
int num2x=168,num2y=28;
int num3x=137,num3y=28;
int num4x=106,num4y=28;
//定义弹窗的位置
int warninfo_x=155;
int warninfo_y=108;
//定义按键的触摸判定范围
int main_rest_minx=14;//主界面的重新开始按钮
int main_rest_maxx=332;
int main_rest_miny=520;
int main_rest_maxy=595;
int warn_yes_minx=247;//重新开始弹窗yes按钮
int warn_yes_maxx=456;
int warn_yes_miny=367;
int warn_yes_maxy=443;
int warn_no_minx=570;//重新开始弹窗no按钮
int warn_no_maxx=778;
int warn_no_miny=367;
int warn_no_maxy=443;
int over_rest_minx=353;//游戏结束弹窗的重新开始按钮
int over_rest_maxx=671;
int over_rest_miny=362;
int over_rest_maxy=438;
int pause_button_minx=90;//暂停按钮
int pause_button_maxx=275;
int pause_button_miny=257;
int pause_button_maxy=443;
int pause_conti_minx=353;//游戏暂停弹窗的继续按钮
int pause_conti_maxx=671;
int pause_conti_miny=362;
int pause_conti_maxy=438;
使用一维数组(这里是st)用于存储4*4格子内的数字状态,当然用二维数组也更直观,这里按照个人习惯来就好。
以下函数具体请看注释,咱基本都写清楚了,如有疑问可在评论区讨论~(代码存在复制粘贴偷懒的情况,如果看到int a[1]之类的奇怪操作请不要奇怪,按照你的想法来就好~)
随机生成2和4以及随机位置:
void rand_sum(int *a1,int *a2)//随机生成2个2或4的随机数用于生成方块
{
int a[2]/*用于保存2个产生的随机数*/, i;
srand((unsigned int)time(NULL));//设置当前时间为种子
for (i = 0; i < 2; i++){
a[i] = rand()%2+1;//产生1~2的随机数
}
//传出生成的随机数2 4
if(a[0]==1)*a1=2;
else *a1=4;
if(a[1]==1)*a2=2;
else *a2=4;
printf("num:%d %d\n",*a1,*a2);
return;
}
void rand_time(int *a1)//随机生成1个1-2的随机数(用于随机第一次生成一个数字块还是两个数字块)
{
int a[1]/*用于保存1个产生的随机数*/, i;
srand((unsigned int)time(NULL));//设置当前时间为种子
for (i = 0; i < 1; i++){
a[i] = rand()%2+1;//产生1~2的随机数
}
//传出生成的随机数
*a1=a[0];
printf("time:%d\n",*a1);
return;
}
void rand_sum_loc(int *a1)//随机生成1个位置
{
int p=0,q=0;
for(int x=0;x<16;x++)
{
if(st_blocks[x]==0)
p++;
}
int m[p];//存储了空位的位置
for(int x=0,y=0;x<16;x++)
{
if(st_blocks[x]==0)
{
m[y]=x;
y++;
}
}
int a[1]/*用于保存1个产生的随机数*/,i;
srand((unsigned int)time(NULL));//设置当前时间为种子
for (i = 0; i < 1; ++i)
{
a[i] = rand()%p+1;//产生1~p的随机数
}
printf("r=%d\n",a[0]);
//传出生成的随机位置
*a1=m[a[0]-1];
return;
}
根据st数组内容打印方块:
void print_img_blocks(int num,int loc)//打印方块到格子中
{
int cx,cy;
switch(loc)
{
case 0:{cx=a1x;cy=a1y;}break;
case 1:{cx=a2x;cy=a2y;}break;
case 2:{cx=a3x;cy=a3y;}break;
case 3:{cx=a4x;cy=a4y;}break;
case 4:{cx=a5x;cy=a5y;}break;
case 5:{cx=a6x;cy=a6y;}break;
case 6:{cx=a7x;cy=a7y;}break;
case 7:{cx=a8x;cy=a8y;}break;
case 8:{cx=a9x;cy=a9y;}break;
case 9:{cx=a10x;cy=a10y;}break;
case 10:{cx=a11x;cy=a11y;}break;
case 11:{cx=a12x;cy=a12y;}break;
case 12:{cx=a13x;cy=a13y;}break;
case 13:{cx=a14x;cy=a14y;}break;
case 14:{cx=a15x;cy=a15y;}break;
case 15:{cx=a16x;cy=a16y;}break;
}
switch(num)
{
case 0:break;
case 2:load_img(a2_img,cx,cy);break;
case 4:load_img(a4_img,cx,cy);break;
case 8:load_img(a8_img,cx,cy);break;
case 16:load_img(a16_img,cx,cy);break;
case 32:load_img(a32_img,cx,cy);break;
case 64:load_img(a64_img,cx,cy);break;
case 128:load_img(a128_img,cx,cy);break;
case 256:load_img(a256_img,cx,cy);break;
case 512:load_img(a512_img,cx,cy);break;
case 1024:load_img(a1024_img,cx,cy);break;
case 2048:load_img(a2048_img,cx,cy);break;
}
}
void load_st()//根据st数组中的状态还原打印格子中的数
{
for(int i=0;i<16;i++)
{
print_img_blocks(st_blocks[i],i);
}
}
void st_reset()//清空状态数组
{
for(int i=0;i<16;i++)
{
st_blocks[i]=0;
}
}
int st_isfull()//判断格子是否已满,是返回1,否返回0
{
int st=1;
for(int i=0;i<16;i++)
{
if(st_blocks[i]==0)
{
st=0;
}
}
return st;
}
这段也没有什么可说的……就是根据数组里的内容照着把数字的图片显示到对应的位置上……以及判断还有没有地方qwq
这里我设定游戏开始时生成1-2个方块,可能是2也可能是4,游戏进行中的时候每次滑动只会生成一个方块,2或4,因此:
void first_rand_block()//第一次随机生成
{
int a,b,loc,time;
int rac[2]={0};//随机生成的方块的值
rand_sum(&a,&b);//随机2个2或4
rac[0]=a;rac[1]=b;
rand_time(&time);//随机生成次数(1次或2次)
for(int i=0;i<time;i++)
{
rand_sum_loc(&loc);//随机一个位置
printf("loc:%d\n",loc);
st_blocks[loc]=rac[i];
}
load_st();
}
void gamein_rand_block()//游戏中随机生成
{
int a,b,loc;
rand_sum(&a,&b);//随机2个2或4
rand_sum_loc(&loc);//随机一个位置
printf("loc:%d\n",loc);
st_blocks[loc]=a;
load_st();
}
滑动后根据方向移动方块:
逻辑很简单,顺着方向贴贴就好了(
void move_blocks(int z)//方块移动
{
if(z==1)//up
{
for(int i=0;i<4;i++)
{
for(int j=4;j<16;j++)
{
if(st_blocks[j]!=0 && st_blocks[j-4]==0)//如果上面是空的
{
st_blocks[j-4]=st_blocks[j];
st_blocks[j]=0;
}
}
}
}
if(z==2)//down
{
for(int i=0;i<4;i++)
{
for(int j=0;j<12;j++)
{
if(st_blocks[j]!=0 && st_blocks[j+4]==0)//如果下面是空的
{
st_blocks[j+4]=st_blocks[j];
st_blocks[j]=0;
}
}
}
}
if(z==3)//left
{
for(int i=0;i<4;i++)
{
for(int j=0;j<16;j++)
{
if((j!=0 && j!=4 && j!=8 && j!=12) && st_blocks[j]!=0 && st_blocks[j-1]==0)//如果左面是空的
{
st_blocks[j-1]=st_blocks[j];
st_blocks[j]=0;
}
}
}
}
if(z==4)//right
{
for(int i=0;i<4;i++)
{
for(int j=0;j<16;j++)
{
if((j!=3 && j!=7 && j!=11 && j!=15) && st_blocks[j]!=0 && st_blocks[j+1]==0)//如果右面是空的
{
st_blocks[j+1]=st_blocks[j];
st_blocks[j]=0;
}
}
}
}
printf("move:\n\
%d %d %d %d\n\
%d %d %d %d\n\
%d %d %d %d\n\
%d %d %d %d\n\
",st_blocks[0],st_blocks[1],st_blocks[2],st_blocks[3],st_blocks[4],st_blocks[5],st_blocks[6],st_blocks[7]\
,st_blocks[8],st_blocks[9],st_blocks[10],st_blocks[11],st_blocks[12],st_blocks[13],st_blocks[14],st_blocks[15]);
}
方块合并:
这里的逻辑是按照方向,检测前面的方块是不是一样的数,如果是相加,并且如果相加后的方块前方还有相同的(和相加之后的方块相同)也不进行合并。
void plus_blocks(int z)//方块相加
{
if(z==1)//up
{
int sta[16]={0};
for(int i=15;i>=0;i--)
{
if(st_blocks[i]!=0 && i>=12 && i<16)//在最后一行
{
if(st_blocks[i]==st_blocks[i-4])//匹配上个
{
score+=st_blocks[i];
st_blocks[i-4]=(st_blocks[i]+st_blocks[i-4]);
st_blocks[i]=0;
sta[i-4]=1;
}
else if(st_blocks[i]==st_blocks[i-8]&&st_blocks[i-4]==0 && sta[i]==0)//匹配上上个并且中间没东西
{
score+=st_blocks[i];
st_blocks[i-8]=(st_blocks[i]+st_blocks[i-8]);
st_blocks[i]=0;
sta[i-4]=1;
}
else if(st_blocks[i]==st_blocks[i-12]&&st_blocks[i-4]==0 && st_blocks[i-8]==0 && sta[i]==0)//匹配上上上个并且中间没东西
{
score+=st_blocks[i];
st_blocks[i-12]=(st_blocks[i]+st_blocks[i-12]);
st_blocks[i]=0;
sta[i-4]=1;
}
}
else if(st_blocks[i]!=0 && i>=8 && i<12)//在第三行
{
if(st_blocks[i]==st_blocks[i-4] && sta[i]==0)//匹配上个
{
score+=st_blocks[i];
st_blocks[i-4]=(st_blocks[i]+st_blocks[i-4]);
st_blocks[i]=0;
sta[i-4]=1;
}
else if(st_blocks[i]==st_blocks[i-8]&&st_blocks[i-4]==0 && sta[i]==0)//匹配上上个并且中间没东西
{
score+=st_blocks[i];
st_blocks[i-8]=(st_blocks[i]+st_blocks[i-8]);
st_blocks[i]=0;
sta[i-4]=1;
}
}
else if(st_blocks[i]!=0 && i>=4 && i<8)//在第二行
{
if(st_blocks[i]==st_blocks[i-4] && sta[i]==0)
{
score+=st_blocks[i];
st_blocks[i-4]=(st_blocks[i]+st_blocks[i-4]);
st_blocks[i]=0;
sta[i-4]=1;
}
}
}
}
if(z==2)//down
{
int sta[16]={0};
for(int i=0;i<12;i++)
{
if(st_blocks[i]!=0 && i>=0 && i<4)//在第一行
{
if(st_blocks[i]==st_blocks[i+4])//匹配下个
{
score+=st_blocks[i];
st_blocks[i+4]=(st_blocks[i]+st_blocks[i+4]);
st_blocks[i]=0;
sta[i+4]=1;
}
else if(st_blocks[i]==st_blocks[i+8]&&st_blocks[i+4]==0 && sta[i]==0)//匹配下下个并且中间没东西
{
score+=st_blocks[i];
st_blocks[i+8]=(st_blocks[i]+st_blocks[i+8]);
st_blocks[i]=0;
sta[i+4]=1;
}
else if(st_blocks[i]==st_blocks[i+12]&&st_blocks[i+4]==0 && st_blocks[i+8]==0 && sta[i]==0)//匹配下下下个并且中间没东西
{
score+=st_blocks[i];
st_blocks[i+12]=(st_blocks[i]+st_blocks[i+12]);
st_blocks[i]=0;
sta[i+4]=1;
}
}
else if(st_blocks[i]!=0 && i>=4 && i<8)//在第二行
{
if(st_blocks[i]==st_blocks[i+4] && sta[i]==0)//匹配下个
{
score+=st_blocks[i];
st_blocks[i+4]=(st_blocks[i]+st_blocks[i+4]);
st_blocks[i]=0;
sta[i+4]=1;
}
else if(st_blocks[i]==st_blocks[i+8]&&st_blocks[i+4]==0 && sta[i]==0)//匹配下下个并且中间没东西
{
score+=st_blocks[i];
st_blocks[i+8]=(st_blocks[i]+st_blocks[i+8]);
st_blocks[i]=0;
sta[i+4]=1;
}
}
else if(st_blocks[i]!=0 && i>=8 && i<12)//在第三行
{
if(st_blocks[i]==st_blocks[i+4] && sta[i]==0)
{
score+=st_blocks[i];
st_blocks[i+4]=(st_blocks[i]+st_blocks[i+4]);
st_blocks[i]=0;
sta[i+4]=1;
}
}
}
}
if(z==3)//left
{
int sta[16]={0};
for(int i=15;i>=0;i--)
{
if(st_blocks[i]!=0&&(i!=0 && i!=4 && i!=8 && i!=12)&&(i==3||i==7||i==11||i==15))//在第4列
{
if(st_blocks[i]==st_blocks[i-1])//匹配左1个
{
score+=st_blocks[i];
st_blocks[i-1]=(st_blocks[i]+st_blocks[i-1]);
st_blocks[i]=0;
sta[i-1]=1;
}
else if(sta[i]==0 && st_blocks[i-1]==0 && st_blocks[i]==st_blocks[i-2])//匹配左左1个并且中间没东西
{
score+=st_blocks[i];
st_blocks[i-2]=(st_blocks[i]+st_blocks[i-2]);
st_blocks[i]=0;
sta[i-1]=1;
}
else if(sta[i]==0 && st_blocks[i-1]==0 && st_blocks[i-2]==0 && st_blocks[i]==st_blocks[i-3])//匹配左左左1个并且中间没东西
{
score+=st_blocks[i];
st_blocks[i-3]=(st_blocks[i]+st_blocks[i-3]);
st_blocks[i]=0;
sta[i-1]=1;
}
}
else if(st_blocks[i]!=0&&(i!=0 && i!=4 && i!=8 && i!=12)&&(i==2||i==6||i==10||i==14))//在第3列
{
if(sta[i]==0 && st_blocks[i]==st_blocks[i-1])//匹配左1个
{
score+=st_blocks[i];
st_blocks[i-1]=(st_blocks[i]+st_blocks[i-1]);
st_blocks[i]=0;
sta[i-1]=1;
}
else if(sta[i]==0 && st_blocks[i-1]==0 && st_blocks[i]==st_blocks[i-2])//匹配左左1个并且中间没东西
{
score+=st_blocks[i];
st_blocks[i-2]=(st_blocks[i]+st_blocks[i-2]);
st_blocks[i]=0;
sta[i-1]=1;
}
}
else if(st_blocks[i]!=0&&(i!=0 && i!=4 && i!=8 && i!=12)&&(i==1||i==5||i==9||i==13))//在第二列
{
if(sta[i]==0 && st_blocks[i]==st_blocks[i-1])//匹配左1个
{
score+=st_blocks[i];
st_blocks[i-1]=(st_blocks[i]+st_blocks[i-1]);
st_blocks[i]=0;
sta[i-1]=1;
}
}
}
}
if(z==4)//right
{
int sta[16]={0};
for(int i=0;i<16;i++)
{
if(st_blocks[i]!=0&&(i!=3 && i!=7 && i!=11 && i!=15)&&(i==0||i==4||i==8||i==12))//在第1列
{
if(st_blocks[i]==st_blocks[i+1])//匹配右1个
{
score+=st_blocks[i];
st_blocks[i+1]=(st_blocks[i]+st_blocks[i+1]);
st_blocks[i]=0;
sta[i+1]=1;
}
else if(sta[i]==0 && st_blocks[i+1]==0 && st_blocks[i]==st_blocks[i+2])//匹配右右1个并且中间没东西
{
score+=st_blocks[i];
st_blocks[i+2]=(st_blocks[i]+st_blocks[i+2]);
st_blocks[i]=0;
sta[i+1]=1;
}
else if(sta[i]==0 && st_blocks[i+1]==0 && st_blocks[i+2]==0 && st_blocks[i]==st_blocks[i+3])//匹配右右右1个并且中间没东西
{
score+=st_blocks[i];
st_blocks[i+3]=(st_blocks[i]+st_blocks[i+3]);
st_blocks[i]=0;
sta[i+1]=1;
}
}
else if(st_blocks[i]!=0&&(i!=3 && i!=7 && i!=11 && i!=15)&&(i==1||i==5||i==9||i==13))//在第2列
{
if(sta[i]==0 && st_blocks[i]==st_blocks[i+1])//匹配右1个
{
score+=st_blocks[i];
st_blocks[i+1]=(st_blocks[i]+st_blocks[i+1]);
st_blocks[i]=0;
sta[i+1]=1;
}
else if(sta[i]==0 && st_blocks[i+1]==0 && st_blocks[i]==st_blocks[i+2])//匹配左左1个并且中间没东西
{
score+=st_blocks[i];
st_blocks[i+2]=(st_blocks[i]+st_blocks[i+2]);
st_blocks[i]=0;
sta[i+1]=1;
}
}
else if(st_blocks[i]!=0&&(i!=3 && i!=7 && i!=11 && i!=15)&&(i==2||i==6||i==10||i==14))//在第3列
{
if(sta[i]==0 && st_blocks[i]==st_blocks[i+1])//匹配右1个
{
score+=st_blocks[i];
st_blocks[i+1]=(st_blocks[i]+st_blocks[i+1]);
st_blocks[i]=0;
sta[i+1]=1;
}
}
}
}
printf("%d %d %d %d\n\
%d %d %d %d\n\
%d %d %d %d\n\
%d %d %d %d\n\
",st_blocks[0],st_blocks[1],st_blocks[2],st_blocks[3],st_blocks[4],st_blocks[5],st_blocks[6],st_blocks[7]\
,st_blocks[8],st_blocks[9],st_blocks[10],st_blocks[11],st_blocks[12],st_blocks[13],st_blocks[14],st_blocks[15]);
}
打印分数:
取余获取分数的每一位,然后打印到屏幕上
void print_score()//打印得分
{
printf("%d\n",score);
if(score>=99999)return;
int a[5]={0};
a[0]=score%10;
a[1]=(score/10)%10;
a[2]=(score/100)%10;
a[3]=(score/1000)%10;
a[4]=(score/10000)%10;
char *num_cha=NULL;
int loc_x,loc_y;
for(int i=0;i<5;i++)
{
switch(a[i])
{
case 0:num_cha=s0;break;
case 1:num_cha=s1;break;
case 2:num_cha=s2;break;
case 3:num_cha=s3;break;
case 4:num_cha=s4;break;
case 5:num_cha=s5;break;
case 6:num_cha=s6;break;
case 7:num_cha=s7;break;
case 8:num_cha=s8;break;
case 9:num_cha=s9;break;
}
switch(i)
{
case 0:{loc_x=num0x;loc_y=num0y;}break;
case 1:{loc_x=num1x;loc_y=num1y;}break;
case 2:{loc_x=num2x;loc_y=num2y;}break;
case 3:{loc_x=num3x;loc_y=num3y;}break;
case 4:{loc_x=num4x;loc_y=num4y;}break;
}
load_img(num_cha,loc_x,loc_y);
}
}
判定游戏是否无法继续:
遍历每个方块看看周围有没有可以合并的方块
int game_isover()//判定游戏是否无法继续
{
if(!(st_isfull()))return 1;//如果格子还没满就直接滚
int isover=0;
for(int i=0;i<16;i++)
{
if(i==0||i==3||i==12||i==15)//四角
{
if(i==0 && (st_blocks[i]==st_blocks[i+1]||st_blocks[i]==st_blocks[i+4]))
isover=1;
else if(i==3 && (st_blocks[i]==st_blocks[i-1]||st_blocks[i]==st_blocks[i+4]))
isover=1;
else if(i==12 && (st_blocks[i]==st_blocks[i+1]||st_blocks[i]==st_blocks[i-4]))
isover=1;
else if(i==15 && (st_blocks[i]==st_blocks[i-1]||st_blocks[i]==st_blocks[i-4]))
isover=1;
}
else if(i==1||i==2||i==4||i==8||i==7||i==11||i==13||i==14)//在四边
{
if((i==1||i==2) && (st_blocks[i]==st_blocks[i-1]||st_blocks[i]==st_blocks[i+1]||st_blocks[i]==st_blocks[i+4]))
isover=1;
else if((i==4||i==8) && (st_blocks[i]==st_blocks[i-4]||st_blocks[i]==st_blocks[i+4]||st_blocks[i]==st_blocks[i+1]))
isover=1;
if((i==7||i==11) && (st_blocks[i]==st_blocks[i-4]||st_blocks[i]==st_blocks[i+4]||st_blocks[i]==st_blocks[i-1]))
isover=1;
if((i==13||i==14) && (st_blocks[i]==st_blocks[i-1]||st_blocks[i]==st_blocks[i+1]||st_blocks[i]==st_blocks[i-4]))
isover=1;
}
else if(i==5||i==6||i==9||i==10)//在中间
{
if(st_blocks[i]==st_blocks[i-4]||st_blocks[i]==st_blocks[i+4]||st_blocks[i]==st_blocks[i-1]||st_blocks[i]==st_blocks[i+1])
isover=1;
}
}
return isover;
}
滑动时调用以上函数:
int scr_num_con(int z)//根据滑动方向执行不同的操作
{
//合并移动数字方块
plus_blocks(z);
move_blocks(z);
//再随机生成一个
if(!(st_isfull()))
{
gamein_rand_block();//随机生成方块
load_img(mainbg,0,0);//加载主界面
load_st();//打印方块
print_score();//打印得分
return 1;
}
}
游戏开始时的初始化:
void game_start()
{
score=0;
lcd_clear(0x00ffffff);//清屏
load_img(mainbg,0,0);//加载主界面
print_score();//打印得分
st_reset();//清空状态数组
first_rand_block();//初始化格子,生成最开始的1个或2个数字
}
检测触摸操作:
判断坐标是否落在按钮的范围内即可
void touch_scan()
{
while(1)
{
if(!(game_isover()))//判断游戏是否结束
{
load_img(warn_over_img,warninfo_x,warninfo_y);//游戏结束弹窗
st_over=1;//游戏结束,不响应弹窗以外的触摸
}
int z=get_touchscreen_index(&x,&y);//扫描触摸屏状态
if(x>0 && x<50*1.28 && y>0 && y<50*1.28)//点击屏幕左上角时退出游戏
{
exit(-1);
}
if(st_warn==0 && st_over==0 && st_pause==0 && x>=main_rest_minx && x<main_rest_maxx &&\
y>=main_rest_miny && y<main_rest_maxy)//点击主界面的重新开始
{
load_img(warn_rest_img,warninfo_x,warninfo_y);//弹窗询问
st_warn=1;//弹窗,不响应弹窗以外触摸
}
if(st_warn==1 && x>=warn_yes_minx && x<warn_yes_maxx &&\
y>=warn_yes_miny && y<warn_yes_maxy)//如果点击弹窗内的确定
{
st_warn=0;
return;
//重新开始游戏
}
if(st_warn==1 && x>=warn_no_minx && x<warn_no_maxx &&\
y>=warn_no_miny && y<warn_no_maxy)//如果点击弹窗内的取消
{
st_warn=0;
load_img(mainbg,0,0);//加载主界面
load_st();//根据st数组中的状态还原打印格子中的数
print_score();//打印得分
//继续游戏
}
if(st_warn==0 && st_over==0 && st_pause==0 && x>=pause_button_minx && x<pause_button_maxx &&\
y>=pause_button_miny && y<pause_button_maxy)//点击主界面的暂停
{
load_img(warn_pause_img,warninfo_x,warninfo_y);
st_pause=1;//弹窗,不响应弹窗以外触摸
}
if(st_pause==1 && x>=pause_conti_minx && x<pause_conti_maxx && y>=pause_conti_miny &&\
y<pause_conti_maxy)//如果点击暂停弹窗内的继续
{
st_pause=0;
load_img(mainbg,0,0);//加载主界面
load_st();//根据st数组中的状态还原打印格子中的数
print_score();//打印得分
//继续游戏
}
if(st_warn==0 && st_over==0 && st_pause==0 && z!=-1)//滑动
{
scr_num_con(z);
}
if(st_over==1 && x>=over_rest_minx && x<over_rest_maxx && y>=over_rest_miny &&\
y<over_rest_maxy)//如果点击游戏结束弹窗内的按钮
{
st_over=0;
return;
//重新开始游戏
}
}
}
主函数:
int main()
{
int fd=lcd_init();//初始化显示屏
lcd_clear(0x00ffffff);//清屏
load_img(homebg,0,0);//加载欢迎界面
while(1)
{
int z=get_touchscreen_index(&x,&y);
if(st_start==1 && z==-1)//还在欢迎界面时点击屏幕开始游戏
{
st_start=0;
}
while(st_start==0)
{
game_start();
touch_scan();
}
}
lcd_uninit(fd);
}
好了,这就是游戏的所有核心代码啦,编译后传到开发板运行试试看~
欢迎界面
游戏界面
游戏寄力(悲
游戏暂停
重新开始
那么本项目就到这里啦,下面放出源码和图片素材!
- 感谢你赐予我前进的力量