在mini板上也做Flappybird游戏

2019-07-20 23:42发布

本帖最后由 posystorage 于 2017-1-25 16:54 编辑

新人第一次发帖,有点小紧张
首先感谢原作者:http://www.openedv.com/thread-27336-1-1.html
看到原作者microbai搞的Flappybird感觉蛮好玩的
我因为没有战舰板,所以就寻思着一致到mini上来跑。
这是效果










我移植主要是重写了绘图的方法,增加了一些资源。原作者的之前取模的好多图素,基本都保留了。
战舰板因为有外置的sram,所以原作者在外置sram上面建立了好多缓冲,使用的策略是帧缓存再加上每个移动物体其后面的背景的备份
u16 FlappyBird_Frame[320][240] __attribute__((at(0X68000000))); //153600
u16 FlappyBird_Bird_Buff[18][26] __attribute__((at(0X68026000)));//936
u16 FlappyBird_column_Buff[3][259][39] __attribute__((at(0X68028000))) ;//59904
u16 FlappyBird_column_Buff_BG[3][259][39] __attribute__((at(0X68037000)));//59904
这里掐指一算用了136k的ram,足够吧mini板上的RCT6内存爆两遍还有余了。
所以说首先肯定是不能要帧缓存的了,数据只能直接刷到屏里面。
64脚的芯片木有fsmc,只能io模拟。用原子哥的LCD.c里面的函数,就算是快速画点,也是太慢了。所以大概用了下面几个策略来解决。
1、需要移动和反复刷新的图素(鸟,柱子,下方移动的绿 {MOD}进度条)都给建立了缓存。
因为鸟有两种姿态,一种平飞,另一种是坠落的鸟。实际上就是相互之间的转置,为了节约内存,用来联合来处理。
柱子,则是将柱子本身和两个柱子墩中间的背景,以及柱子右边3个像素宽度的的背景先写入缓存(这样每次柱子可移动1-3像素,下次刷屏之际再下一个位置刷就行,老图像会被覆盖),最后一次性刷到屏里面
u16 FlappyBird_GreenBar_Buff[12][240];
u16 FlappyBird_column_Buff[257][42];//20560
union Bird_Buff
{                  
    u16 normal_Bird[18][26];//正常鸟的缓存
    u16 f_mode_Bird[26][18];//坠落的鸟的缓存
}FlappyBird_Bird_Buff;
2、大面积的图,比如说整个背景,则是先用dma+tim8的方法刷入。
因为lcd的rd引脚在定时器8的通道2上面,所以说用tim8做一个pwm,然后吧定时器的溢出作为dma的使能,(先设置好刷屏窗口,吧cs拉低和rs拉高)由dma直接从flash或者sram吧数据搬到GPIO-ODR,数据使能脚的pwm时间到使能一下,图就进去了。
实测从flash的数据19个时钟周期就能刷到屏幕上,sram的数据16个差不多就可以了。
3、大面积的单 {MOD}。类似于高速的清屏。
先设置好刷屏窗口,吧cs拉低和rs拉高,16bit数据放在gpiob上,定时器设置做三个周期的pwm(0分频,2溢出)。实测大约3.5ms就刷满全屏,实际使用的时候稍微调整下时间就好(原子哥的LCD_clear大概要30+ms)

因为我只有9325的屏幕,为了快速lcd的函数和游戏的函数有混合
比如说刷柱子的时候用到了这样来处理一部分柱子在屏幕外的情况:
        LCD_WriteReg(lcddev.setxcmd, x);//设置光标位置
        for( j=0; j < 257; j++ )
        {
            LCD_WriteReg(lcddev.setycmd, j);//设置光标位置
            LCD_WriteRAM_Prepare();    //开始写入GRAM
            LCD_CS_CLR;
            LCD_RS_SET;//数据
            for( i = 0; i < 42; i++ )
            {
                if((i+x)>239)break;//超出区域的控制   
                GPIOB->ODR=FlappyBird_column_Buff[j];
                LCD_WR_CLR;
                LCD_WR_SET;
            }
        }
所以说就不支持其他主控的屏幕了(面面俱到的考虑比较费脑力,而且搞了也没法试验对不对),需要其他屏幕玩的童鞋需要移植下。
屏幕驱动需要移植的地方:lcd.c 文件、dma_lcd.c文件和Engine.c文件的FlappyBird_Frame_DrawColumn和FlappyBird_Frame_DrawBird_Play函数

因为带了的图片资源差不多256k,在调试的时候频繁烧入很浪费时间,也比较伤flash所以我固定了资源的地址,且平时不需要烧录,第一次下载,或者更新资源才需要下载,方法是:
在flappybird_pic_map.h文件下有
#define refresh_flash  //如果开启这个define,那么将重新刷写资源进入flash,几乎需要擦写整个片区,同时清零历史成绩记录
//建议第一次烧录的时候将资源烧入,后面关闭开关


另外,理论上需要STM32103RE芯片(图片资源写在了256-512k的地方),但是RC容量和RD容量芯片可以自行尝试(用jlink之类)超区域写入是否有问题(一般没问题),RB和R8就洗洗睡吧,stlink似乎也是可以洗洗睡了

难度有5级可调,新手,简单,困难,非常困难和速度增加(也就是分越高越快)
成绩记录有四个最高排名,这些数据都记录在eeprom里面。
原作者的暂停键我搞不明白有啥用,改成点进去是成绩记录和设置难度了,哈哈。

原作者用的空引脚读adc得到做随机数种子,我改成都内部温度传感器和内部基准的加和了。而且随机数种子只需要一次就可以了,不知道原作为毛每次都做

鸟的姿态除了平飞和垂直下坠,我加了斜上和歇下飞的效果,稍微自然一点了
而且在撞到柱子的时候,也有和手机上一样的加了坠效果机


FlappyBird原子mini板 9325屏幕. ...
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。