请选择 进入手机版 | 继续访问电脑版
查看: 1000|回复: 5

[原创] STM32F446+OLED12864跑贪吃蛇游戏

[复制链接]

该用户从未签到

10

主题

40

帖子

20

蝴蝶豆

高级会员

最后登录
2018-9-3
发表于 2018-2-7 14:16:56 | 显示全部楼层 |阅读模式
闲暇之余发现看了下OLED12864的数据手册,发现他的显示在Y轴上只有页写,也就是一次写8个点。

突然想到,如果自己程序需要精准定位到某个点,那这不是会很艹蛋么?去网上搜索,基本上都是页写的代码,也就是在Y轴上的定位只能是0~7.

于是花了点时间,做了个贪吃蛇的游戏,写了段程序。

程序硬件支持:
STM32F446R+OLED12864+按键

软件结构:
1.DMA跑SPI刷屏
2.贪吃蛇游戏算法
3.重新定义OLED显示方式

底层驱动就不说,DMA配置,跑SPI数据。

我先做了个二位数组,存放64*128个点,初始值为0;
uint8_t OLED_Display_Data[8][128]

之后开个定时器,每隔一段时间跑一次屏幕
                if(HardwareParamter.TimingOLED>=Refresh_Time && !HardwareParamter.OLEDFlash_flag)
                {
                        HardwareParamter.TimingOLED = 0;
                        Display_Process(OLED_Display_Data);       
                }


基本想法就是,不停的跑这个数组,数组就是屏幕的每个点。

贪吃蛇算法做的简单:
首先是一个结构体,存放相关参数

typedef struct {
        uint8_t food_x;      //食物横坐标
        uint8_t food_y;      //食物纵坐标

        uint8_t gameEsc;     //游戏开始暂停
        uint8_t gameSpeed;   //游戏速度
        uint8_t gameLevel;   //游戏难度
       
        uint8_t x[39];
        uint8_t y[39];
        uint8_t node;        //蛇的节数
        uint8_t direction;   //蛇头方向
}GameParamter_t;


两个核心函数:移动和创建食物
食物依赖于随机数生成函数
//    需要出现新食物
uint8_t createNewFood(void)
{
        uint8_t i;
        uint8_t size = GameParamter.node;
        uint8_t flag = TRUE;                         //    标记创建的新事物与贪吃蛇的身体冲突
        srand(HardwareParamter.TimingVal);
        GameParamter.food_x = rand() % MAP_H;
        GameParamter.food_y = rand() % MAP_L;
       
        //    食物的坐标必须为3的倍数才会在显示屏先被显示
        for (; GameParamter.food_x % DOT_H != 0; ++GameParamter.food_x) {      
                        ;
        }
       
        for (; GameParamter.food_y % DOT_L != 0; ++GameParamter.food_y) {      
                        ;
        }
       
        for (i = 0; i < size; ++i) {
                        if (GameParamter.food_x == GameParamter.x[i] && GameParamter.food_y == GameParamter.y[i]) {
                                        flag = FALSE;
                                        break;
                        }
        }   

        return flag;
}


移动就是简单的数据加减
//    贪吃蛇移动
void move(void)
{
        uint8_t i;

        if(GameParamter.gameEsc)
        {
                //    将蛇从最后个节点向前一个节点移动
                for(i = GameParamter.node - 1; i > 0; i--) {                    
                                GameParamter.x[i] = GameParamter.x[i - 1];
                                GameParamter.y[i] = GameParamter.y[i - 1];
                }
               
                //    根据此时贪吃蛇的方向,设置蛇头的位置            
                switch(GameParamter.direction)   
                {                  
                        case RIGHT:
                                        GameParamter.x[0] += DOT_H;
                                        break;
                        case LEFT:
                                        GameParamter.x[0] -= DOT_H;
                                        break;
                        case UP:
                                        GameParamter.y[0] -= DOT_L;
                                        break;
                        case DOWN:
                                        GameParamter.y[0] += DOT_L;
                                        break;
                }
        }
}

显示部分随时更新
uint8_t temp;
       
        switch(State_Flag)
        {
                case Snake_Move:
                        //清除蛇尾部
                        for(temp = 0;temp < GameParamter.node;temp++)
                                Oled_Dot(GameParamter.x[temp],GameParamter.y[temp],0);
                       
                        //移动蛇
                        move();
                       
                        //显示蛇的位置
                        for(temp = 0;temp < GameParamter.node;temp++)
                                Oled_Dot(GameParamter.x[temp],GameParamter.y[temp],1);
                       
                        //吃到食物,创建新的食物
                        if(GameParamter.food_x == GameParamter.x[0] && GameParamter.food_y == GameParamter.y[0])
                                Oled_food();
                       
                        if(GameParamter.x[0] >= MAP_H || GameParamter.y[0] >= MAP_L)
            {
                                OLEDClear();
                                OLED_ShowString(((128 - ((strlen("GAME")*10)))>>1),2,"GAME");
                                OLED_ShowString(((128 - ((strlen("OVER")*10)))>>1),5,"OVER");
                                State_Flag = Game_Over;
                                HardwareParamter.OLEDFlash_flag = 1;
                        }
                break;
                case Game_Over:

                break;
                default:
                        OLEDClear();
                        State_Flag = Snake_Move;
                  HardwareParamter.OLEDFlash_flag = 0;
                break;
        }


外带一个按键处理,解决方向和暂停重置问题。

1.png
N$TC_KA52ICSCU3@IQJ~OBQ.png
  2018年STM32线下培训时间表>>                    
回复

使用道具 举报

该用户从未签到

3

主题

819

帖子

258

蝴蝶豆

版主

最后登录
2018-9-25
发表于 2018-2-7 15:17:28 | 显示全部楼层
说起贪吃蛇,以前在大学的时候,学完数据结构,然后就在dos下面写了一个极其简陋的!!!
回复 支持 反对

使用道具 举报

该用户从未签到

0

主题

169

帖子

7

蝴蝶豆

金牌会员

最后登录
2018-9-25
发表于 2018-2-7 22:21:36 | 显示全部楼层
可以试试
  2018年STM32线下培训时间表>>                    
回复

使用道具 举报

该用户从未签到

1

主题

361

帖子

63

蝴蝶豆

金牌会员

最后登录
2018-9-25
发表于 2018-2-8 08:14:23 | 显示全部楼层
有点意思。楼主有时间放个视频上来看看。
回复 支持 反对

使用道具 举报

  • TA的每日心情
    开心
    2018-2-6 09:20
  • 签到天数: 1 天

    [LV.1]初来乍到

    1142

    主题

    4817

    帖子

    1

    蝴蝶豆

    管理员

    最后登录
    2018-9-25
    发表于 2018-2-12 14:17:18 | 显示全部楼层
    感谢分享,已汇总到2月技术原创  http://www.stmcu.org.cn/module/forum/thread-614799-1-1.html
      2018年STM32线下培训时间表>>                    
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    11

    帖子

    0

    蝴蝶豆

    中级会员

    最后登录
    2018-9-24
    发表于 2018-8-21 16:22:06 | 显示全部楼层
    程序下载链接木有?
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|意法半导体STM32/STM8技术社区

    GMT+8, 2018-9-25 19:19 , Processed in 0.088163 second(s), 12 queries , MemCache On.

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

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