应使用std::vector存储蛇身坐标而非硬编码数组,因其动态扩容更安全;移动时先push_back新头再按需pop_back尾部;碰撞检测需跳过头部自身;方向控制须校验反向非法转向;帧率用时间补偿法而非固定sleep;边界检测需包含等于边界的死亡条件。

用 std::vector 存蛇身比数组更安全
硬编码数组大小容易越界,比如蛇长超过预设值就直接崩;std::vector 动态扩容,插入删除也直观。别用 int snake_x[100] 和 int snake_y[100] 这种双数组模拟——多一维就难维护,而且长度不同步风险高。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 用
std::vector<:pair int>></:pair>存每节坐标,头在front(),尾在back() - 移动时先
push_back()新头,再根据是否吃到食物决定是否pop_back() - 判断碰撞:检查新头坐标是否与自身其他节重合,用
std::find或循环遍历begin()+1到end()(跳过头部自己)
方向控制别直接改 dx/dy,要过滤反向操作
用户按左键后立刻按右键,蛇会原地翻转撞自己——这不是输入快,是逻辑没拦住非法转向。方向变量(如 dx, dy)必须和当前朝向做校验。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 只允许转向 90°:若当前
dx == 0,则新方向只能是dx = ±1, dy = 0;若当前dy == 0,则新方向只能是dx = 0, dy = ±1 - 用
if链或switch拦住反向:比如当前向右(dx==1),就拒绝dx==-1的输入 - 键盘响应建议用非阻塞方式(如
GetAsyncKeyStateon Windows 或poll+stdinon Linux),避免卡顿导致连按失效
sleep_for 控制帧率时,别把延时写死在循环里
固定 std::this_thread::sleep_for(100ms) 看似简单,但游戏逻辑耗时波动大(比如渲染、IO),会导致整体节奏忽快忽慢,甚至累积延迟。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 用“帧时间补偿”:记录上一帧开始时间,每帧开头算出已过时间,再用
sleep_for(target_frame_time - elapsed) - 加个下限保护,比如
sleep_for(std::max(1ms, target - elapsed)),防止负数或空转 - 目标帧率设 10 FPS 就够练手(
100ms),太高反而难看清蛇的移动步进
边界检测必须包含“贴边即死”,别漏掉坐标等于边界值的情况
常见错误是写成 if (x > width || y > height),结果蛇头坐标刚等于 width 就穿模出去了——因为坐标通常从 0 开始,合法范围是 [0, width-1] 和 [0, height-1]。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 明确画布尺寸定义:比如终端宽 80 列、高 24 行,则合法
x是0 ,<code>y同理 - 碰撞检查放在移动后、绘制前:先算新头坐标,再判断是否越界或撞身,成立就结束游戏
- 别依赖清屏掩盖问题:有些实现靠快速刷新“看起来没穿墙”,实际逻辑漏洞还在
最易被忽略的是:蛇身坐标更新顺序和碰撞检测时机不一致,比如先删尾再加头,就会漏检头尾重叠(刚吃食物时长度+1,但旧尾还没删,新头可能正好落在旧尾位置)。这个点不画图推一遍很容易绕晕。











