在Linux系统下基于ARM嵌入式的俄罗斯方块.docx
《在Linux系统下基于ARM嵌入式的俄罗斯方块.docx》由会员分享,可在线阅读,更多相关《在Linux系统下基于ARM嵌入式的俄罗斯方块.docx(35页珍藏版)》请在冰豆网上搜索。
在Linux系统下基于ARM嵌入式的俄罗斯方块
目录
1、摘要…………………………………………………………………………3
2、各种问题的具体介绍
(1)图形的如何存储问题………………………………………………………3
(2)图形的染色问题……………………………………………………………3
(3)游戏的屏幕显示问题………………………………………………………3
(4)方块图形的自动下移问题…………………………………………………3
(5)方块图形的左右移动问题…………………………………………………3
(6)方块图形的如何翻转问题…………………………………………………3
(7)图形移动时的自动消行问题………………………………………………3
(8)图形移动翻转时的边界判断问题…………………………………………3
(9)如何实现一键到底的问题…………………………………………………3
(10)各种移动的用键问题………………………………………………………3
(11)游戏时的自动冒行问题……………………………………………………3
(12)游戏时的作弊消行问题……………………………………………………3
(13)游戏时作弊方块出现问题…………………………………………………3
(14)游戏时的作弊炸弹使用问题………………………………………………4
三、流程图
流程图……………………………………………………………………5
四、实习总结
实习总结……………………………………………………………………6
五、附件
(1)程序源代码…………………………………………………………………6
(2)操作截图……………………………………………………………………18
六、参考文献………………………………………………………………………21
一、摘要
在Linux系统下使用vim编辑器实现如手机上的游戏俄罗斯方块,利用所学知识实现以下的各个问题。
二、各种问题的具体介绍
(1)图形的存储问题:
每个方块采用一个4*4的小数组存储,不同的方块给对应的数组赋不同的值,从1~7,以便打印是染不同的颜色,实现每种方块都有不同的颜色。
(2)图形的染色问题:
使用VT控制码对不同的图形涂不同的颜色。
(3)游戏屏幕的显示问题:
采用一个20*12的大数组,数组元素全部赋值为0,在终端打印空格,形成一片矩形区域,每个俄罗斯方块(以下简称方块)占4*4个空格的区域,赋值给大数组即可在终端打印出方块。
在大数组的上方再打印一个4*4的小数组,以显示下一个将出现的方块,并打印出得分,等级,计时等。
(4)方块图形的自动下移问题:
有一个变量记录方块下移的行数,并像左右移动一样打印向下移动的方块,设置一个信号,每一秒发送一个信号,进程每收到一次信号变量加一实现自动下移。
(5)方块图形的左右移动问题:
有一个变量记录方块第一行一列的坐标,左移时变量减一,右移时变量加一,把小数组原来在大数组的位置清零,在把小数组赋值到大数组相应坐标的位置即可打印出移动后的方块的位置,实现方块的左右移动。
(6)方块图形的如何翻转问题:
为了实现方块不同方向的转动,要新建一个4*4的新的小数组new,将存放方块的小数组按逆向旋转90度的方向存进new,把小数组清空,并把new的值重新赋值给小数组,大数组里方块原来的位置置零,把旋转后的小数组复制给大数组,即可打印出旋转后的方块。
(7)图形移动时的自动消行问题:
当大数组的某一行全部不为零时,既是达到了消行的条件,将大数组这样的行置零,其上的所有行下移一行(或多行),以实现消行的操作。
系统会根据消行的行数打印出鼓励语句,例如comeon,good,perect等。
(8)图形移动翻转时的边界判断问题:
方块左右移动或向下运动,当遇到左右边界或到底时应不再继续左移,右移或下移,此时要判断边界。
找出存放方块的小数组中所有不为0元素的元素在大数组的位置,判断大数组相应位置是否不为0,是否为边界,若满足两者之一即为到达边界
(9)如何实现一键到底的问题:
实现按一下x或向下键使方块从当前位置一下移到最后一行,先将方块当前位置清零,把小数组的值赋给大数组的最底,即可打印出移到最底的状态,即可实现一键到底。
(10)各种移动的用键问题:
左移使用‘d’键或者向左的箭头键,右移使用‘a’键或者向右的箭头键,翻转使用‘w’键或者向下的箭头键,一键到底使用‘x’键或者向下的箭头键。
(11)游戏时的自动冒行问题:
当玩家每累计得20分时会从底部随机冒出一行一增加难度。
大数组所有行向上移动一行,最后一行随机赋0~7的值。
(12)游戏时的作弊消行问题:
按e消去最后一行,当玩家希望减少行数时可使用此种方法。
将大数组的最后一行置零,并将除第一行的所有行下移一行,此时屏幕的最后一行被消除。
(13)游戏时作弊方块出现问题:
按m在按数字键1~7可以出玩家希望得到的方块。
数字1~7分别对应7种方块,当进程得到相应方块的命令时会把相应方块赋值给下一个将出现的方块小数组,打印到终端即可得到。
(14)游戏时的作弊炸弹使用问题:
按z键可在当前方块到底时炸掉它周围一些方块。
当方块到底时将其周围一些大数组置零。
三、流程图
四、实习总结
在Linux下使用红帽系统做出俄罗斯方块,最一开始接到这个项目时只知道游戏怎么玩,但是却不知道该怎么用所学的知识实现它,当时是如此的纠结。
我们的项目是要求以组为单位的,每个小组由4个人组成,以便训练我们与人的协同合作能力,所以接到项目以后我们小组四个人就聚在一起开始讨论,大概讨论了一下午才确定了项目的基本结构和大体流程,然后简单的分派了一下任务,把几个模块分派给不同的人来做,然后再把每个人写的组合在一起。
在写图形的翻转问题时遇到了好多问题,开始时我想了一种方法,可是写着写着突然发现写不下去了,如果用这种方法会出现好多连带的问题,可是我的思路已经固定在那了,再想其他的方法也会不知不觉的绕道以前带的问题上去,后来没办法,只能求助小组其他成员,因为我们是在协同作战,最后经过我们的一起努力完成的图形的翻转。
等游戏功能基本完成以后,我们又加上了一些自己的创意,比如作弊键。
完成以后再往前回顾后发现,有了思路以后项目是很容易完成的,最主要的是开始的思路混乱问题,那段时间时那么的心酸纠结,但是我的收获却也很多,例如,完成后的那种成就感是什么也没法替代的,再就是我们小组成员之间的合作也是相当值得骄傲的,这次的项目不仅使我们的知识更加牢固,也是我们小组成员间的交流更加顺畅,赢得了知识也赢得了友谊。
五、附件
1.程序源代码
#include
#include
#include
#include
#include
#defineM20
#defineN12
inta1[4][4]={0,1,1,0,//方块模型
0,0,1,0,
0,0,1,0};
inta2[4][4]={0,2,2,0,
0,2,0,0,
0,2,0,0};
inta3[4][4]={0,3,0,0,
3,3,3,0,
0,0,0,0};
inta4[4][4]={4,4,0,0,
4,4,0,0,
0,0,0,0};
inta5[4][4]={5,5,5,5};
inta6[4][4]={0,6,0,0,
0,6,6,0,
0,0,6,0};
inta7[4][4]={0,0,7,0,
0,7,7,0,
0,7,0,0};
inta[M][N]={0};//控制屏幕显示
intaa[4][4]={0};//存放旋转后的方块模型
intnew[4][4]={0};//存放下一个将要出现的方块模型
intblow=0;//计向下移动,行坐标
intleftright=0;//计左右移动
intsum=0;//记录消行总数
intscore=0;//记录总分数
charrank='A';//等级
intsecond=0;//记录开始游戏的时间
intmflag=0,v;//作弊出任意想要的方块模型的标志,V对应相应的方块模型
intzflag=0;
structtermiostermios_p[1]/*指针*/,termios_pb[1]/*副本*/;//键盘控制
voidoutput(intn,ints)//若s为1输出大数组,s为0输出next方块
{
switch(n){
case0:
if(s)
printf("*");
else
printf("");
break;
case1:
printf("\33[40m\33[0m");break;
case2:
printf("\33[41m\33[0m");break;
case3:
printf("\33[42m\33[0m");break;
case4:
printf("\33[43m\33[0m");break;
case5:
printf("\33[44m\33[0m");break;
case6:
printf("\33[45m\33[0m");break;
case7:
printf("\33[46m\33[0m");break;
}
}
voidconfigure()//计算得分,等级
{
score=sum*10;
rank='A'+score/50;
}
voidshow()//显示屏幕
{
inti,j;
configure();
printf("\t========================================\n");
printf("\t$\33[31m\33[4m\33[1mScore:
%3d\tRank:
%c\t\tTime:
%3d\33[0m$\n",score,rank,second);
printf("\t$\t\t\33[31m\33[4m\33[1mNext:
\33[0m$\n");
for(i=0;i<4;i++){
printf("\t$\t\t");
for(j=0;j<4;j++){
output(new[i][j],0);//输出next方块
}
printf("$\n");
}
printf("\t$\t--------------------------$\n");
for(i=0;iprintf("\t$\t|");
for(j=0;joutput(a[i][j],1);//输出大数组组成的屏幕
}
printf("|\t$\n");
}
printf("\t$\t--------------------------$\n");
printf("\t========================================\n");
}
voidcopy(intdes[4][4],intsor[4][4])//小数组复制到另一个小数组
{
inti,j;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
des[i][j]=sor[i][j];
}
}
}
voidpaint(intflag)//小数组(方块模型)画到大数组里
{
inti,j;
intm=blow;
intn=N/2-1+leftright;
for(i=3;i>=0;i--){
for(j=3;j>=0;j--){
if(aa[j][i]&&flag)
a[m+j][n+i]=aa[j][i];
elseif(aa[j][i]&&!
flag)
a[m+j][n+i]=0;
}
}
}
intisbottom()//判断是否到底及模型下是否有其他方块
{
intm=blow;
intn=N/2-1+leftright;
inti,j,k;
intl[4][2]={-1,-1,-1,-1,-1,-1,-1,-1};
for(i=0,k=0;i<4;i++,k++){
for(j=0;j<4;j++)
if(aa[j][i]){
l[k][0]=j+m;//每列最后一个元素的横坐标
l[k][1]=i+n;//每列最后一个元素的纵坐标
}
}
for(i=0;i{
if(l[i][0]==-1)
continue;
if(l[i][0]+1>=M||a[l[i][0]+1][l[i][1]])//最后一行是否到底,下一行是否有其他元素
return1;
}
return0;
}
intisleft()//判断是否到左边界
{
intm=blow;
intn=N/2-1+leftright;
inti,j,k=0;
intl[4][2]={-1,-1,-1,-1,-1,-1,-1,-1};
for(i=0,k=0;i<4;i++,k++){
for(j=3;j>=0;j--)
if(aa[i][j]){
l[k][0]=i+m;//每行最左边元素的横坐标
l[k][1]=j+n;//每行最左边元素的纵坐标
}
}
for(i=0;i{
if(l[i][0]==-1)
continue;
if(l[i][1]-1<0||a[l[i][0]][l[i][1]-1])
return1;
}
return0;
}
intisright()//判断是否到右边界
{
intm=blow;
intn=N/2-1+leftright;
inti,j,k=0;
intl[4][2]={-1,-1,-1,-1,-1,-1,-1,-1};
for(i=0,k=0;i<4;i++,k++){
for(j=0;j<4;j++)
if(aa[i][j]){
l[k][0]=i+m;//每行最右边元素的横坐标
l[k][1]=j+n;//每行最右边元素的纵坐标
}
}
for(i=0;i{
if(l[i][0]==-1)
continue;
if(l[i][1]+1>=N||a[l[i][0]][l[i][1]+1])
return1;
}
return0;
}
voidmove(intz)//大数组里的元素下移一行
{
intk,j;
for(k=z;k>0;k--){
for(j=0;ja[k][j]=a[k-1][j];
}
}
for(j=0;ja[0][j]=0;
}
interase()//一行满了消行
{
inti,j,k;
intflag,count=0;
for(i=0;iflag=1;
for(j=0;jif(!
a[i][j]){
flag=0;
break;
}
}
if(flag){
move(i);
count++;
}
}
returncount;
}
voidcheaterase()//作弊消去最后一行
{
inti,j;
move(M-1);
blow++;
}
voidcopyof(int(*aa)[4],intn)
{
switch(n){
case0:
copy(aa,a1);break;
case1:
copy(aa,a2);break;
case2:
copy(aa,a3);break;
case3:
copy(aa,a4);break;
case4:
copy(aa,a5);break;
case5:
copy(aa,a6);break;
case6:
copy(aa,a7);break;
}
}
intislose()
{
if(isbottom(a,aa)){
show(a);
printf("\t\t\33[31m\33[4m\33[1mGameover!
!
!
\33[0m\n");
return1;
}
return0;
}
voidclear(int(*aa)[4])
{
inti,j;
for(i=0;i<4;i++){
for(j=0;j<4;j++)
aa[i][j]=0;
}
}
intfindfirstline(int(*bb)[4])
{
intk,h,flag;
for(k=0;k<4;k++)
{flag=0;
for(h=0;h<4;h++)
{
if(bb[k][h])
flag=1;
}
if(flag)
returnk;
}
}
intfindfirstrow(int(*bb)[4])
{
intk,h,flag;
for(k=0;k<4;k++)
{flag=0;
for(h=0;h<4;h++)
{
if(bb[h][k])
{flag=1;
}
}
if(flag)
returnk;
}
}
voidchange()
{
intbb[4][4]={0};
inti,j,k,h,p,q;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
bb[j][i]=aa[i][3-j];
}
}
clear(aa);
i=findfirstline(bb);
j=findfirstrow(bb);
for(k=i,p=0;k<4;k++,p++){
for(h=j,q=0;h<4;h++,q++)
{
aa[p][q]=bb[k][h];
}
}
}
voidcheatbomb()
{
inti,j,n;
n=N/2-1+leftright;
for(i=blow;ifor(j=n-1;ja[i][j]=0;
}
voiddown()
{
if(isbottom())
{
if(zflag)
{
cheatbomb();
zflag=0;
}
bottomoperate();
}
else{
paint(0);
blow++;
paint
(1);
}
second++;
show();
alarm
(1);
}
voiddownbottom()
{
paint(0);
while(!
isbottom()){
blow++;
}
paint
(1);
}
voidleft()
{
if(!
isleft()){
paint(0);
leftright--;
paint
(1);
}
}
voidright()
{
if(!
isright()){
paint(0);
leftright++;
paint
(1);
}
}
voidturn()
{
if(!
isbottom()&&!
isleft()&&!
isright()){
paint(0);
change();
paint
(1);
}
}
voidprint(intcount)
{
switch(count){
case0:
printf("\t\t\t\33[36m\33[1mComeon!
\33[0m\n");break;
case1:
printf("\t\t\t\33[31m\33[1mGood!
\33[0m\n");break;
case2:
printf("\t\t\t\33[33m\33[1mPretty!
!
\33[0m\n");break;
case3:
printf("\t\t\t\33[34m\33[1mWonderful!
!
!
\33[0m\n");break;
case4:
printf("\t\t\t\33[35m\33[1m\33[4mPerfect^_^!
!
!
\33[0m\n");break;
}
}
intcheatmodel()
{
scanf("%d",&v);
getchar();
returnv;
}
voidappear()
{
inti,j,u;
for(i=0;ifor(j=0;ja[i][j]=a[i+1][j];
for(j=0;j{
if(j%3==0)
a[M-1][j]=rand()%8;
else
a[M-1][j]=0;
}
}
intbottomoperate()//到底或者下边有元素时要进行的操作
{
intcount,m;
count=erase(a);
sum+=count;
if(score&&score%10==0&&count)
appear();
print(count);
fflush(stdout);
if(mflag)
{
copyof(new,v);
mflag=0;
}
copy(aa,new);//把new模板里的图案给aa模板
m=rand()%7;//重新获得一个随机图案
copyof(new,m);//把新的图案赋给new模板
signal(SIGALRM,down);
alarm
(1);
blow=0;//行置0
leftright=0;//列置0
paint
(1);//把新的aa模板里的图案赋给大屏幕
if(islose(a,aa)){//判断是不是输了