G0001学习记录 G0001写贪吃蛇
分享作者:F888
作者昵称:我爱小易
评测品牌:灵动微电子
评测型号:MM32G0001A1TC
发布时间:2025-10-20 11:04:28
2 1
前言
开源口碑分享内容
一、硬件平台与功能概览
- 主控:MM32G000
- 显示:I2C/SPI OLED(128×64)
- 输入:4 个独立按键(上/下/左/右)
二、核心数据结构设计
1. 定义“蛇段”结构体
typedef struct {
uint8_t x;
uint8_t y;
uint8_t length; // 实际仅蛇头用到 length,食物可复用此结构
} Snake;
2. 全局变量管理状态
Snake snake; // 蛇头
Snake food; // 食物
Snake snake_body[50]; // 蛇身(最大长度 50,占用 100 字节)
uint8_t direction = 4; // 当前方向(1=上, 2=下, 3=左, 4=右)
uint8_t previous_direction = 4; // 上一次方向(防 180° 调头)
三、关键函数解析
1. 初始化:蛇与食物
void Snake_Init() {
snake.x = 32; snake.y = 20;
snake.length = INIT_SNAKE_LENGTH; // 如 3
// 初始化蛇身:水平向左排列
for (uint8_t i = 0; i < snake.length; i++) {
snake_body[i].x = snake.x - i;
snake_body[i].y = snake.y;
}
// 食物初始位置
food.x = 32; food.y = 26; food.length = 1;
}
蛇身初始化必须与初始方向一致,否则移动时会“断裂”。
2. 方向控制:防 180° 调头
uint8_t Snake_GetKey() {
if (KEY_NUM == 0) return previous_direction;
switch(KEY_NUM) {
case 1: // 上
if (previous_direction != KEY_DOWN) {
previous_direction = KEY_UP;
return KEY_UP;
}
break;
// ... 其他方向类似
}
return previous_direction; // 无效操作返回原方向
}
⚠️不能从“上”直接按“下”,否则蛇会“咬自己脖子”!
3. 蛇的移动:数组平移法
void Snake_Update() {
// 蛇身整体前移:从尾到头拷贝
for (uint8_t i = snake.length - 1; i > 0; i--) {
snake_body[i] = snake_body[i - 1];
}
// 蛇头更新为当前位置
snake_body[0].x = snake.x;
snake_body[0].y = snake.y;
// 绘制整条蛇
for (uint8_t i = 0; i < snake.length; i++) {
OLED_DrawPoint(snake_body[i].x, snake_body[i].y);
}
}
头进尾出,无需动态内存
4. 吃食物 & 随机生成
oid Snake_Eatfood() {
if (snake.x == food.x && snake.y == food.y) {
snake.length++; // 蛇变长
// 利用全局时间种子生成随机位置
srand(times); // times 由 1ms 定时器累加
food.x = rand() % 126 + 1; // 避开边框(1~126)
food.y = rand() % 62 + 1; // (1~62)
}
}
5. 游戏结束判断
uint8_t Snake_GameOver() {
if (snake.x >= GAME_WIDTH - 1 || snake.x < 1 ||
snake.y >= GAME_HEIGHT - 1 || snake.y < 1) {
return 0; // 碰墙
}
return 1; // 游戏继续
}
边界定义:OLED 有效区域为 (1,1) 到 (126,62),边框 (0,0)-(127,63) 为游戏墙。
四、主循环:帧刷新策略
void snake_game_main() {
OLED_Clear();
Draw_GameBorder();
Snake_Init();
OLED_Update();
while (1) {
Snake_direction(); // 更新蛇头坐标
Snake_Update(); // 移动并绘制蛇身
Snake_Eatfood(); // 检测吃食物
Snake_Draw(food.x, food.y, 1); // 重绘食物
OLED_Update(); // 刷新屏幕
OLED_ClearArea(1, 1, 126, 62); // 清除游戏区(下帧重绘)
if (!Snake_GameOver()) break; // 游戏结束
}
}
五、结语
通过这个项目,你不仅锻炼了编程能力,更培养了:
- 问题分解能力(把游戏拆成初始化、移动、碰撞等模块)
- 调试思维
- 资源约束意识
全部评论

暂无评论

0/144