基于RP2040 Game Kit的复古平台跳越游戏
由5个关卡构成的平台跳越游戏,需要操控主角收集金币并到达终点,使用Pico SDK开发。
标签
嵌入式系统
显示
2022寒假在家练
迷湖浅浅
更新2022-09-14
1353

简介

该项目(图一)使用Pico SDK开发环境,用C++语言高性能的实现了一款基于RP2040微控器的经典平台跳越类型游戏,并且该游戏拥有基于Python语言实现的图片转16进制工具以及地图编辑器插件,可以对接专业级美术软件与游戏开发软件。游戏采用双层卷轴显示,拥有超大的地图,精灵动画,视觉效果极其丰富。尽管该项目所使用的开发板上的板载蜂鸣器没有数字到模拟转换,但游戏中使用PWM音效依旧实现了非常丰富的声音效果合成(音量调节,ADSR包络,噪音发生器,比特粉碎,变调,混响)。

图一

游戏的主角是一只名叫Proto的小狗(图二),你的目标是操纵主角在平台和各种机关之间跳跃攀爬,收集金币,并且最终到达目标。游戏共有五个精心设计的关卡(由6750个地图块组成,使用超过100种地图块类型,用于展示地图编辑器插件的强大能力(图三)),每个关卡有数量不等的金币,并且每一关都有一枚隐藏金币,需要精心留意细节才能发现,找齐全部金币并不容易。

图二

图三

该项目的代码充分利用了RP2040的双核M0+处理器,DMA,PIO等模块,在保证全程稳定43帧每秒运行的同时,依然有超过百分之50的CPU空闲周期可供日后添加更多玩法,视觉特效以及声音特效。

运行结构

硬件

这部分主要介绍在项目中发挥重要作用的硬件

 

M0+核心

RP2040拥有两颗这样的核心,虽然在ARM家族中的定位是低性能产品,但毕竟是32位芯片,其性能依旧可以和GBA等并不是很老的游戏机的处理器相媲美。RP2040的核心由片内的3.3V转1.1V进行供电,该供电可通过寄存器的设置来调节电压,核心的频率也能够通过软件进行调节,最高可达超过420MHz。GBA有专门的2D图形加速硬件,可以支持2D图像的缩放变形混合,对多达128个精灵进行硬件加速等强大功能,RP2040在游戏方面相比依旧实力不足,为了保证游戏运行的性能,核心电压被从1.1V加压到1.2V,核心频率由默认125MHz超频至250MHz。

 

DMA

游戏中需要涉及大量图像素材在各个缓冲区之间拷贝以及向屏幕的发送,例如如需显示一张地图,需先逐块定位到地图块所对应精灵集(terrain_b)的位置,并且向对应区域(map_canvas)进行拷贝,最终将地图根据摄影机变换叠加到屏幕缓冲区(SCREEN),再由PIO(稍后会详细说明)发送至屏幕。使用DMA可以在CPU只进行很少的参与下自动进行数据的转移,极大节约了CPU算力。

 

PIO

PIO是RP2040中的一个独特的硬件,可通过PIO汇编语言对其进行编程,让其自动进行信号的处理。在这个项目中,PIO被用来向ST7789显示屏驱动芯片发送像素信息。独特之处在于通过编程,PIO可以自动将一个像素的数据进行两次发送,再配合CPU将每一行也进行两次发送,就可以实现性能代价极小的半分辨率显示,非常适合复古游戏。PIO极大节约了CPU算力并且减少了几乎百分之75的内存使用。

代码说明

因为代码中实现的功能众多(仅游戏主逻辑就25个函数),不像实现某个具体功能的仪器可能有某几个重点的算法可以讲,对于这款游戏来说大部分函数的功能都很重要,并且附件源代码中的变量名函数名已经十分清楚明了,也有中文注释,在这里罗列出来只会影响观看,所以除了展示部分PicoSystem API中增改的代码,其它部分只挑选重点的做功能的介绍,具体实现方式可参照源代码。

对于PicoSystem API的功能增加以及修补

bool pressed(uint32_t b)
bool button(uint32_t b)

PicoSystem API采用gpio_get_all()函数获取按键信息,我在原生函数中增加了对摇杆的支持,前后左右键现在可以由摇杆代替,也可以使用普通按键。

void blit(buffer_t *src, int32_t sx, int32_t sy, int32_t sw, int32_t sh, int32_t dx, int32_t dy, int32_t dw, int32_t dh, uint32_t flags)

函数存在bug,在某些时候无法成功复制画面,只会显示白屏,在这款游戏中这个函数已被我修复,bug已经向PicoSystem API开发者进行和汇报并且得到了确认。

buffer_t*   buffer(uint32_t w, uint32_t h, void *data = nullptr)

函数存在bug,若不向其提供初始化画面,程序依旧能编译,但创建的缓冲区在后期使用时透明度通道会显示乱码,在这款游戏中通过为其提供透明图像序列来使这个函数暂时能够正常工作,bug已经向PicoSystem API开发者进行和汇报并且得到了确认。

多个以_no_offset结尾的函数

PicoSystem API的原生函数在绘图时均会被摄影机偏移影响,而在绘制界面等功能时不需要使用偏移,这些以_no_offset结尾的函数在绘制时不会偏移,适合用来绘制游戏UI。

struct Player
{
  int time, sp;
  float x, y;
  uint32_t flags;
  float dx, dy, max_dx, max_dy, acc, boost;
  bool running, jumping, falling, climbing, landed, sliding;
};

结构类型,储存玩家的位置,速度,状态等信息

地图相关

 

void pre_map(int *c_map, bool bg_flag = false)

根据当前关卡序号,读取地图块数据并在map_canvas缓冲上绘制地图画面

int m_get(int x, int y)

输入笛卡尔坐标,返回对应地图块的序号

bool t_get(int index, int tag)

检查对应序号地图块的属性是否与给出属性一致,返回布尔值。

bool collide_map(Player p, Aim aim_player, int type)
int collide_map(Player p, Aim aim_player, int type, bool coin)

检测玩家在给定方向(上下左右以及玩家中心)是否与地图发生碰撞,可选返回布尔值也可以返回具体碰撞的方块的类型标签。

音效

 

void sfx(int sfx_index)

声音效果的合成与播放

物理逻辑

 

void player_update()

获取玩家的按键输入,进行对重力加速度,摩擦力,刚体碰撞等的模拟,已经完成对道具碰撞的检测以及计分。

动画

 

void player_animate()

通过定时器以及玩家的状态更新玩家对应的精灵序号

void update_coins_animation()

通过定时器以及金币的可见性等状态更新金币对应的精灵序号

void game_start_draw()

绘制游戏开始画面,实现了一个有趣的文字动画

void game_running_draw()

绘制游戏运行时的画面,通过双卷轴滚动以及相机动画实现了一些透视效果

void game_end_draw()

绘制游戏结算画面

困难

这块开发板中最大的困难就是那块ST7789液晶,不知道为什么,其它用同款屏幕的开发板都连了CS引脚,但这块开发板就没连。因不明原因,这块屏幕在Pico SDK实现的程序中必须要在命令之间拉高一次CS引脚,屏幕才能正确读取指令,而CS引脚应当只是表示当前设备是否被选中,并不需要拉高应该就能正常读取下一个指令,在ST7789的数据手册中也没有记录必须拉高CS引脚才能读取下一个指令的情况。我自从12月底到2月中旬耗费无数个日夜,还斥巨资买了个逻辑分析仪,询问国内外多名大佬依旧没弄清楚它为什么在MicroPython下不用CS引脚也能驱动,但理论上功能完全一样的代码在C语言环境里就没法驱动,可能这就是华强北技术的独到之处吧。最后直接一坨锡连上,问题解决。这些研究让我对SPI通信以及液晶屏幕的驱动方式有了更深层次的认识,不过因为这个问题实在是太难解决以至于我最终都没能在软件中解决,之后编程中遇到的问题感觉起来都是不值一提的小问题了。

2020/2/24更新:已证实ST7789无法正常驱动是因为屏幕批次问题(因屏幕批次不同,故准备两款固件,若其中一款无法运行请尝试另一款),通过调整SPI极性,屏幕现在已经可以不用CS引脚即可驱动,太好了。(谢谢笛子老师发现的解决方案)

未来可以继续建设的部分

 

粒子效果:例如从高处落下地面会激起尘土,捡起金币会有金色粒子效果一类的。目前来看M0+的性能还绰绰有余,但目前内存占用已经比较吃紧,未来也许可以通过优化内存来实现粒子效果

 

多人联机:这块开发板上有红外发射与接受模块,是有能力实现多人联机的,但因为我只有一块开发板暂时没有开发联机功能

 

通过SD卡切换游戏:若是用C语言实现底层驱动,MicroPython来实现简单逻辑的话,也许可以开发通过SD卡切换游戏的功能,而不是每次只能下载一个游戏,但因为这块开发板上没有SD卡槽,也就没有设计这样的功能(实际有很多类似的项目已经实现了)。

 

附件下载
main.7z
游戏主程序
my_game.uf2
已经编译好可以直接上传的UF2文件
团队介绍
普瑞特艺术学院-工业与产品设计本科
团队成员
迷湖浅浅
罗德岛设计学院-动画 普瑞特艺术学院-工业与产品设计
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号