基于RT-Thread实现的小游戏(贪吃蛇、俄罗斯方块)

前言:本实现基于stm32芯片,移植RT_Thread Nano系统源码,实现两个小游戏(贪吃蛇/俄罗斯方块)。本实验提供完整的IAR工程源码并且有很多注释,是一个不错的参考例程。关键知识点:OLED驱动,ADC采样,游戏逻辑设计,RT_Thread移植


《点击下载源码》

1.硬件设计

0.96寸OLED

基于RT-Thread实现的小游戏(贪吃蛇、俄罗斯方块)_第1张图片基于RT-Thread实现的小游戏(贪吃蛇、俄罗斯方块)_第2张图片

摇杆

基于RT-Thread实现的小游戏(贪吃蛇、俄罗斯方块)_第3张图片

stm32f103c8t6 (64k-ROM 20k-RAM)

基于RT-Thread实现的小游戏(贪吃蛇、俄罗斯方块)_第4张图片

以上材料,照着图片搜索都能在TB买到。

2.设计思路:

运用RT-Thread系统需要结合自己的项目需求,将RT-Thread的优点发挥出来,不仅要实现需求,还要让代码具有可扩展性、移植性。

我们利用一个定时器进行周期地检测摇杆的状态,我们要保证任务能够快速响应摇杆。

作为游戏机而言,其中包含了很多种小游戏,如果一种游戏当作一个线程,那么某一个时刻只会运行一个游戏,也就是一个游戏线程;创建那么多个线程不就没有意义了吗?确实最好的方式是使用前后台的形式实现,但这里为了让代码能够层次分明,可扩展性,一个小游戏就是一个线程,系统只需要运行当前用户打开的小游戏的线程,其他的线程挂起,不参与调度。

回到刚才摇杆的问题,我们要保证每个线程都能快速地获取摇杆状态,当摇杆的状态变化时产生出一个摇杆事件,线程等待该事件,当事件到来时,调用摇杆驱动的接口,主动获取摇杆信息。

按键也是同样的道理,利用一个定时器周期地检测按键的状态,当有按键发生变化时产出事件,线程等待事件发生时,主动获取按键信息。

接下来说一下关于显示的问题,通常的做法就是利用定时器,周期地将显存的数据同步到屏幕了,但是这样做有缺陷,但用户没有操作界面变化时,这时候的刷新时没有必要的,会大大增加系统的负担。

我们用一个线程实现周期地刷新屏幕,其他的线程会调用屏幕驱动函数,把数据写入显存时,在该函数里发送一个屏幕刷新事件,屏幕服务线程等待到这个事件就进行屏幕显示刷新,将显存的数据通过i2c发送的屏幕。

我们需要利用一个线程也就是main函数进行游戏管理和设置,当用户选择某种游戏时,创建该游戏的线程,当退出时,把该线程删除。

线程的优先级:main函数 > 游戏进程 > 屏幕刷新线程。要注意的是在屏幕刷新时,进行i2c数据传送过程中不能被其他线程打断,所以先把中断关闭,数据传输完成后再打开中断。

3.代码设计:

我之前单独做过贪吃蛇和俄罗斯方块的小游戏,再结合STM32移植rt_thread源码的例程。可参考以下博客:

基于stm32、0.96寸OLED实现的贪吃蛇小游戏(详细源码注释)
基于stm32、0.96寸OLED实现的俄罗斯方块小游戏(详细源码注释)
基于IAR-stm32裸板工程,完美移植RT-Thread Nano系统(附源码)

将上面的代码结合到一个工程里就是本篇所要做的项目:

基于RT-Thread实现的小游戏(贪吃蛇、俄罗斯方块)_第5张图片

使用说明:

接线如下:

基于RT-Thread实现的小游戏(贪吃蛇、俄罗斯方块)_第6张图片

如果要在电脑上看串口打印信息,需要将PA9引脚通过串口小板接到电脑。

  • 下载编译代码,将工程烧录到开发板上,点击运行,出现以下界面,如果屏幕花屏,那么将OLED的RES引脚接地进行复位,再复位单片机。

基于RT-Thread实现的小游戏(贪吃蛇、俄罗斯方块)_第7张图片

  • 上下控制摇杆可以选中不同的游戏,按下摇杆中键进入选中的游戏,例如运行Snake游戏,首先出现以下界面:

基于RT-Thread实现的小游戏(贪吃蛇、俄罗斯方块)_第8张图片

  • 再按下摇杆中键开始游戏,操控摇杆进行游戏,界面如下:

基于RT-Thread实现的小游戏(贪吃蛇、俄罗斯方块)_第9张图片

  • 在游戏进行时中或游戏失败(弹出”GAME OBER”),这时候按下中键可以重新开始游戏:

基于RT-Thread实现的小游戏(贪吃蛇、俄罗斯方块)_第10张图片

  • 在游戏过程中,长按中键2s以上再松开回到首页。

如果在这个代码架构下添加新游戏,在main函数里的gamestr结构体数组加入元素,一个元素包括游戏名、游戏启动接口、游戏停止接口,游戏内容的实现方法可参考现有的游戏例程。


时间仓促,如有错误之处,还望指出。

 

《博观而约取,厚积而薄发。————苏轼》

你可能感兴趣的:(RT-Thread,STM32应用实例)