趣味小游戏:用单片机和LED灯阵制作的贪吃蛇趣味小游戏 附源代码

sw

最近几天天气总是在下雨,对于不爱玩手机游戏的我来说过得太无聊了。

想想怎么才能让时间过得快一点呢,这个时候我看到电视里的一个广告类似贪吃蛇的,于是抱着试试看的想法用单片机和LED灯阵做了一个贪吃蛇的游戏,基本功能都有,玩起来体验还可以,总算可以充分利用时间了。

下面我就把制作过程和文件分享给大家

用一个18650电池供电,用一个单片机进行控制

名称:8X8点阵贪吃蛇

功能如下:

按右键开始、中间可以选择速度1最慢9最快(飞一般的感觉)

速度2和9,哎呀呀,自己撞死了(可以穿墙,撞到自己的身体死亡)

按中间确定可查看吃到了多少

暂停

废话不多说先上实物图:

实物图1

实物图2

焊接实物图1由于时间比较急线布得有点乱啊

#include""

sbitd=P2^4;

sbita=P2^0;

sbitw=P2^2;

sbits=P2^6;

sbitkey=P2^7;

unsignedcharcoden[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01},n0[8]={0x08,0x04,0x02,0x01,0x10,0x20,0x40,0x80};

unsignedcharsnake[8][8],xmax,ymax,xmin,ymin,max=0,min=200,eat=0,ch='d',num=0,f=0,cun=0,food=1,hz=0,n1=0,v=2;

voidlate(unsignedinti)

{

for(;i0;i--);

}

voidxian(unsignedchary0,unsignedcharx0,unsignedchary1,unsignedcharx1,unsignedcharon)

//在数组snake[][]中绘直线的函数,(x0,y0)to(x1,y1)on,0:off1:常亮2:以1:1亮灭时间比闪烁

{

chari,j,nx,ny;

if(x0x1)

nx=-1;

elseif(x0==x1)

nx=0;

else

nx=1;

if(y0y1)

ny=-1;

elseif(y0==y1)

ny=0;

else

ny=1;

for(i=y0,j=x0;i!=y1+ny||j!=x1+nx;i=ny+i,j=nx+j)

snake[j][i]=on;

}

voidprint(void)//把二维数组snake[][]转换点阵的函数,数组某元素为0时,对应的led灭,1为亮,2为闪烁。(以后用多色led点阵时也可以用这种方法控制颜色)

{

unsignedchari,j;

P3=0x00;

P1=0x00;

for(i=0;i8;i++)

{

P3=0x00;

P1=~n[i];

for(j=0;j8;j++)

{

if(snake[j][i]==1)

{

P3|=n0[j];

}

elseif(snake[j][i]==2)

{

if(hz%125=60)

P3|=n0[j];

else

P3=~n0[j];

}

elseif(snake[j][i]==0)

P3=~n0[j];

}

late(10);

}

}

voidnumber(unsignedcharsu,unsignedcharx,unsignedchary,unsignedcharon,unsignedcharin)

{//在数组snake[][]从某坐标起绘数字的函数,on:显示样式,in:背景样式

xian(x+2,y,x+2,y+4,on);

if(su==7||su==4||su==1)

{

if(su==7)

xian(x,y,x+2,y,on);

if(su==4)

{

xian(x,y,x,y+2,on);

snake[y+2][x+1]=on;

}

}

else

{

xian(x,y,x+2,y,on);

if(su!=0)

xian(x,y+2,x+2,y+2,on);

xian(x,y+4,x+2,y+4,on);

xian(x,y,x,y+4,on);

switch(su)

{

case5:snake[y+3][x]=in;

case6:snake[y+1][x+2]=in;break;

case9:snake[y+3][x]=in;break;

case2:snake[y+1][x]=snake[y+3][x+2]=in;break;

case3:snake[y+1][x]=snake[y+3][x]=in;

}

}

}

voidmain(void)

{

unsignedinti,j;

TMOD=0x01;

TH0=(65536-10000)/256;

TL0=(65536-10000)%256;//每10000微秒中断一次(每0.01秒执行一次中断函数)

EA=1;

ET0=1;

TR0=1;

//以上是有关时间中断的设置

start:

P3=0x00;

P1=0x00;

f=1;

cun=1;

while(cun)//等待开始

{

n1++;

if(n1==240)

n1=0;

for(i=0;i8;i++)

for(j=0;j8;j++)

snake[j][i]=0;

switch(f)

{

case1://主界面:开

xian(0,1,4,1,1);

xian(0,3,4,3,1);

xian(1,1,1,5,1);

xian(3,1,3,6,1);

xian(6,2,6,4,2);

snake[3][7]=2;

snake[6][0]=1;

print();

P3=0x00;

P1=0x00;

if(d==0)

cun=0;

break;

case2://选择速度等级的界面

number(v,2,1,1,0);

snake[3][6]=2;

snake[3][0]=2;

if(d==0v9)

{

v++;

while(!d);

}

if(a==0v1)

{

v--;

while(!a);

}

print();

}

if(key==0)

{

while(!key);

if(f==2)

f=1;

else

f++;

}

}

f=0;

cun=0;

for(i=0;i8;i++)//snake[][]数组的初始化

for(j=0;j8;j++)

snake[j][i]=100;//100代表空

snake[0][0]=101;snake[0][1]=102;snake[0][2]=103;//大于100代表蛇身,其中最大值代表蛇头,101代表蛇尾。

for(;;)//游戏运行部分

{

for(i=0;i8;i++)

{

P3=0x00;

P1=~n[i];

for(j=0;j8;j++)

{

if(snake[j][i]100)

{

P3|=n0[j];

if(f==1eat==0)

{

snake[j][i]--;

}

}

elseif(snake[j][i]==100)

P3=~n0[j];

elseif(snake[j][i]==50)//值为50的点代表食物

{

cun++;//统计现在存在的食物数

if(hz%2510)

P3|=n0[j];

else

P3=~n0[j];

if(hz120)

hz=0;

//以上几行:闪烁显示食物

}

if(snake[j][i]max)//以下:把蛇头和蛇尾及其坐标找出来,以便后面对蛇移动的操作

{

max=snake[j][i];

xmax=j;

ymax=i;

}

if(snake[j][i]minsnake[j][i]100)

{

min=snake[j][i];

xmin=j;

ymin=i;

}

}

late(10);

n1++;

}

if(f==1)

f=0;

if(d==0)//方向按键的识别

{

if(ch!='a')

ch='d';

}

elseif(a==0)

{

if(ch!='d')

ch='a';

}

elseif(w==0)

{

if(ch!='s')

ch='w';

}

elseif(s==0)

{

if(ch!='w')

ch='s';

}

if(key==0)//暂停功能

{

while(!key);

late(200);

P1=~0x24;

while(key)

{

if(hz%12560)

P3=n0[2]+n0[3]+n0[4]+n0[5];

else

P3=0x00;

}

while(!key);

}

//下面:食物坐标的生成(用以时间为种子的随机数%8得到)

if(cunfood)//如果存在的食物数food

{

sui:

i=hz%8;

j=n1%8;

if(snake[j][i]==100)//如果该坐标点为空(没有蛇身,障碍物和食物)

snake[j][i]=50;//该坐标点生成食物

else//否则回到sui,重新生成食物坐标

gotosui;

}

cun=0;//初始化食物数为0,以便下一次循环的统计

if(num==0)

{

num=1;

f=1;

eat=0;

switch(ch)

{

case'a'://贪吃蛇左走

if(ymax1)

{

if(snake[xmax][ymax+7]100)

goto;

elseif(snake[xmax][ymax+7]==50)

{

eat++;

gotob72;

}

else

b72:snake[xmax][ymax+7]=max+1;

}

else

{

if(snake[xmax][ymax-1]100)

goto;

elseif(snake[xmax][ymax-1]==50)

{

eat++;

gotoo72;

}

else

o72:snake[xmax][ymax-1]=max+1;

}

break;

case'd'://右走

if(ymax+1=8)

{

if(snake[xmax][ymax+1-8]100)

goto;

elseif(snake[xmax][ymax+1-8]==50)

{

eat++;

gotob80;

}

else

b80:snake[xmax][ymax+1-8]=max+1;

}

else

{

if(snake[xmax][ymax+1]100)

goto;

elseif(snake[xmax][ymax+1]==50)

{

eat++;

gotoo80;

}

else

o80:snake[xmax][ymax+1]=max+1;

}

break;

case'w'://上走

if(xmax1)

{

if(snake[xmax+7][ymax]100)

goto;

elseif(snake[xmax+7][ymax]==50)

{

eat++;

gotob75;

}

else

b75:snake[xmax+7][ymax]=max+1;

}

else

{

if(snake[xmax-1][ymax]100)

goto;

elseif(snake[xmax-1][ymax]==50)

{

eat++;

gotoo75;

}

else

o75:snake[xmax-1][ymax]=max+1;

}

break;

case's'://下走

if(xmax+1=8)

{

if(snake[xmax+1-8][ymax]100)

goto;

elseif(snake[xmax+1-8][ymax]==50)

{

eat++;

gotob77;

}

else

b77:snake[xmax+1-8][ymax]=max+1;

}

else

{

if(snake[xmax+1][ymax]100)

goto;

elseif(snake[xmax+1][ymax]==50)

{

eat++;

gotoo77;

}

else

o77:snake[xmax+1][ymax]=max+1;

}

break;

}

max=0;min=200;

}

}

:

f=0;

while(key)//游戏结束,显示“X”

{

xian(0,0,7,7,1);

xian(0,7,7,0,1);

print();

}

while(!key);

for(i=0;i8;i++)

for(j=0;j8;j++)

snake[j][i]=0;

while(key)//显示游戏得分

{

number((max-103)/10,0,2,1,0);

number((max-103)%10,4,2,1,0);

print();

应该写得够详细了吧,最后,如果有什么意见或者建议欢迎直接给我留言,让我们共同学习一起进步,如果需要完整的代码或设计文件,请在下方留言或者私信我,看到后会第一时间回复。谢谢大家!如果你喜欢这个项目自己动手DIY一下吧!

文章版权声明:除非注明,否则均为虚境探索者原创文章,转载或复制请以超链接形式并注明出处。

上一个 回合制RPG游戏推荐 不容错过的经典大作

下一个 两只企鹅在游戏里秀恩爱的下场是什么?