电子DIY小家 发表于 2024-4-7 22:29:54

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

话不多说,先上测试视频:
118


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


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


一、知识储备
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= {   /* 菜单及界面 */
    /*SUB EBF */
    {2, 1, 0, Menu},
    {0, 1, 0, Game},
    {0, 0, 0, GameMode}
};
这个结构体数组讲用到的三个界面都做进去了,分别是主菜单界面(Menu),游戏界面(Game),游戏模式设置界面(GameMode)。

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

3.主菜单界面(Menu)介绍
(1)如果切换过界面,先清除当前界面的显示
(2)初始化所有的运行变量
(3)显示汉字
(4)判断当前的模式并在指定位置显示 *
具体的实现代码如下:
void Menu(void)
{
    if(modeFlag)
    {
      OLED_Clear();
    }
    /* 不在游戏中 */
    playing = 0;
    modeFlag = 0;
    replay = 1;
    Get_Command();
    /* 关闭定时器 */
    TR0 = 0;
    /* 显示贪吃蛇 */
    OLED_ShowCHinese(44,0,0);
    OLED_ShowCHinese(60,0,1);
    OLED_ShowCHinese(76,0,2);
    /* 开始游戏 */
    OLED_ShowCHinese(34,3,3);
    OLED_ShowCHinese(50,3,4);
    OLED_ShowCHinese(66,3,5);
    OLED_ShowCHinese(82,3,6);
    /* 难度选择 */
    OLED_ShowCHinese(34,5,7);
    OLED_ShowCHinese(50,5,8);
    OLED_ShowCHinese(66,5,9);
    OLED_ShowCHinese(82,5,10);

    /* 菜单选择 */
    switch(menuSelect)
    {
    case MAINMENU:
      OLED_ShowChar(14,3,'*',16);
      OLED_ShowChar(14,5,' ',16);
      break;
    case GAMEMODE:
      OLED_ShowChar(14,5,'*',16);
      OLED_ShowChar(14,3,' ',16);
      break;
    }


}
显示效果图如下图所示:


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

具体的实现代码如下:
void GameMode(void)
{
    if(!modeFlag)
    {
      OLED_Clear();
    }
    Get_Command();
    playing = 0;
    modeFlag = 1;
    OLED_ShowCHinese(34,1,15);
    OLED_ShowCHinese(50,1,16);
    OLED_ShowCHinese(34,4,17);
    OLED_ShowCHinese(50,4,18);

    switch(CuMode)
    {
    case 0:
      OLED_ShowChar(14,1,'*',16);
      OLED_ShowChar(14,4,' ',16);
      break;
    case 1:
      OLED_ShowChar(14,1,' ',16);
      OLED_ShowChar(14,4,'*',16);
      break;
    }
}显示效果图如下图所示:


5.游戏界面(Game)
(1)是否重新开界面,先清除当前界面的显示和之前的游戏记录
(2)定时时间到了蛇移动,如果移动后吃到了食物在重新生成,画新的蛇
(3)如果游戏结束了展示成绩
具体的实现代码如下:
void Game(void)
{

    /* 重开游戏 */
    if(replay)
    {
      /* 贪吃蛇初始化 */
      clearSnake();
      GUI_Init();
      replay = 0;
    }
    /* 正在游戏中 */
    playing = 1;
    /* 开启定时器 */
    TR0 = 1;
    if(timerFlag)
    {
      Move();
      Eat_Food();
      drawSnake();
      timerFlag = 0;
    }
    //定时器0开始计时
    Get_Command();
    GUI_Refresh(map);
    if(GameOver())
    {
      OLED_Clear();
      /* 展示成绩 */
      Show_Score();
      Delay2000ms();
      OLED_Clear();
      Cur = Table.Back;

    }
}显示效果图如下图所示:




三、蛇体部分分析
1.如何实现游戏界面的显示:本项目使用的OLED屏是0.96寸的,像素为128*64。贪吃蛇少不了蛇,如果采用一个像素点来画蛇的身体,那这个蛇小到离谱,不够明显。所以本项目使用的4*4像素的正方形(只点亮外框像素)来绘制蛇的身体。实现的思路大致如下:使用map 放大四倍变为128*64。
map : 对应的是上图中的左边。用于存储数据,然后调用GUI_Refresh判断相应的值,做出对应的操作,然后放大四倍成为上图中的右边,最后再调用OLED里面的相关代码,就会把数据写入OLED_GRAM。例如:void Paint_Body(uint8_t x,uint8_t y )//绘制身体
{
    uint8_t i,j;
    for(i=4*y; i<4*y+4; i++)
    {
      for(j=4*x; j<4*x+4; j++)
      {
            if(i==4*y||i==4*y+3)
            {

                OLED_DrawPoint(j,i);

            }
            if(j==4*x||j==4*x+3)
            {

                OLED_DrawPoint(j,i);

            }
      }
    }
}
void Paint这里OLED_GRAM:作为OLED的显存数组,通过这个数据就可以让OLED上对应的像素亮起来。• snake_Grid: 用来存储蛇的坐标,后面会有讲解。其他的代码也可以这样实现,比如画外框,食物等。之后就只需要操作map数组,就可以完成我们的贪吃蛇啦。
2.游戏规则设计上面有提到snake_Grid是用于存储蛇的坐标的,同时snake_Grid和snake_Grid是来存储蛇头的坐标,我们只需要判断蛇的其他坐标是不是等于蛇头的坐标,相等说明吃到自己了,结束游戏;另一个规则是撞到墙游戏结束,只需要判断蛇头的坐标是不是等于0xfe(0xfe对应的是边框值)。 // 撞到墙结束游戏
      if(map]] == 0xfe && GameDifficulty==1)
      {
                // crashWall
                crashWall = 1;
      }bit GameOver(void)
{
    //蛇头坐标
    uint8_t sx=snake_Grid,sy=snake_Grid,i;
    //判断有没有吃到自己
    for(i=1; i<length; i++)
    {
      if(snake_Grid==sx && snake_Grid==sy)
            return 1;
    }
      //如果撞到墙
      if(crashWall==1 && GameDifficulty==1)
      {
                crashWall = 0;
                return 1;
      }
    return 0;
}
具体的代码都在上面讲解了,有需要源码的小伙伴可以在群文件下载,有任何问题可以在下面留言!

电子DIY小家 发表于 2024-4-7 22:37:06

有奖征集,谁能第一个把这个代码里的显示屏的显示改为字库索引的方式的话
(附上修改好的代码,并展示用STC-ISP软件实现汉字取模的过程方为有效),
免费送一套这个文中的硬件!注意:只有在本文下方第一个发布的才有效!!



wangxiangtan 发表于 2024-4-8 08:26:01

收藏 再看,不会搞字模{:4_184:}

PWM硬件移相测试卡教程(四)组合PWM(180度移相互补输出)@STC8H2K12U系列
PWM硬件移相测试卡教程(四)组合PWM(180度移相互补输出)@STC8H2K12U系列 - 工控板,PLC,STC8/STC32实现 - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)

PWM硬件移相测试卡教程(三)不对称PWM(高速正交编码信号输出)@STC
PWM硬件移相测试卡教程(三)不对称PWM(高速正交编码信号输出)@STC - 工控板,PLC,STC8/STC32实现 - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)

PWM硬件移相测试卡教程(二)贪吃蛇@STC8H2K12U系列
PWM硬件移相测试卡教程(二)贪吃蛇@STC8H2K12U系列 - 工控板,PLC,STC8/STC32实现 - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)

PWM硬件移相测试卡教程(一)按键点灯测试@STC8H2K12U系列
PWM硬件移相测试卡教程(一)按键点灯测试@STC8H2K12U系列 - 工控板,PLC,STC8/STC32实现 - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)

四汐 发表于 2024-4-9 18:45:39

本帖最后由 四汐 于 2024-4-9 18:48 编辑

修改前:
//显示汉字
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
{
    u8 t,adder=0;
    OLED_Set_Pos(x,y);
    for(t=0; t<16; t++)
    {
      OLED_WR_Byte(Hzk,OLED_DATA);
      adder+=1;
    }
    OLED_Set_Pos(x,y+1);
    for(t=0; t<16; t++)
    {
      OLED_WR_Byte(Hzk,OLED_DATA);
      adder+=1;
    }
}

修改后:


取模设置:



字库:



电子DIY小家 发表于 2024-4-9 21:27:26

四汐 发表于 2024-4-9 18:45
修改前:




附上改完之后的代码压缩包即可领取哈{:lol:}

soma 发表于 2024-4-9 21:51:33

没入群就没源码下了?

四汐 发表于 2024-4-11 01:13:56

电子DIY小家 发表于 2024-4-9 21:27
附上改完之后的代码压缩包即可领取哈


电子DIY小家 发表于 2024-4-11 08:06:42

四汐 发表于 2024-4-11 01:13


{:5_272:}q群里私聊下群主领取奖励

神农鼎 发表于 2024-4-11 08:19:33

还是放个附件,完整程序,供大家方便下载,
体现我们纯技术论坛的博大精深

电子DIY小家 发表于 2024-4-11 15:56:40

神农鼎 发表于 2024-4-11 08:19
还是放个附件,完整程序,供大家方便下载,
体现我们纯技术论坛的博大精深
...

上面有群友放了升级版的代码{:5_332:}
页: [1] 2
查看完整版本: PWM硬件移相测试卡教程(二)贪吃蛇@STC8H2K12U系列