注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
nemon的个人空间 https://home.eeworld.com.cn/space-uid-424743.html [收藏] [复制] [分享] [RSS]
日志

【平头哥RVB2601创意应用开发】掌上游戏机

已有 225 次阅读2022-6-6 22:16 |个人分类:CH2601

 

作品名称掌上游戏机

 

作者:nemon

https://bbs.eeworld.com.cn/home.php?mod=space&uid=424743

javascript:;

 

  • 项目背景

以前有人统计说大众最热衷3个G,其中为首的就是GAME。看到核心为平头哥CH2601芯片的RVB2601开发板的片上资源、板载资源都很丰富。于是基于这个平台,制作了掌上游戏机的原型。

  • 作品简介

本项目完全基于RVB2601开发板本身资源,以用户按键K1、K2作为输入,OLED作为输出,自造了位图、字体、抽象屏幕、游戏应用框架4个车轮,优化了oled的刷新算法,手工绘制了全部所需位图,编制出主菜单和flappy bird共2个应用。

操作过程:开机后显示菜单。

 

根据屏幕提示,按右键(B)可以更换选项,按左键(A)运行游戏。

 

 

根据屏幕提示,按右键(B)退出,按左键(A)开始游戏。

 

在游戏中,按左键(A)提升小鸟,钻过缺口得一分,撞倒水管游戏结束。

 

  • 系统框图

 

  1. 系统硬件组成

 

通过GPIO得到按键操作,经mpu处理,通过SPI接口,更新oled屏

 

  1. 组件关系图

 

main函数调用csi_gpio_pin进行初始化等。Menu和FlappyBird实现Game结构体,main函数调用Menu并传递事件给它;menu调用FlappyBird并传递事件给它。各种Game都使用Screen更新oled。Font使用Image存储点阵,Screen及各种Game都依赖Image、Font。

 

  1. GAME的状态转移

 

父过程调用game的init来获取单例并初始化,game自己控制状态,在收到父过程通过event_handle传过来事件后,决定如何处理,并返回状态。当game将自己状态置为退出后,父进程接管控制流。

 

  • 各部分功能说明和解析

1、源码文件清单

 

以上文件,以文件名对应第二部分“组件关系图”中的各组件。

  1. 位图Image.hImage.c):

结构体IMAGE包含3个子元素:位图宽,位图高,数据数组。此处为了简化多维数组处理,数据用了一维数组,于是就定义了一个宏 IMAGE_POT,用于将二维的表示法转为一维的定义。image_create_function 用数据创建位图,如果只提供了大小,可以创建空白图片。 image_destory_function 销毁位图,主要作用是释放位图占用的内存。另有5个工具函数,作用分别是:水平翻转、垂直翻转、旋转180度、右转90度、左转90度。

3、字体Font.hFont.c):

存储每个字符的位图,用函数font_get_char_function“字库”里检索

  1. flappy bird游戏(game_FlappyBird.h、game_FlappyBird.c):

实现动画和游戏逻辑,包括按键处理、评分、各阶段屏幕绘制。

  1. 屏幕抽象层(Screen.h、Screen.c):

screen_init_function(int b_flag_inversen);用于初始化屏幕,并设置屏幕是否为反色输出。就是这个反色输出功能,使我能用习惯的黑白来画图。如果需要,也可以在OLEd和LCD间方便地切换。

screen_set_dirty_flag_function(int b_flag) 和 screen_set_auto_refresh_flag_function(int b_flag) 用于设置是否发生更改和是否自动向设备层刷新。这两个函数是联合使用,我一般先关掉自动刷新,然后绘图的时候,绘图函数自动根据颜色来设置是否有更改。所有的画图都完成后,再打开自动刷新,这时就会根据之前的更改标记来决定是否调用OLED驱动函数进行刷新。

void screen_refresh_function();如名字所示,执行它会进行一次强制刷新。

void screen_clean_function();如名字所示,执行它会清理缓存。

另外的几个功能函数,分别是screen_draw_bitmap_function(画位图)、screen_draw_string_function(调用字库画字符串)、screen_draw_Int32_function(数字转字符串画出)、screen_draw_horizontal_line_function(画水平线)、screen_draw_vertical_line_function(画垂直线)、screen_draw_rectangular_function(用边框色和填充色画矩形)、screen_draw_dot_function(画一个点)。

  1. oled优化(只涉及函数oled_reflesh):

增加一级缓存,用于记录上一次更新后的屏幕数据:

uint8_t g_oled_ram_cache[8][128]={0};

修改oled_reflesh(),增加输出前判断是否一致(由于硬件特性,连续修改不需要设置列的位置)。

7、抽象游戏结构体(Game.h

Game.c中仅是被注释起来的示例。game_event预定义了按键A、B、1、2、3、4按下,以及定时器触发和请求刷新显示事件。父过程通过结构体_GAME中的(*game_event_handle)(game_event event)向子过程传递事件,并获取最新的GAME_STAT。面向对象的角度看,每个游戏都是一个单例对象。启动一个游戏时,首先执行该游戏的init函数,获得指向该游戏的结构体指针game。之后有2种处理方法:用中断或是while(1)如果用中断,则(1)执行game->game_loop_handle直到退出;(2)在事件对应的处理函数中调用game->game_event_handle,将事件传递给game;(3)维护一个game*的栈,把当前的game压进去,并在game退出时,恢复最新的顶部game。如果使用while(1),则(1)while(1)要写在在main函数一级,也就是整个系统的最高层;(2)通过PIO、延时等方法判断是否触发事件,然后用game->game_event_handle,将事件传递给game,同时根据返回的GAME_STAT值,判断是否游戏已经退出。(3)由于这种情况下,需要父级game管理子级game,并在子级game退出时,接管输入输出。

8、主菜单(game_MainMenu.h、game_MainMenu.c):

用于显示菜单和启动游戏。因为现在只做了1个Flappy Bird,所以10个菜单挂的是它。然后把菜单出来,响应按钮事件,更换选择或执行选中游戏的操作。当选中时,将gameMenu状态设置成游戏中,同时初始化对应的game,这时所有的事件都应该传给当前的game。传事件之后顺便检查一下,要是已经退出了,那就把gameMenu的状态改回来,也就是接管控制。

 

  • 作品源码

初步统计,代码超过1600行。核心代码在发帖和博客中详细分析(见第七部分的链接)。工程文件压缩后约35MB,链接: https://pan.baidu.com/s/18FNGYZJgrcPjjpHOT-gd0A 提取码: uxyn 。

  • 视频演示(视频简介+链接)

基于平头哥CH2601的游戏掌机原型:flappy bird:

链接地址:javascript:;

  • 项目总结
  1. 项目总结:

本项目验证了RVB2601的资源和处理能力,在YoC的组件基础上,比较快速的搭建出了掌上游戏机平台。受时间约束,完成了主控和一个游戏,可以作为原型验证CH2601的运算速度和片上存储空间。

后期努力方向包括:

  1. 继续增加游戏种类,对接更多控制方式;
  2. 了解组件依赖关系,裁剪工程,提高编译速度;
  3. 研究udp协议实现,支持网络对战。

 

2、【平头哥RVB2601创意应用开发】掌上游戏机”系列文章:

标题

电子工程世界-论坛-平头哥RISC-V RVB2601活动专区

平头哥芯片开放社区(OCC)博客

0)开箱,吓一跳

https://bbs.eeworld.com.cn/thread-1205763-1-1.html

 

1)对眼儿画图记

https://bbs.eeworld.com.cn/thread-1205765-1-1.html

javascript:;

2)飞翔的小鸟

https://bbs.eeworld.com.cn/thread-1205768-1-1.html

javascript:;

3)一按就蹦

https://bbs.eeworld.com.cn/thread-1205862-1-1.html

javascript:;

八、其他

感谢电子工程世界平头哥芯片开放社区的支持!

 

 

本文来自论坛,点击查看完整帖子内容。

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章