利用51单片机+hc595芯片配合在led点阵上玩贪吃蛇 第三篇“相关决策函数”

利用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_y
1) //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. 判断有没有吃到果子
  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_death
1)
{
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/
请大家多多点赞,你们的点赞对我很重要,是我创作的动力

猜你喜欢

转载自blog.csdn.net/linxinloningg/article/details/107237935