找回密码
 立即注册
查看: 220|回复: 11

PWM硬件移相测试卡教程(二)贪吃蛇@STC8H2K12U系列

[复制链接]
  • TA的每日心情
    开心
    6 天前
  • 签到天数: 90 天

    [LV.6]常住居民II

    38

    主题

    986

    回帖

    6775

    积分

    荣誉版主

    冲哥视频教程和各种开源资料QQ交流群884047237,可群

    积分
    6775
    QQ
    发表于 2024-4-7 22:29:54 | 显示全部楼层 |阅读模式
    话不多说,先上测试视频:



    这一章节用的硬件是PWM移相测试卡+OLED12864 ( SSD1306_IIC)
    截图202404071937393649.jpg

    序言、
        最近刷抖音看到了个贪吃蛇,这不一下就激起了童年的回忆,准备小试牛刀做个贪吃蛇耍耍。既然也做出来了个初版,那就给广大网友一起耍耍了,想自己借鉴或者升级的也可以仔细看下文章,想玩的直接群文件下载代码即可。这个帖子的代码用的最最好理解的方法写的,适合新手练习,老鸟略过哈哈。
    截图202404071940526265.jpg

    一、知识储备
    1.去下面这个帖子学习IIC的知识:https://www.stcaimcu.com/forum.php?mod=viewthread&tid=236
    2.去下面这个帖子学习OLED显示汉字的知识:https://www.stcaimcu.com/forum.php?mod=viewthread&tid=30
    3.去下面的帖子学习单片机驱动G驱动OLED12864,I2C方式:https://www.stcaimcu.com/forum.php?mod=viewthread&tid=2592
    4.去下面的帖子学习菜单:https://www.stcaimcu.com/forum.php?mod=viewthread&tid=44

    二、效果分析
    按键,oled初始化什么的比较简单就略过了,有需要的可以去看上面的帖子。这里主要讲绘图和蛇的动作。
    1.界面功能切换的结构体
    typedef struct Menu
    {
        uint8_t Sub;
        //进入下一级
        uint8_t Enter;
        //返回上一级
        uint8_t Back;
        // 对应的函数指针
        void (*Current_Operation)(void);
    } Menu_Table;
    程序里基于这个结构体定义了一个结构体数组,

    Menu_Table Table[3]= {   /* 菜单及界面 */
        /*SUB E  B  F */
        {2, 1, 0, Menu},
        {0, 1, 0, Game},
        {0, 0, 0, GameMode}
    };
    这个结构体数组讲用到的三个界面都做进去了,分别是主菜单界面(Menu),游戏界面(Game),游戏模式设置界面(GameMode)。

    2.界面和功能切换的函数指针
    在代码里定义了一个 void (*Operation)(void); 的函数指针,Operation指向要执行的函数。Operation=Table[Cur].Current_Operation指向当前界面的函数,然后再主循环里不断的循环执行这个函数。这部分不懂得可以去参考上面的菜单的帖子。

    3.主菜单界面(Menu)介绍
    (1)如果切换过界面,先清除当前界面的显示
    (2)初始化所有的运行变量
    (3)显示汉字
    (4)判断当前的模式并在指定位置显示 *
    具体的实现代码如下:
    1. void Menu(void)
    2. {
    3.     if(modeFlag)
    4.     {
    5.         OLED_Clear();
    6.     }
    7.     /* 不在游戏中 */
    8.     playing = 0;
    9.     modeFlag = 0;
    10.     replay = 1;
    11.     Get_Command();
    12.     /* 关闭定时器 */
    13.     TR0 = 0;
    14.     /* 显示贪吃蛇 */
    15.     OLED_ShowCHinese(44,0,0);
    16.     OLED_ShowCHinese(60,0,1);
    17.     OLED_ShowCHinese(76,0,2);
    18.     /* 开始游戏 */
    19.     OLED_ShowCHinese(34,3,3);
    20.     OLED_ShowCHinese(50,3,4);
    21.     OLED_ShowCHinese(66,3,5);
    22.     OLED_ShowCHinese(82,3,6);
    23.     /* 难度选择 */
    24.     OLED_ShowCHinese(34,5,7);
    25.     OLED_ShowCHinese(50,5,8);
    26.     OLED_ShowCHinese(66,5,9);
    27.     OLED_ShowCHinese(82,5,10);
    28.     /* 菜单选择 */
    29.     switch(menuSelect)
    30.     {
    31.     case MAINMENU:
    32.         OLED_ShowChar(14,3,'*',16);
    33.         OLED_ShowChar(14,5,' ',16);
    34.         break;
    35.     case GAMEMODE:
    36.         OLED_ShowChar(14,5,'*',16);
    37.         OLED_ShowChar(14,3,' ',16);
    38.         break;
    39.     }
    40. }
    复制代码
    显示效果图如下图所示:
    截图202404072135272594.jpg

    4.游戏模式设置界面(GameMode)
    (1)如果切换过界面,先清除当前界面的显示
    (2)初始化所有的运行变量
    (3)显示汉字
    (4)判断当前的模式并在指定位置显示 * ,表示当前选中

    具体的实现代码如下:
    1. void GameMode(void)
    2. {
    3.     if(!modeFlag)
    4.     {
    5.         OLED_Clear();
    6.     }
    7.     Get_Command();
    8.     playing = 0;
    9.     modeFlag = 1;
    10.     OLED_ShowCHinese(34,1,15);
    11.     OLED_ShowCHinese(50,1,16);
    12.     OLED_ShowCHinese(34,4,17);
    13.     OLED_ShowCHinese(50,4,18);
    14.     switch(CuMode)
    15.     {
    16.     case 0:
    17.         OLED_ShowChar(14,1,'*',16);
    18.         OLED_ShowChar(14,4,' ',16);
    19.         break;
    20.     case 1:
    21.         OLED_ShowChar(14,1,' ',16);
    22.         OLED_ShowChar(14,4,'*',16);
    23.         break;
    24.     }
    25. }
    复制代码
    显示效果图如下图所示:
    截图202404072136251055.jpg

    5.游戏界面(Game)
    (1)是否重新开界面,先清除当前界面的显示和之前的游戏记录
    (2)定时时间到了蛇移动,如果移动后吃到了食物在重新生成,画新的蛇
    (3)如果游戏结束了展示成绩
    具体的实现代码如下:
    1. void Game(void)
    2. {
    3.     /* 重开游戏 */
    4.     if(replay)
    5.     {
    6.         /* 贪吃蛇初始化 */
    7.         clearSnake();
    8.         GUI_Init();
    9.         replay = 0;
    10.     }
    11.     /* 正在游戏中 */
    12.     playing = 1;
    13.     /* 开启定时器 */
    14.     TR0 = 1;
    15.     if(timerFlag)
    16.     {
    17.         Move();
    18.         Eat_Food();
    19.         drawSnake();
    20.         timerFlag = 0;
    21.     }
    22.     //定时器0开始计时
    23.     Get_Command();
    24.     GUI_Refresh(map);
    25.     if(GameOver())
    26.     {
    27.         OLED_Clear();
    28.         /* 展示成绩 */
    29.         Show_Score();
    30.         Delay2000ms();
    31.         OLED_Clear();
    32.         Cur = Table[Cur].Back;
    33.     }
    34. }
    复制代码
    显示效果图如下图所示:
    截图202404072210238020.jpg

    截图202404072213116116.jpg

    三、蛇体部分分析
    1.如何实现游戏界面的显示:
    本项目使用的OLED屏是0.96寸的,像素为128*64。贪吃蛇少不了蛇,如果采用一个像素点来画蛇的身体,那这个蛇小到离谱,不够明显。
    所以本项目使用的4*4像素的正方形(只点亮外框像素)来绘制蛇的身体。实现的思路大致如下:
    使用map [32][16]放大四倍变为128*64。
    截图202404072222269218.jpg
    map [32][16] : 对应的是上图中的左边。用于存储数据,然后调用GUI_Refresh判断相应的值,做出对应的操作,然后放大四倍成为上图中的右边,最后再调用OLED里面的相关代码,就会把数据写入OLED_GRAM[128][8]。
    例如:
    1. void Paint_Body(uint8_t x,uint8_t y )//绘制身体
    2. {
    3.     uint8_t i,j;
    4.     for(i=4*y; i<4*y+4; i++)
    5.     {
    6.         for(j=4*x; j<4*x+4; j++)
    7.         {
    8.             if(i==4*y||i==4*y+3)
    9.             {
    10.                 OLED_DrawPoint(j,i);
    11.             }
    12.             if(j==4*x||j==4*x+3)
    13.             {
    14.                 OLED_DrawPoint(j,i);
    15.             }
    16.         }
    17.     }
    18. }
    19. void Paint
    复制代码
    这里OLED_GRAM[128][8]:作为OLED的显存数组,通过这个数据就可以让OLED上对应的像素亮起来。• snake_Grid[32][2]: 用来存储蛇的坐标,后面会有讲解。其他的代码也可以这样实现,比如画外框,食物等。之后就只需要操作map数组,就可以完成我们的贪吃蛇啦。

    2.游戏规则设计
    上面有提到snake_Grid[32][2]是用于存储蛇的坐标的,同时snake_Grid[0][0]和snake_Grid[0][1]是来存储蛇头的坐标,我们只需要判断蛇的其他坐标是不是等于蛇头的坐标,相等说明吃到自己了,结束游戏;另一个规则是撞到墙游戏结束,只需要判断蛇头的坐标是不是等于0xfe(0xfe对应的是边框值)。
    1. // 撞到墙结束游戏
    2.         if(map[snake_Grid[0][0]][snake_Grid[0][1]] == 0xfe && GameDifficulty==1)
    3.         {
    4.                 // crashWall
    5.                 crashWall = 1;
    6.         }
    复制代码
    1. bit GameOver(void)
    2. {
    3.     //蛇头坐标
    4.     uint8_t sx=snake_Grid[0][0],sy=snake_Grid[0][1],i;
    5.     //判断有没有吃到自己
    6.     for(i=1; i<length; i++)
    7.     {
    8.         if(snake_Grid[i][0]==sx && snake_Grid[i][1]==sy)
    9.             return 1;
    10.     }
    11.         //如果撞到墙
    12.         if(crashWall==1 && GameDifficulty==1)
    13.         {
    14.                 crashWall = 0;
    15.                 return 1;
    16.         }
    17.     return 0;
    18. }
    复制代码

    具体的代码都在上面讲解了,有需要源码的小伙伴可以在群文件下载,有任何问题可以在下面留言!

    回复 送花

    使用道具 举报

  • TA的每日心情
    开心
    6 天前
  • 签到天数: 90 天

    [LV.6]常住居民II

    38

    主题

    986

    回帖

    6775

    积分

    荣誉版主

    冲哥视频教程和各种开源资料QQ交流群884047237,可群

    积分
    6775
    QQ
     楼主| 发表于 2024-4-7 22:37:06 | 显示全部楼层
    有奖征集,谁能第一个把这个代码里的显示屏的显示改为字库索引的方式的话
    (附上修改好的代码,并展示用STC-ISP软件实现汉字取模的过程方为有效),
    免费送一套这个文中的硬件!注意:只有在本文下方第一个发布的才有效!!
    截图202404072235005166.jpg


    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    慵懒
    11 小时前
  • 签到天数: 162 天

    [LV.7]常住居民III

    12

    主题

    341

    回帖

    1088

    积分

    金牌会员

    积分
    1088
    发表于 2024-4-8 08:26:01 | 显示全部楼层
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    18 小时前
  • 签到天数: 80 天

    [LV.6]常住居民II

    4

    主题

    44

    回帖

    533

    积分

    高级会员

    积分
    533
    发表于 2024-4-9 18:45:39 | 显示全部楼层
    本帖最后由 四汐 于 2024-4-9 18:48 编辑

    修改前:
    1. //显示汉字
    2. void OLED_ShowCHinese(u8 x,u8 y,u8 no)
    3. {
    4.     u8 t,adder=0;
    5.     OLED_Set_Pos(x,y);
    6.     for(t=0; t<16; t++)
    7.     {
    8.         OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
    9.         adder+=1;
    10.     }
    11.     OLED_Set_Pos(x,y+1);
    12.     for(t=0; t<16; t++)
    13.     {
    14.         OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
    15.         adder+=1;
    16.     }
    17. }
    复制代码


    修改后:
    截图202404091847229349.jpg

    取模设置:
    截图202404091839505801.jpg


    字库:
    截图202404091841313604.jpg 截图202404091842103248.jpg


    点评

    附上改完之后的代码压缩包即可领取哈  详情 回复 发表于 2024-4-9 21:27
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    6 天前
  • 签到天数: 90 天

    [LV.6]常住居民II

    38

    主题

    986

    回帖

    6775

    积分

    荣誉版主

    冲哥视频教程和各种开源资料QQ交流群884047237,可群

    积分
    6775
    QQ
     楼主| 发表于 2024-4-9 21:27:26 | 显示全部楼层

    附上改完之后的代码压缩包即可领取哈
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    10 小时前
  • 签到天数: 61 天

    [LV.6]常住居民II

    3

    主题

    556

    回帖

    760

    积分

    高级会员

    积分
    760
    发表于 2024-4-9 21:51:33 | 显示全部楼层
    没入群就没源码下了?
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    18 小时前
  • 签到天数: 80 天

    [LV.6]常住居民II

    4

    主题

    44

    回帖

    533

    积分

    高级会员

    积分
    533
    发表于 2024-4-11 01:13:56 | 显示全部楼层
    电子DIY小家 发表于 2024-4-9 21:27
    附上改完之后的代码压缩包即可领取哈

    2.贪吃蛇.zip (343.49 KB, 下载次数: 10)

    点评

    q群里私聊下群主领取奖励  详情 回复 发表于 2024-4-11 08:06
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    6 天前
  • 签到天数: 90 天

    [LV.6]常住居民II

    38

    主题

    986

    回帖

    6775

    积分

    荣誉版主

    冲哥视频教程和各种开源资料QQ交流群884047237,可群

    积分
    6775
    QQ
     楼主| 发表于 2024-4-11 08:06:42 | 显示全部楼层

    q群里私聊下群主领取奖励
    回复 支持 2 反对 0 送花

    使用道具 举报

    该用户从未签到

    550

    主题

    9323

    回帖

    1万

    积分

    管理员

    积分
    13908
    发表于 2024-4-11 08:19:33 | 显示全部楼层
    还是放个附件,完整程序,供大家方便下载,
    体现我们纯技术论坛的博大精深

    点评

    上面有群友放了升级版的代码  详情 回复 发表于 2024-4-11 15:56
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    6 天前
  • 签到天数: 90 天

    [LV.6]常住居民II

    38

    主题

    986

    回帖

    6775

    积分

    荣誉版主

    冲哥视频教程和各种开源资料QQ交流群884047237,可群

    积分
    6775
    QQ
     楼主| 发表于 2024-4-11 15:56:40 | 显示全部楼层
    神农鼎 发表于 2024-4-11 08:19
    还是放个附件,完整程序,供大家方便下载,
    体现我们纯技术论坛的博大精深
    ...

    上面有群友放了升级版的代码
    回复 支持 反对 送花

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-5-5 20:00 , Processed in 0.437099 second(s), 71 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表