【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.pswp.cn/web/95652.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/95652.shtml
英文地址,請注明出處:http://en.pswp.cn/web/95652.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

江協科技STM32學習筆記補充之004

STM32 ISP 一鍵下載電路&#xff08;按功能、邏輯與時序拆解&#xff09;

數據庫小冊(1)

1. 關系型數據庫主要考點關系型數據庫&#xff1a;架構索引鎖語法理論規范2. 如何設計一個關系型數據庫設計即模塊劃分。數據庫最主要的功能是存儲我們的數據&#xff0c;所以需要一個存儲的文件系統。我們要把涉及到的物流數據提供邏輯的形式給組織和表示出來&#xff0c;這是…

記錄收入最高的一次私活 選號網,需要大量賣號的人可能需要,比如游戲腳本批量跑的號

選號網管理后臺(上傳游戲信息、賬號信息、 查看記錄) http://124.223.214.5:180/admin1 選號網客戶端(PC/H5頁面 給客戶篩選商品用) http://124.223.214.5:181/ 該在線地址僅供低頻率測試&#xff0c;正式使用需要另外部署。 功能不滿足可以聯系開發者定制 一、項目的由來 …

熱烈慶祝“中國抗戰勝利80周年”,織信低代碼助力國之重器砥礪前行!

“從保家衛國到科技強軍&#xff0c;織信低代碼平臺為軍工企業數字化轉型注入新動能。”80年后的今天&#xff0c;國人記憶從未褪色。2025年9月3日&#xff0c;正值中國抗戰勝利80周年閱兵之際&#xff0c;我國國防軍工力量在經歷長期的艱苦奮斗后&#xff0c;現今終于迎來了曙…

PostgreSQL與SQL Server:B樹索引差異及去重的優勢

PostgreSQL與SQL Server&#xff1a;B樹索引差異及去重的優勢 在優化查詢性能方面&#xff0c;索引是數據庫工程師可使用的最強大工具之一。PostgreSQL和Microsoft SQL Server&#xff08;或Azure SQL&#xff09;都將B樹索引用作其默認索引結構&#xff0c;但每個系統實現、維…

【微實驗】使用MATLAB制作一張賽博古琴?

當一個理工音樂人沒錢去買古琴&#xff0c;我直接用代碼畫一個古琴&#xff01;目錄 零、總腳本&#xff1a; 一、核心功能&#xff1a;交互模塊拆解 二、核心價值 一、初始化腳本&#xff1a;參數配置與啟動界面 ①廢話不說&#xff0c;直接上代碼 ②代碼模塊拆解與詳細解…

畢業項目推薦:67-基于yolov8/yolov5/yolo11的大棚黃瓜檢測識別系統(Python+卷積神經網絡)

文章目錄 項目介紹大全&#xff08;可點擊查看&#xff0c;不定時更新中&#xff09;概要一、整體資源介紹技術要點功能展示&#xff1a;功能1 支持單張圖片識別功能2 支持遍歷文件夾識別功能3 支持識別視頻文件功能4 支持攝像頭識別功能5 支持結果文件導出&#xff08;xls格式…

無人機小尺寸RFSOC ZU47DR板卡

整板尺寸&#xff1a;120*120mmFPGA: XCZU47DR-2FFVE1156I;DDR&#xff1a;PS側8GB 2400Mhz*64bit / PL側 4GB 2400Mhz*32bit&#xff1b;2路(QSP0QSPI1)/單片512Mb、共計1Gb&#xff1b;千兆以太網&#xff1a;1路&#xff08;PS側&#xff09;&#xff1b;主要接口資源如下&a…

LangGraph(一):入門從0到1(零基礎)

文章目錄LangGraph入門從0到10?? 安裝 & 確認環境1?? 把 LangGraph 想象成「自動化的做菜流水線」2?? 最小可運行例子&#xff1a;一句話復讀機3?? 加一個小節點&#xff1a;把用戶輸入變大寫4?? 條件邊&#xff1a;如果用戶說 quit 就結束&#xff0c;否則復讀5…

學習數據結構(16)快速排序

快速排序的基本思想&#xff1a;快速排序是Hoare于1962年提出的一種二叉樹結構的交換排序方法&#xff0c;其基本思想為&#xff1a;任取待排序元素序列中的某元素作為基準值&#xff0c;按照該基準值將待排序集合分割成兩子序列&#xff0c;左子序列中所有元素均小于基準值&am…

uni-app iOS 上架常見問題與解決方案,實戰經驗全解析

uni-app 讓開發者能夠“一套代碼&#xff0c;多端運行”&#xff0c;極大降低了開發成本。 但當應用進入 iOS 上架階段 時&#xff0c;不少團隊發現流程并沒有想象中那么順利&#xff1a;證書問題、打包失敗、上傳出錯、審核被拒……這些都可能讓項目卡殼。 本文結合實際案例&a…

洗衣機的智能升級集成方案WT2606B屏幕驅動+AI語音控制

2025&#xff0c;洗衣機市場正從功能滿足轉向體驗升級&#xff0c;企業正面臨哪些轉型難點?一文為您解讀洗衣機行業智能化升級之路。傳統洗衣機就像是一個"沉默的工人"&#xff0c;只能通過簡單的LED指示燈告訴你它在工作&#xff0c;卻無法讓你真正了解它在干嘛。用…

機器學習進階,梯度提升機(GBM)與XGBoost

梯度提升機&#xff08;Gradient Boosting Machine, GBM&#xff09;&#xff0c;特別是其現代高效實現——XGBoost。這是繼隨機森林后自然進階的方向&#xff0c;也是當前結構化數據競賽和工業界應用中最強大、最受歡迎的算法之一。為什么推薦XGBoost&#xff1f; 與隨機森林互…

【ARMv7】開篇:掌握ARMv7架構Soc開發技能

本專欄&#xff0c;開始與大家共同總結使用ARMv7系列CPU的Soc開發技能。大概匯總了一下&#xff0c;后面再逐步完善下面的思維導圖。簡單說說&#xff1a;與通用的ARMv7-A/R相比&#xff0c;以STM32F為代表的ARMv7-M架構有以下關鍵區別和重點&#xff1a;無MMU&#xff0c;有MP…

【學術會議論文投稿】JavaScript在數據可視化領域的探索與實踐

【ACM出版 | EI快檢索 | 高錄用】2024年智能醫療與可穿戴智能設備國際學術會議&#xff08;SHWID 2024&#xff09;_艾思科藍_學術一站式服務平臺 更多學術會議請看 學術會議-學術交流征稿-學術會議在線-艾思科藍 目錄 引言 JavaScript可視化庫概覽 D3.js基礎入門 1. 引入…

CSS基礎學習步驟

好的&#xff0c;這是一份為零基礎初學者量身定制的 **CSS 學習基礎詳細步驟**。我們將從最根本的概念開始&#xff0c;通過一步一步的實踐&#xff0c;帶你穩穩地入門。 第一步&#xff1a;建立核心認知 - CSS 是做什么的&#xff1f; 1. 理解角色&#xff1a; HTML&…

MTK Linux DRM分析(三十七)- MTK phy-mtk-hdmi.c 和 phy-mtk-hdmi-mt8173.c

一、簡介 HDMI PHY驅動 HDMI 的物理層接口主要就是 HDMI Type-A 接口(19 pin),除此之外還有 Type-B、Type-C(Mini HDMI)、Type-D(Micro HDMI)、Type-E(車載專用)。 1. HDMI Type-A(常見 19-pin 標準接口) HDMI Type-A Connector Pinout ========================…

【人工智能學習之MMdeploy部署踩坑總結】

【人工智能學習之MMdeploy部署踩坑總結】報錯1&#xff1a;TRTNet: device must be a GPU!報錯2&#xff1a;Failed to create Net backend: tensorrt報錯3&#xff1a;Failed to load library libonnxruntime_providers_shared.so1. 確認庫文件是否存在2. 重新安裝 ONNX Runti…

力扣516 代碼隨想錄Day16 第一題

找二叉樹左下角的值class Solution { public:int maxd0;int result;void traversal(TreeNode* root,int depth){if(root->leftNULL&&root->rightNULL){if(depth>maxd){maxddepth;resultroot->val;}}if(root->left){depth;traversal(root->left,depth…

網格圖--Day07--網格圖DFS--LCP 63. 彈珠游戲,305. 島嶼數量 II,2061. 掃地機器人清掃過的空間個數,489. 掃地機器人,2852. 所有單元格的遠離程度之和

網格圖–Day07–網格圖DFS–LCP 63. 彈珠游戲&#xff0c;305. 島嶼數量 II&#xff0c;2061. 掃地機器人清掃過的空間個數&#xff0c;489. 掃地機器人&#xff0c;2852. 所有單元格的遠離程度之和 今天要訓練的題目類型是&#xff1a;【網格圖DFS】&#xff0c;題單來自靈茶山…