利用51单片机+hc595芯片配合在led点阵上玩贪吃蛇 第三篇“相关决策函数”
我们需要的决策函数有哪些:
1.改变方向的函数
改变方向示例中只采用了两个按键,因为贪吃蛇是不断朝某一方向运动的,那么相对于蛇运动的方向来看,其实只要两个可以改变的方式:要么向左,要么向右,没可能蛇头反转穿过蛇身运动的。
因此既然我只用这两个按键,那么刚好能使用外部中断,当按下按键时,进入外部中断0或外部中断1
进而根据逻辑判断,改变flag_x和flag_y的值,改变蛇的运动方向。
逻辑判断:
贪吃蛇在平面上运动,将平面分为上下左右,假设当蛇向平面方向上的左运动,那么相对于这个运动方向的左手边即是平面方向的下,右手边即是平面方向上的上
以此类推,只需要两个按键即可操作好蛇的运动方向
1.1外部中断配置;
void EX_INIT()
{
IT0=1;
EX0=1;
IT1=1;
EX1=1;
EA =1;
}中断服务函数:
void EX1_SER(void) interrupt 0
{
if(flag_y1) //up
{flag_x=-1; //left
flag_y=0;}
else if(flag_y-1) //down
{flag_x=1; //right
flag_y=0;}
else if(flag_x==-1) //left
{flag_x=0; //down
flag_y=-1;}
else if(flag_x1) //right
{flag_x=0; //up
flag_y=1;}
}
void EX2_SER(void) interrupt 2
{
if(flag_y1) //up
{flag_x=1; //right
flag_y=0;}
else if(flag_y==-1) //down
{flag_x=-1; //left
flag_y=0;}
else if(flag_x==-1) //left
{flag_x=0; //up
flag_y=1;}
else if(flag_x==1) //right
{flag_x=0; //down
flag_y=-1;}
}2.吃果子后蛇变长的函数
吃果子后蛇变长的函数需要做的事情只有三件:
- 判断有没有吃到果子
吃到果子后蛇变长
吃到果子后生成果子
1.判断有没有吃到果子:
吃到果子有两种情况:按下按键之后刚好吃到果子和蛇在自动运行过程中吃到果子。
无论哪种情况,都是判断蛇头的x,y是否和果子的berry_x,berry_y是否相等,相等即视为吃到果子;
当然,对于第一种情况,更准确的描述是按按键之后x+flag_x,y+flag_y和果子berry_x,berry_y相等。
2.吃到果子后蛇变长:
蛇变长可以看做将果子嵌入蛇头前一个位置:相关操作就是:
原本蛇的长度length,吃到果子之后length++,
此时x[length-1],y[length-1]并未有数值,还只都是0,(length未自加前length-1指向蛇头)
x[length-2],y[length-2]指向蛇头
因此将berry_x,berry_y的数值分别写入x[length-1],y[length-1]
就相当于将果子嵌入蛇头前一个位置。
3.吃到果子后生成果子:直接调用随机生成果子的函数random_berry()即可
封装吃果子后蛇变长的函数:
分析完,直接上一波代码:
void Eating_berry(void)
{
if(((x[length-1]+flag_x)==berry_x)&&((y[length-1]+flag_y)==berry_y) )
{flag_eating=1;}
else if((x[length-1]==berry_x)&&(y[length-1]==berry_y))
{flag_eating=1;}
if(flag_eating)
{
flag_eating=0;
TR0 = 0;
length++;
x[length-1]=berry_x+flag_x;
y[length-1]=berry_y+flag_y;
random_berry();
TR0=1;
}
}3.判断蛇是否咬到自己的函数
判断蛇是否咬到自己的条件与判断是否吃到果子是异曲同工之妙的。
不过要注意的是,在蛇长度大于4之前,是无法咬到自己的蛇身的,因此我们可以从长度length>4开始判断。
判断的条件是:蛇头是否与蛇身(贪吃蛇排在前3的led除外,可以假想一波,蛇头是无法咬到2,3盏灯的)的任意一盏led灯的坐标重合,如果重合,即是咬到自己了。
代码很短:
unsigned char flag_death=0;
void judgment(void)
{
unsigned char i;
if(length>4)
{
for(i=0;i<length-4;i++)
{
if(((x[length-1])==x[i])&&((y[length-1])y[i]) )
{
flag_death=1;
}
}
if(flag_death1)
{
led_g=~led_g;
}
}
}if(flag_death==1)这是死亡之后的操作,可以自行设计,设计音效或者闪灯什么的都可。
flag_death是死亡的标志,通过这个标志可以在蛇死亡之后主函数停止调用相关操作函数,游戏结束。
主函数调用:
int main()
{
EX_INIT();
snake_init();
Timer0Init();
Timer1Init();
random_berry();
while(1)
{
if(!flag_death)
{
appear();
auto_move();
Eating_berry();
judgment();
}
led=~led;
}
}其中设计的所以函数都分析完毕,虽然功能实现的十分粗糙,但各位可以根据自行需要进行更多的设计。
最后附上源码跟效果图:
源码地址:https://github.com/linxinloningg/51-chip-microcomputer-led-hc595.git
欢迎大家来我的空间踩踩,教学相长也 ~~
https://linxinloningg.space/
请大家多多点赞,你们的点赞对我很重要,是我创作的动力