基于单片机的贪吃蛇游戏设计仿真

1、设计内容

利用51单片机设计了一个贪吃蛇游戏,并通过keil+protues进行仿真

游戏设计规则:

①当没有改变方向时,贪吃蛇沿原来路径一直前进;

②贪吃蛇无法回头,只能异于当前方向改变行动;

③蛇头碰到蛇身时死亡,游戏结束;

④贪吃蛇吃到豆子则蛇身增加;

⑤蛇头碰到墙壁时死亡,游戏结束;

⑥当蛇长达到17及以上时出现山洞出口,进入则游戏胜利

 2、protues仿真电路

         电路很简单,由单片机最小系统+12864液晶屏+按键组成;单片机负责程序的执行和调度,液晶屏显示游戏画面,按键负责控制上下左右移动。

3、典型算法

3.1、采用循环队列存储蛇头的转向信息

        存储蛇头转向的信息使用了step记录,即每走一步使step+1,初始化蛇头step>蛇尾step,当按下按键时代表蛇头发生转向,用循环队列记录此时蛇头step坐标入队,同时使队尾指针+1,当不停前进蛇尾到达此step时,代表之前蛇头在此发生转向,则可不用具体xy坐标记录信息,从而节省存储空间。

void Key_Scan(void){  
    if (KEY0 == 0)  
        pause();  
    else if (KEY1 == 0) {  
        if (direction != 2) { //蛇不能直接掉头  
            direction = 1;  
            tailtrun_step[rear] = head_step;  
            tailtrun_direction[rear] = 1;  
            rear = (rear + 1) % 20;  
        }  
    }  
    else if (KEY2 == 0) {  
        if (direction != 1) {  
            direction = 2;  
            tailtrun_step[rear] = head_step;  
            tailtrun_direction[rear] = 2;  
            rear = (rear + 1) % 20;  
        }  
    }  
    else if (KEY3 == 0) {  
        if (direction != 4) {  
            direction = 3;  
            tailtrun_step[rear] = head_step;  
            tailtrun_direction[rear] = 3;  
            rear = (rear + 1) % 20;  
        }  
    }  
    else if (KEY4 == 0) {  
        if (direction != 3) {  
            direction = 4;  
            tailtrun_step[rear] = head_step;  
            tailtrun_direction[rear] = 4;  
            rear = (rear + 1) % 20;  
        }  
    }  
} 

3.2、根据行列具体点亮或熄灭LCD-12864某一个点

        由于LCD-12864的点阵点亮是八位DB0~DB7一次性操作一个page,代表一次只能八位一起操作,无法根据某一点的line,column点亮一个点,这里采用了位与或的思想,即根据某一点的line算出此坐标点对应的page中所在的位,后读取这点所在整列的数据与此位进行位或,即可在不改变原始数据的情况下点亮此点,熄灭相似,先对位信息进行取反,后与所在整列的数据与此位进行位与,即可熄灭某一具体点。

// 位转16进制  
int bitTo16(uint8 wei){  
    switch (wei){  
        case 0:return 0x01;break;  
        case 1:return 0x02;break;  
        case 2:return 0x04;break;  
        case 3:return 0x08;break;  
        case 4:return 0x10;break;  
        case 5:return 0x20;break;  
        case 6:return 0x40;break;  
        case 7:return 0x80;break;  
        //default:return 0x00;break;  
    }  
}  
// 点亮一个点,行列  
void show_p(uint8 screen, uint8 line, uint8 column) {  
    SelectScreen(screen);  
      
    dat = read_LCD_data(line / 8, column);  
    write_LCD_data(dat | bitTo16(line % 8));  
}  
// 熄灭一个点,行列  
void out_p(uint8 screen, uint8 line, uint8 column) {  
    SelectScreen(screen);  
      
    dat = read_LCD_data(line / 8, column);  
    write_LCD_data(dat & ~(bitTo16(line % 8)));  
}  

3.3、碰撞检测

        同样采取位与的思想,函数传入具体点的line,column坐标,读取此列的信息,后进行位与操作,若结果不为零,则代表此点已被点亮,表示发生碰撞(蛇身,墙壁)。

// 碰撞检测  
void hit_block(uint8 line, uint8 column) {  
   dat = read_LCD_data(line / 8, column);  
   if ((dat & bitTo16(line % 8)) != 0)  
       over();  
}  

4、测试结果

1.游戏开始,按下中键继续

2.进入游戏,初始得分为03(蛇身长度),按下“上下左右”按键控制方向,按下中键可以暂停游戏,吃到豆子得分+1,且蛇身长度+1。

3.当贪吃蛇撞墙或者碰撞蛇身时,游戏结束。

本文介绍了在设计的过程的关键点,供大家参考学习,如果有错误或者不明白的可以直接私信作者,或者添加微信biyezhan007。   

4.当贪吃蛇长度大于17时,山洞出现出口,进入则获得游戏胜利。

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CC呢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值