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


    个人主页:咸鱼弟

    激励话语:在你想要放弃的那一刻, 想想为什么当初走到了这里。

    系列专栏:单片机设计

    1、设计内容

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

    游戏设计规则:

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

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

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

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

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

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

     2、protues仿真电路

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

    3、典型算法

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

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

    1. void Key_Scan(void){
    2. if (KEY0 == 0)
    3. pause();
    4. else if (KEY1 == 0) {
    5. if (direction != 2) { //蛇不能直接掉头
    6. direction = 1;
    7. tailtrun_step[rear] = head_step;
    8. tailtrun_direction[rear] = 1;
    9. rear = (rear + 1) % 20;
    10. }
    11. }
    12. else if (KEY2 == 0) {
    13. if (direction != 1) {
    14. direction = 2;
    15. tailtrun_step[rear] = head_step;
    16. tailtrun_direction[rear] = 2;
    17. rear = (rear + 1) % 20;
    18. }
    19. }
    20. else if (KEY3 == 0) {
    21. if (direction != 4) {
    22. direction = 3;
    23. tailtrun_step[rear] = head_step;
    24. tailtrun_direction[rear] = 3;
    25. rear = (rear + 1) % 20;
    26. }
    27. }
    28. else if (KEY4 == 0) {
    29. if (direction != 3) {
    30. direction = 4;
    31. tailtrun_step[rear] = head_step;
    32. tailtrun_direction[rear] = 4;
    33. rear = (rear + 1) % 20;
    34. }
    35. }
    36. }

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

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

    1. // 位转16进制
    2. int bitTo16(uint8 wei){
    3. switch (wei){
    4. case 0:return 0x01;break;
    5. case 1:return 0x02;break;
    6. case 2:return 0x04;break;
    7. case 3:return 0x08;break;
    8. case 4:return 0x10;break;
    9. case 5:return 0x20;break;
    10. case 6:return 0x40;break;
    11. case 7:return 0x80;break;
    12. //default:return 0x00;break;
    13. }
    14. }
    15. // 点亮一个点,行列
    16. void show_p(uint8 screen, uint8 line, uint8 column) {
    17. SelectScreen(screen);
    18. dat = read_LCD_data(line / 8, column);
    19. write_LCD_data(dat | bitTo16(line % 8));
    20. }
    21. // 熄灭一个点,行列
    22. void out_p(uint8 screen, uint8 line, uint8 column) {
    23. SelectScreen(screen);
    24. dat = read_LCD_data(line / 8, column);
    25. write_LCD_data(dat & ~(bitTo16(line % 8)));
    26. }

    3.3、碰撞检测

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

    1. // 碰撞检测
    2. void hit_block(uint8 line, uint8 column) {
    3. dat = read_LCD_data(line / 8, column);
    4. if ((dat & bitTo16(line % 8)) != 0)
    5. over();
    6. }

    4、测试结果

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

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

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

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

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

            本文介绍了在设计的过程的关键点,供大家参考学习,如需获取实物、或者下载链接失效、对其他单片机硬件设计感兴趣、有不明白的或者错误的,可以添加徽信biyezhan007 

    郑重声明,此文章提供给大家做参考模板,杜绝一切不良学术不良行为。

     

  • 相关阅读:
    JAVA计算机毕业设计社区志愿者服务管理系统源码+系统+mysql数据库+lw文档
    睿趣科技:抖音开网店新手卖什么好
    还在为 Dubbo 服务写 Controller?因为未使用 ShenYu 网关
    全景环视开启「第二曲线」
    使用VS Code 搭建 platformio 平台
    JavaEE进阶 - Spring Boot 日志文件 - 细节狂魔
    LeetCode —— dfs和bfs
    重点用能单位能耗系统在湖南三立集团的应用
    Linux进程间通信——共享内存
    算法(一)
  • 原文地址:https://blog.csdn.net/u013253075/article/details/126452257