You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于网格的C++贪吃蛇游戏:LCD屏幕蛇身与果实对齐问题求助

解决贪吃蛇蛇身与果实对齐的网格系统实现方案

嘿,这个问题我之前帮朋友调试类似的LCD小游戏时碰到过,其实用网格系统来统一蛇身和果实的位置逻辑,就能完美解决对齐问题,结合你的C++基础和84×48的LCD尺寸,咱们一步步来落地:

第一步:确定网格单元尺寸

你的蛇身是3×3像素的方块,那直接把网格单元设为3×3像素就最合理了。先算好屏幕能划分的网格数量:

  • 横向列数:84 / 3 = 28列
  • 纵向行数:48 / 3 = 16行

在代码里可以定义成常量,方便后续复用:

const int GRID_CELL_SIZE = 3; // 每个网格的像素边长
const int SCREEN_GRID_COLS = 84 / GRID_CELL_SIZE;
const int SCREEN_GRID_ROWS = 48 / GRID_CELL_SIZE;

第二步:把所有位置从像素坐标转为网格坐标

之前你用的是逐像素的(x,y)位置,现在全部换成网格坐标(比如grid_x, grid_y),每个网格坐标对应屏幕上的像素区域是:
像素x起点 = grid_x * GRID_CELL_SIZE
像素y起点 = grid_y * GRID_CELL_SIZE

这样蛇的移动逻辑就从"每次移动1像素"变成"每次移动1个网格单元",彻底解决对齐问题。

第三步:修改蛇的移动与绘制逻辑

1. 蛇身数据结构调整

把蛇身每个节点的存储从像素坐标改成网格坐标:

struct SnakeSegment {
    int grid_x;
    int grid_y;
};

std::vector<SnakeSegment> snake_body;

初始化蛇身的时候,直接用网格坐标(比如从屏幕中间开始):

// 初始化3节蛇身,横向排列在屏幕中间
snake_body.push_back({14, 8});  // 蛇头
snake_body.push_back({13, 8});
snake_body.push_back({12, 8});

2. 移动逻辑修改

每次移动时,只需要修改蛇头的网格坐标,再把新蛇头插入队列、删除尾部(吃到果实则不删):

// 示例:向上移动
SnakeSegment new_head = snake_body.front();
new_head.grid_y -= 1;

// 处理边界(可选:穿墙逻辑)
if (new_head.grid_y < 0) {
    new_head.grid_y = SCREEN_GRID_ROWS - 1;
}

// 插入新蛇头
snake_body.insert(snake_body.begin(), new_head);

// 如果没吃到果实,删除尾部保持长度
if (!ate_food) {
    snake_body.pop_back();
}

3. 蛇身绘制

根据每个蛇身节点的网格坐标,计算对应的像素区域,绘制3×3的方块:

for (const auto& seg : snake_body) {
    int start_x = seg.grid_x * GRID_CELL_SIZE;
    int start_y = seg.grid_y * GRID_CELL_SIZE;
    int end_x = start_x + GRID_CELL_SIZE - 1;
    int end_y = start_y + GRID_CELL_SIZE - 1;
    
    // 调用你的LCD填充矩形函数(这里假设是draw_fill_rect)
    lcd.draw_fill_rect(start_x, start_y, end_x, end_y, COLOR_BLACK);
}

第四步:果实的生成与绘制对齐

果实同样用网格坐标生成,确保和蛇身的网格完全对齐:

struct Food {
    int grid_x;
    int grid_y;
};

Food current_food;

// 生成果实:随机选一个网格,且不在蛇身上
void spawn_food() {
    do {
        current_food.grid_x = rand() % SCREEN_GRID_COLS;
        current_food.grid_y = rand() % SCREEN_GRID_ROWS;
    } while (is_food_on_snake(current_food)); // 自己实现判断果实是否在蛇身上的函数
}

// 绘制果实
void draw_food() {
    int start_x = current_food.grid_x * GRID_CELL_SIZE;
    int start_y = current_food.grid_y * GRID_CELL_SIZE;
    int end_x = start_x + GRID_CELL_SIZE - 1;
    int end_y = start_y + GRID_CELL_SIZE - 1;
    
    lcd.draw_fill_rect(start_x, start_y, end_x, end_y, COLOR_RED);
}

额外优化点

  • 碰撞检测简化:现在判断蛇头是否吃到果实,只需要比较蛇头和果实的网格坐标是否相同,不用逐像素判断;蛇身碰撞同理,直接比较网格坐标即可。
  • 移动节奏控制:因为现在是按网格移动,你可以通过控制移动的时间间隔(比如每200ms移动一次)来调整游戏难度,比逐像素移动的速度控制更直观。
  • 随机数初始化:记得在程序开头调用srand(time(NULL))(如果你的平台支持time函数),避免每次生成的果实位置都一样。

这样修改后,蛇身和果实就会完美对齐,再也不会出现错位的问题啦!

内容的提问来源于stack exchange,提问作者Andrea Loriedo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:18:31