当前位置: 首页 > news >正文

【STM32】贪吃蛇 [阶段 3] 增强模块结构(架构优化)

这篇博客是 承接:【项目思维】贪吃蛇(嵌入式进阶方向)中 聚焦于 🧱 阶段 3:增强模块结构(架构优化) 中的 菜单系统(Menu System),这部分的结构优化可以学到的内容包含:工程项目架构设计、模块划分、状态管理、事件响应、接口抽象、可扩展性(预留) 等方面。接下来,我将对这些内容进行详细说明。

🧱 阶段 3:菜单系统的架构优化(模块化 + 状态机)

🎯 目标:
构建一个可维护、可扩展、可复用的菜单系统框架,为后续游戏 / 应用系统提供通用架构。

一、总体架构图
Main
├── MenuManager(菜单框架)
│   ├── 状态管理(enum GameState)
│   ├── 菜单项结构体(MenuItem)
│   └── 菜单事件派发器(事件响应)
├── UI_Display(接口抽象)
│   ├── OLED 显示实现
│   └── TFT 显示实现
├── InputManager(输入管理)
│   ├── 按键扫描
│   └── 输入事件封装
├── Assets(资源)
│   ├── 字体 / 图标
│   └── 菜单配置
📦 二、文件结构 + 模块划分(示例)

此处的模块化划分仅供参考:模块化的具体情况要根据具体项目进行合理化分解。

📁 Core/
│   ├── main.c
│   ├── app.c / app.h            	// 主程序调度
│   └── game_state.c / .h        	// 状态控制
📁 Menu/
│   ├── menu.c / menu.h          	// 菜单控制逻辑
│   └── menu_items.c / .h        	// 菜单项配置
📁 Drivers/
│   ├── oled.c / .h              	// OLED 显示驱动
│   ├── tft.c / .h               	// TFT 驱动
│   └── input.c / .h             	// 输入处理(按键)
📁 Assets/
│   └── font.c / icon.c          	// 字体、图标资源
📦 三、状态管理(GameState)
typedef enum {STATE_MENU,STATE_PLAY,STATE_PAUSE,STATE_GAME_OVER
} GameState;static GameState current_state = STATE_MENU;void switch_state(GameState new_state) {current_state = new_state;// 可在此执行 state entry 动作
}
🔖 四、菜单项结构体定义
typedef struct MenuItem {const char* name;void (*on_select)(void);  // 选中时执行的回调
} MenuItem;MenuItem main_menu[] = {{"Start Game", start_game},{"Settings", open_settings},{"About", show_about},{"Exit", system_exit}
};
🎮 五、菜单控制逻辑(MenuManager)

1. 菜单状态结构:

typedef struct {int current_index;MenuItem* items;int item_count;
} MenuState;MenuState menu = {.current_index = 0,.items = main_menu,.item_count = sizeof(main_menu)/sizeof(MenuItem)
};

2. 菜单事件响应:

void menu_handle_event(InputEvent evt) {switch (evt) {case EVENT_UP:menu.current_index = (menu.current_index - 1 + menu.item_count) % menu.item_count;break;case EVENT_DOWN:menu.current_index = (menu.current_index + 1) % menu.item_count;break;case EVENT_OK:if (menu.items[menu.current_index].on_select)menu.items[menu.current_index].on_select();break;default:break;}
}
🖥️ 六、显示层抽象(支持 OLED / TFT)

1. 显示接口定义(display_interface.h):

typedef struct {void (*clear)(void);void (*draw_text)(int x, int y, const char* text, bool selected);void (*refresh)(void);
} DisplayInterface;extern DisplayInterface* display;  // 指向当前使用的显示驱动

2. OLED 实现:

DisplayInterface oled_display = {.clear = oled_clear,.draw_text = oled_draw_text,.refresh = oled_refresh
};

使用方式:

void render_menu(MenuState* m) {display->clear();for (int i = 0; i < m->item_count; ++i) {display->draw_text(0, i*10, m->items[i].name, i == m->current_index);}display->refresh();
}
🕹️ 七、事件机制(按键输入与事件派发)

1. 输入事件定义:

typedef enum {EVENT_NONE,EVENT_UP,EVENT_DOWN,EVENT_OK
} InputEvent;

2. 按键扫描模块输入处理:

InputEvent read_input_event() {if (key_press(KEY_UP)) return EVENT_UP;if (key_press(KEY_DOWN)) return EVENT_DOWN;if (key_press(KEY_OK)) return EVENT_OK;return EVENT_NONE;
}

此处可以加入 事件队列机制,支持多个模块监听同一事件。


🛠️ 八、主函数(main.c
int main(void) {hardware_init();display = &oled_display;  // 或 tft_displaywhile (1) {InputEvent evt = read_input_event();switch (current_state) {case STATE_MENU:menu_handle_event(evt);render_menu(&menu);break;case STATE_PLAY:game_run();break;// 更多状态...}delay_ms(50);}
}
菜单系统设计原则

模块解耦:菜单逻辑、UI 显示、输入处理独立开发。
状态明确:使用 GAME_STATE 管理程序流程。
接口抽象:显示接口统一支持不同设备。
事件驱动:菜单响应按键事件,支持外部事件扩展。
可扩展性:菜单项可动态增加 / 嵌套子菜单。

这个菜单后续还可以扩展更多的功能:
功能						实现方式
菜单嵌套					每个菜单项跳转到子菜单(子 MenuItem 数组)
动画效果					菜单切换时加入滑动、淡入淡出
声音反馈					按键 / 选中时播放 beep 声
存档支持					菜单设置保存到 Flash
多语言支持				使用字符串资源表切换语言

以上,欢迎有从事同行业的电子信息工程、互联网通信、嵌入式开发的朋友共同探讨与提问,我可以提供实战演示或模板库。希望内容能够对你产生帮助!

http://www.dtcms.com/a/360936.html

相关文章:

  • HarmonyOS应用开发深度解析:基于Stage模型与ArkTS的现代实践
  • ServBay 是一款集成式、图形化的本地 Web 开发环境工具,专为 macOS 和 Windows 系统设计
  • LeetCode 142. 环形链表 II - 最优雅解法详解
  • Linux自动化构建工具-make/Makefile
  • 【并发场景问题】超卖、一人一单业务问题的解决方案
  • AI 重构医疗诊断:影像识别准确率突破 98%,基层医院如何借技术缩小诊疗差距?
  • Git指令 | 个人学习笔记
  • Interceptor拦截器入门知识及其工作原理
  • Python OpenCV图像处理与深度学习:Python OpenCV图像滤波入门
  • gradle安装、配置环境变量、配置阿里源及idea 中配置gradle
  • RabbitMinQ(模拟实现消息队列项目)02
  • Axure科技感可视化原型案例:赋能设计与研发的宝藏资源
  • 二、感知机
  • 你的Redis是不是在家能用,到了学校就连不上?
  • CPTS-Vintage 票据,基于资源的约束委派 (RBCD),DPAPI密钥
  • 搭建APP应用程序如何选择服务器
  • ‌NAT穿透技术原理:P2P通信中的打洞机制解析‌
  • 【机器学习入门】4.4 聚类的应用——从西瓜分类到防控,看无监督学习如何落地
  • Windows11安装WSL教程
  • HBase实战(一)
  • golang json v1 和 v2对比差异
  • 【重学MySQL】九十六、MySQL SQL Mode高效配置全攻略
  • Beego: Go Web Framework 详细指南
  • ⚡ Linux xargs 命令参数详解
  • 【数据可视化-103】蜜雪冰城门店分布大揭秘:2025年8月数据分析及可视化
  • Ubuntu 25.10 Snapshot4 发布。
  • 小迪Web自用笔记23
  • Linux 定时任务 crontab 完全指南 —— 让服务器自动干活,解放双手
  • 【XR技术概念科普】详解6DoF:为什么它是沉浸感的关键?
  • 【开题答辩全过程】以 健身爱好者饮食管理小程序为例,包含答辩的问题和答案