基于51单片机的贪吃蛇游戏
程序员文章站
2024-03-18 17:01:58
...
1.简介
本设计为一款贪吃蛇游戏,显示器采用8*8点阵,主控制器采用51单片机,并通过按键实现对游戏的操作。
2.贪吃蛇算法介绍
吃蛇游戏算法的实现,即如何通过液晶屏显示蛇的移动。
- 其实蛇看似移动的过程中,实质只有两个点再变,即蛇头前进方向增加一个点,蛇尾减少一个点。
- 知道如何显示蛇的移动后,再一个关键问题就是蛇的转折问题,如何控制蛇尾消失的点沿着蛇的路径。通俗的说就是蛇怎么实现曲折移动,这里就用到了循环队列,每次蛇头前进方向发生变化后,队列增加一个结点,结点中包含蛇头方向变化的位置,以及蛇头转变的方向。
- 蛇尾每次移动的过程中都会与队列头指针所储存的位置做一次判断,当蛇尾到达这一位置后,从结点中取出保存的蛇头的移动方向赋给蛇尾,结点出队列即删除这一结点。
- 由于队列是头出尾进,所以蛇头先产生的结点,蛇尾会先与其进行判断,并且删除它,即实现了蛇的曲折运动。
3.硬件设计
此设计的硬件相对简单,主要由四部分组成,分别为单片机最小系统、8x8LED矩阵模块、按键电路、系统电源。硬件框图如下,
(1)8*8LED矩阵电路
8X8点阵LED结构如下图所示:
从图中可以看出,8X8点阵共需要64个发光二极管组成,且每个发光二极管是放置在行线和列线的交叉点上,当对应的某一列置1电平,某一行置0电平,则相应的二极管就亮;要实现显示图形或字体,只需考虑其显示方式。通过编程控制各显示点对应LED阳极和阴极端的电平,就可以有效的控制各显示点的亮灭。
例如:要实现一根柱形的亮法,如图所示,对应的一列为一根竖柱,或者对应的一行为一根横柱,因此实现柱的亮的方法如下所述:
一根竖柱:对应的列置1,而行则采用扫描的方法来实现。
一根横柱:对应的行置0,而列则采用扫描的方法来实现。
此外,为了增大单片机的驱动能力,在单片机的P0脚上增加了一个74HC245缓冲器,增强对LED的驱动能力,电路如下
(2)按键电路
在此设计中设置了五个按键,分别为方向使能、上、下、左、右,方式为当方向使能按键按下后,四个方向的按键动作才有效。电路如图,
(3)硬件电路图
4.软件设计
(1) 按键操作程序
/*******************************************
判断碰撞
*******************************************/
bit knock()
{
bit k;
k=0;
if(x[1]>7||y[1]>7)
k=1; //撞墙
for(i=2;i<n;i++)
if((x[1]==x[i])&(y[1]==y[i]))
k=1; //撞自己
return k;
}
/*****************
上下左右键位处理
*****************/
void turnkey()// interrupt 0 using 2
{
if(keyenable == 0)
{
key_en ^= 1; //取反操作
}
if(key_en)
{
if(left==0){addy=0;if(addx!=1)addx=-1; else addx=1;}
if(right==0){addy=0;if(addx!=-1)addx=1; else addx=-1;}
if(up==0){addx=0;if(addy!=-1)addy=1; else addy=-1;}
if(down==0){addx=0;if(addy!=1)addy=-1; else addy=1;}
}
}
/*****************
乘方程序
*****************/
uchar mux(uchar temp)
{
if(temp==7)return 128;
if(temp==6)return 64;
if(temp==5)return 32;
if(temp==4)return 16;
if(temp==3)return 8;
if(temp==2)return 4;
if(temp==1)return 2;
if(temp==0)return 1;
return 0;
}
(2)主程序
/*****************
主程序
*****************/
void main(void)
{
e=SPEED;
P0=0x00;
P1=0xff;
P2=0x00;
P3=0x00;
while(1)
{
//if(keyenable==1){P1=0x00;P2=0xff;}else{P1=0xff;P2=0x00;}
for(i=3;i<SNAKE+1;i++)
x[i]=100;
for(i=3;i<SNAKE+1;i++)
y[i]=100;//初始化
x[0]=4;y[0]=4; //果子
n=3; //蛇长 n=-1
x[1]=1;y[1]=0; //蛇头
x[2]=0;y[2]=0; //蛇尾1
addx=0;addy=0; //位移偏移
//k=1;
while(1)
{
if(keyenable)
break;
timer0(1);
}
while(1)
{
timer0(e);
if(knock())
{
e=SPEED;
break;
} //判断碰撞
if((x[0]==x[1]+addx)&(y[0]==y[1]+addy)) //是否吃东西
{
n++;
if(n==SNAKE+1)
{
n=3;
e=e-10;
for(i=3;i<SNAKE+1;i++)
x[i]=100;
for(i=3;i<SNAKE+1;i++)
y[i]=100;
}
x[0]=x[n-2];
y[0]=y[n-2];
}
for(i=n-1;i>1;i--){x[i]=x[i-1];y[i]=y[i-1];}
//x[n-1]=x[2];y[n-1]=y[2];
x[1]=x[2]+addx;y[1]=y[2]+addy; //移动
}
}
}
源码+PCB+AD原理图 下载:关注公众号,首页回复“贪吃蛇”获取资料
下一篇: c++数字雨屏保