当前位置: 首页 > 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.xdnf.cn/news/1425043.html

相关文章:

  • curl 介绍及使用教程
  • python爬虫之selenium库进阶(小白五分钟从入门到精通)
  • 基本渗透概念
  • Raft 协议在 Nacos 中的实现
  • 从零开始实现Shell | Linux进程调度实战
  • Product Hunt 每日热榜 | 2025-09-01
  • 基于YOLOv11的脑卒中目标检测及其完整数据集——推动智能医疗发展的新机遇!
  • 齿轮里的 “双胞胎”:分度圆与节圆
  • [React]监听Form中某个字段的变化
  • 微算法科技(NASDAQ:MLGO)张量网络与机器学习融合,MPS分类器助力顶夸克信号识别
  • deepseek doubao chatgpt 优缺点分析
  • 并发--并发中的线程状态及不同状态下线程所在队列
  • React学习教程,从入门到精通, React 入门指南:创建 React 应用程序的语法知识点(7)
  • OpenCV-CUDA 图像处理
  • 数据库常见故障类型
  • 知识产品和标准化
  • 在 Qt 中加载 .qm 翻译文件
  • 跳跃游戏(二):DFS 求解最少跳跃次数与最优路径
  • 专项智能练习(Word)
  • JavaSE:抽象类和接口
  • 计算机视觉(五):blur
  • 原子操作(Atomic Operation) 是指不可被中断的操作——要么完整执行,要么完全不执行
  • 贵州在假期及夏天结束后保持旅游活力的策略分析
  • AI如何重塑电力工程设计?揭秘良策金宝AI的六大“超能力”
  • SQLSERVER关键字:N
  • VBA数据库解决方案第二十二讲:根据工作表数据生成数据库中数据表
  • 算法练习——189.轮转数组
  • 【逆序对 博弈】P10737 [SEERC 2020] Reverse Game|普及+
  • 【开题答辩全过程】以 基于JSP的养生网站设计与实现为例,包含答辩的问题和答案
  • MySQL 中 InnoDB 引擎的事务隔离级别与“可重复读”隔离级别下的 SQL 编写规范