news 2026/10/31 16:49:40

用Qt做FlappyBird小游戏:C++课程设计从0到答辩加分

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Qt做FlappyBird小游戏:C++课程设计从0到答辩加分

简介:这是一份基于Qt和C++实现的经典FlappyBird小游戏完整工程源码,面向C++与Qt入门者、高校学生,尤其适合课程设计或图形界面编程实战练习。源码实现了点击屏幕控制小鸟向上飞行、避开障碍物的核心玩法,覆盖游戏循环、碰撞检测、分数统计、资源加载等常见开发环节。压缩包共80个文件,包含47个png游戏素材、12个cpp逻辑实现、11个h头文件、5个ui界面布局文件,以及pro工程配置与qrc资源管理文件;整体体积仅263KB,轻量紧凑,便于直接编译运行和二次修改。工程按Sources、Widgets、Resources等目录划分,方便按模块查阅。目前已有103人学习下载,作为轻量级Qt游戏范例,这份源码能帮助读者理解窗口组件、绘图事件、定时器联动等关键机制,也可为课程设计答辩提供完整参考。

1. 为什么我用 FlappyBird 做 Qt 课程设计,而不是做计算器或贪吃蛇

如果你打开过学校里给的 C++ 课程设计题目清单,大概率会看到计算器、图书管理系统、贪吃蛇这三件套。它们不是不好,而是已经被做了太多年,答辩老师看一眼界面就知道你用了多少功夫。我选 FlappyBird 的原因很简单:它看起来是个小游戏,但 C++ 的面向对象、Qt 的事件循环、绘图坐标系、定时器调度、碰撞检测全部都要用到,代码量控制在 600 到 1000 行之间,一个人一周能写完,又能在答辩时演示“游戏能跑、手感可调、代码能讲”。这个项目非常适合第一次用 Qt 做完整小程序的 C++ 学习者:你不需要懂 QML,不需要碰模型视图框架,只要把 QWidget + QPainter + QTimer 这三板斧吃透,FlappyBird 就能做得像模像样。这篇就按我的实现顺序,从类设计、绘图、碰撞、踩坑到答辩加分,一条线讲完。

2. 先把课程设计的“分数”拿到手:类拆分与 Qt 定时器选型

2.1 为什么用 QTimer 驱动游戏循环,而不是 while 死循环

第一次写游戏的人最容易犯的错,是在 QWidget 里写while (1) { update(); }。在 Qt 里这么写,窗口直接卡死,因为事件循环被死循环堵住,鼠标键盘消息全部排队,QPainter 也没法正常重绘。FlappyBird 这种 60 帧/秒的小游戏,正确驱动方式是QTimer定时触发,在超时回调里更新逻辑坐标,再调用update()请求重绘。

我做这套代码时用的是QTimer+ 单次连接的写法,而不是把定时器对象长期挂在界面上:

// GameWidget.h class GameWidget : public QWidget { Q_OBJECT public: explicit GameWidget(QWidget *parent = nullptr); protected: void paintEvent(QPaintEvent *event) override; void keyPressEvent(QKeyEvent *event) override; void mousePressEvent(QMouseEvent *event) override; private slots: void onTimeout(); private: void startGame(); void stopGame(); void resetGame(); QTimer m_timer; int m_frameInterval = 16; // 约 60 FPS,单位 ms bool m_running = false; double m_birdY = 300.0; // 小鸟左上角 Y 坐标 double m_birdVy = 0.0; // 小鸟垂直速度 double m_gravity = 0.35; // 每帧重力加速度,像素/帧^2 };

m_frameInterval是定时器触发的毫秒间隔。16 毫秒约等于 60 FPS,我一般取 16 而不是 1000 除以 60 的 16.67,因为QTimer的毫秒参数只接受整数,16 和 17 差别不大,但 16 在 Windows 上配合Qt::PreciseTimer更容易稳定触发。m_gravity是每帧的速度增量,单位是“像素/帧²”,配合 60 FPS 时手感合适;如果你把定时器改成 10ms 跑 100 帧,这套数值要重新调,否则小鸟会飘。

在构造函数里启动定时器,但不启动游戏逻辑:

GameWidget::GameWidget(QWidget *parent) : QWidget(parent) { setFocusPolicy(Qt::StrongFocus); setFixedSize(420, 640); m_timer.setInterval(m_frameInterval); m_timer.setTimerType(Qt::PreciseTimer); connect(&m_timer, &QTimer::timeout, this, &GameWidget::onTimeout); m_timer.start(); }

setFocusPolicy(Qt::StrongFocus)保证键盘事件能被窗口收到。很多人在 QWidget 里按空格没反应,就是因为默认的Qt::NoFocus根本不接收键盘输入。setFixedSize锁死窗口尺寸,避免用户拉伸窗口导致背景图片拉伸变形,也省去重写resizeEvent的麻烦。

2.2 把游戏拆成 State 而不是拆成“一堆函数”

课程设计答辩最怕被问“如果加个暂停功能,你怎么改”。如果你把游戏逻辑全写在onTimeout()里,加暂停就得加一堆 if 判断。我习惯用一个枚举状态机来拆分,代码读起来像游戏引擎的思路,答辩时也讲得清楚:

enum class GameState { Ready, // 等待开始,显示标题和操作提示 Playing, // 游戏中 Paused, // 暂停 GameOver // 撞柱子或落地 };

每次状态切换,对应处理进入和退出逻辑。比如进入Ready状态时把小鸟放到固定位置、清空柱子列表;进入Paused时记录当前速度,退出时恢复。QTimer始终在跑,但onTimeout()里先看状态再决定是否执行物理更新和碰撞检测。这个设计把“游戏循环”“用户输入”“绘制”三层解耦,是 Qt 小项目里性价比最高的架构,没有之一。

类拆分上我建议至少四个文件,别把所有代码塞进一个 main.cpp:

文件职责包含内容
main.cpp程序入口创建 QApplication,实例化 GameWidget
GameWidget.h / .cpp窗口与游戏循环状态切换、QTimer 回调、键盘鼠标事件
Bird.h / .cpp小鸟逻辑位置、速度、重力更新、跳跃动作
Pipe.h / .cpp柱子逻辑上下柱坐标、间距、随机高度生成

如果你愿意再拆一层,把Bird和Pipe变成纯 C++ 类,不依赖 QWidget,只暴露update()、getRect()这类接口,这样以后想移植到 QML 或控制台版本都能复用。但课程设计不建议拆太细,四个文件已经足够展示面向对象能力,拆成七八个文件反而显得刻意。

2.3 帧率、重力加速度与跳跃初速度的手感标定

FlappyBird 之所以让人又爱又恨,是因为物理参数直接决定“容错率”。这里给出我调试后觉得手感适中的一组参数:重力加速度 0.35 像素/帧²,跳跃初速度 -6.5 像素/帧(向上为负,注意 Qt 的 Y 轴向下为正),最大下落速度 8 像素/帧。这组参数配合 60 FPS,小鸟从点击到最高点大约上升 110 像素,下落过程不会太突兀。相关热词“C++ 小游戏”的项目里,很多人把这组数值写死成常量,其实应该把它们提到类成员变量,方便答辩现场调参演示。

const double kGravity = 0.35; const double kJumpVelocity = -6.5; const double kMaxFallSpeed = 8.0; const double kPipeSpeed = 3.0; // 柱子向左移动速度像素/帧 const int kPipeSpacing = 160; // 上下柱之间的空隙像素 const int kPipeWidth = 70; // 柱子宽度像素

调参的痛点在于:如果用 60 FPS 固定帧率,kPipeSpeed为 3 时柱子从右到左穿过 420 像素宽的窗口需要约 140 帧,也就是 2.3 秒,玩起来节奏偏快。改成 2.5 会比较休闲。课程设计里建议把“高手模式”和“休闲模式”做成两个预设参数组,这也算一个答辩亮点。

3. 用 QPainter 画一个会动的场景:坐标换算、背景滚动与小鸟帧动画

3.1 先定画布坐标系,再写绘制代码,别边画边想

Qt 的绘图坐标系是左上角为原点,X 向右,Y 向下。很多从数学坐标系转过来的人第一张图是上下颠倒的。FlappyBird 里所有物体坐标我都用“左上角 + 宽高”的QRectF来描述,而不是用中心点。这样做碰撞检测直接调QRectF::intersects(),省去自己写矩形相交判断的麻烦。

QRectF birdRect = QRectF(birdX, m_birdY, kBirdWidth, kBirdHeight);

背景滚动的实现原理非常简单:用一个m_backgroundOffset变量记录背景纹理的偏移量,每帧渲染时先画一个超出窗口右侧的背景块,再画一个与之相邻的块,两块之间用拼接图样无缝衔接。但如果你不想找素材,可以用纯色渐变 + 几条白色虚线模拟云朵,效果也够看。我课程设计时用的就是一张 420x640 的 PNG 背景图,程序启动时加载一次,绘制时按偏移量分两次画:

void GameWidget::drawBackground(QPainter &painter) { m_backgroundOffset -= kPipeSpeed; if (m_backgroundOffset <= -m_background.width()) { m_backgroundOffset += m_background.width(); } painter.drawImage(QPoint(m_backgroundOffset, 0), m_background); painter.drawImage(QPoint(m_backgroundOffset + m_background.width(), 0), m_background); }

这里有个细节:当偏移量小于负的背景宽度时,取模回退。因为背景图宽度和窗口宽度相等,所以两张图刚好覆盖整个窗口,滚动看起来是无缝的。如果你用的是比窗口宽的背景图,取模的基准要换成背景图宽度。

QPainter 绘制时建议开启抗锯齿,否则小鸟边缘会像锯齿一样难看:

painter.setRenderHint(QPainter::Antialiasing, true);

3.2 生成柱子:随机高度背后的“可玩性数学”

柱子的随机不能纯随机。如果上下柱之间空隙只有 160 像素,而柱子最大高度 500 像素、最小高度 80 像素,纯随机会出现连续两三根高柱或低柱,玩家根本没法玩。FlappyBird 的精髓在于“随机但留有余地”。我的做法是维护一个上一根柱子的中心位置,新柱子的中心在旧中心附近 ±60 像素范围内变化:

int newCenterY = qBound(kPipeMinCenterY, m_lastPipeCenterY + QRandomGenerator::global()->bias(-60, 61), kPipeMaxCenterY);

qBound是 Qt 的裁剪函数,保证随机结果落在上下界之间。这样生成的柱子序列既不会出现极端跳跃,又能让每局地形不同。如果你想要更简单的实现,也可以把中心位置固定在上一次的 ±40 像素内,配合空隙 160 像素,基本不会生成死局。

每一次新柱子生成时,把它推入一个QVector<Pipe>,并且记录它是否已经计过分。柱子到达窗口左边界外时从容器里移除,避免容器无限增长。这个容器管理是 FlappyBird 的核心逻辑之一,建议在课程设计文档里单独画一张数据流图。

struct Pipe { int x; // 柱子左上角 X int centerY; // 上下柱空隙的中心 Y int width; int gapHeight; bool scored; };

判定“柱子是否生成”不需要按时间,而是按距离。当最后一根柱子的 X 坐标小于窗口宽度减kPipeSpacing(柱子间距)时,就生成下一根。这样不管柱子速度怎么调,间距始终是 200 像素左右,逻辑上更稳。

3.3 小鸟的“扑腾”动画和旋转,用帧计数解决

FlappyBird 的小鸟如果不做动画,就是一坨静止的黄色圆球,观感差很多。我的做法是准备三帧翅膀姿态图片(上、中、下),用一个m_wingFrame变量在 0、1、2 之间循环,每 5 帧切换一次。加上小鸟上升时抬头、下降时低头,手感反馈非常直观。

void GameWidget::updateBirdPose() { if (m_birdVy < -1.0) { m_birdAngle = -20; // 快速上升时抬头 } else if (m_birdVy > 1.0) { m_birdAngle = 40; // 下落时低头 } else { m_birdAngle = 0; } }

绘制时用painter.translate()到小鸟中心,旋转坐标轴,再画图片,最后restore():

painter.save(); painter.translate(birdCenterX, birdCenterY); painter.rotate(m_birdAngle); painter.drawImage(QRectF(-kBirdWidth/2, -kBirdHeight/2, kBirdWidth, kBirdHeight), birdImage); painter.restore();

旋转的坑点在于translate必须在rotate之前,否则是绕窗口原点旋转,小鸟会飞出屏幕。另外QPainter::save/restore要成对出现,漏掉restore会让后续绘制全部带着旋转状态,画出来的柱子都是歪的。

4. 撞柱子才叫 FlappyBird:矩形相交判定、落地检测与计分逻辑

4.1 用 QRectF::intersects 替代手写碰撞公式

碰撞检测如果用“圆心到矩形距离”那套,代码长而且容易出边界 bug。Qt 的QRectF已经提供了相交检测,直接用它就好。我维护的是一根柱子由上下两个矩形组成:上柱是“从窗口顶部到 gap 上边缘”,下柱是“从 gap 下边缘到窗口底部”。

QRectF upperRect = QRectF(pipe.x, 0, pipe.width, pipe.centerY - pipe.gapHeight / 2.0); QRectF lowerRect = QRectF(pipe.x, pipe.centerY + pipe.gapHeight / 2.0, pipe.width, m_windowHeight - (pipe.centerY + pipe.gapHeight / 2.0));

碰撞判断只需要三行:

QRectF birdBox = QRectF(m_birdX, m_birdY, kBirdWidth, kBirdHeight); if (birdBox.intersects(upperRect) || birdBox.intersects(lowerRect)) { setGameState(GameState::GameOver); }

这里有个性能小优化:QRectF::intersects在 Qt 5.15 里是内联的,性能足够。课程设计里不需要自己写 AABB 碰撞,但你要能讲清楚“为什么矩形碰撞检测是最高效的”——因为两个矩形不相交只需比较四条边,时间复杂度 O(1)。答辩老师问到这里,你能答上来就是加分项。

4.2 落地判定:比柱子碰撞更隐蔽的坑

柱子碰撞大家都会写,但落地判定经常被忽略。FlappyBird 如果只撞柱子不落地,小鸟会飞出屏幕底部然后消失,画面很难看。落地检测本质是判断小鸟底部是否超过地面高度:

const int kGroundHeight = 80; // 底部地面占窗口高度 if (m_birdY + kBirdHeight >= m_windowHeight - kGroundHeight) { m_birdY = m_windowHeight - kGroundHeight - kBirdHeight; setGameState(GameState::GameOver); }

注意落地瞬间要先停止小鸟下落,把 Y 坐标钳制到地面高度之上,否则画面会闪一帧穿模。这个“先钳制再结算”的顺序是我踩过坑的地方:先结算状态再钳制,会导致 GameOver 画面里小鸟陷进地面一半。

4.3 计分逻辑:什么时候算“过柱子”

计分有三种常见实现:碰到柱子中心线就加 1、飞出柱子右边界加 1、柱子完全通过小鸟左边界加 1。第三种手感最准,玩家看到的是“柱子过去了才加分”,不会出现“还没撞到就加分”的错觉。我用的是柱子右边缘小于小鸟左边缘时加分:

for (auto &pipe : m_pipes) { if (!pipe.scored && pipe.x + pipe.width < m_birdX) { pipe.scored = true; m_score++; } }

加分时做一个简单的音效反馈,QApplication::beep() 在 Windows 上能用,但声音很单调。如果你引入了 QMediaPlayer,就可以播鸟叫音效。但课程设计不建议在声音上花太多时间,答辩现场没音箱会很尴尬。计分变量用 int,刷新时在左上角用 QPainter::drawText 绘制:

painter.setPen(Qt::white); QFont font = painter.font(); font.setPixelSize(32); font.setBold(true); painter.setFont(font); painter.drawText(QRect(0, 20, m_windowWidth, 40), Qt::AlignCenter, QString::number(m_score));

4.4 用 QElapsedTimer 做“真实帧间隔”,解决不同电脑手感差异

这是一个进阶优化,但不难。QTimer的 16ms 间隔在 Windows 上实际触发可能是 15ms 到 20ms 波动。如果游戏逻辑按“每帧移动 3 像素”固定算,帧率波动时游戏速度会忽快忽慢。解决办法是用QElapsedTimer记录真实时间差,把速度因子换算成“像素/毫秒”。

qint64 elapsedMs = m_frameTimer.elapsed(); m_frameTimer.restart(); double factor = elapsedMs / 16.0; m_pipeOffset -= kPipeSpeed * factor;

这套换算在课程设计里属于亮点,但实现复杂度会增加不少。如果你时间不够,直接在答辩 PPT 里提一句“我用 60 FPS 固定帧率,所以逻辑和渲染在同一线程”,老师一般不会深究。

5. 代码写完了先别交:Qt 5.15.2 + MSVC2019 环境下最常翻车的 5 个坑

5.1 编译报错:-1: error: dependent '..\..\..\..\..\..\qt\5.15.2\msvc2019_64\include\qtwidgets...,项目根本起不来

现象:新建 Qt Widgets Application 后,一编译就报一个超长路径的 dependent 错误,指向 Qt 安装目录的 include 文件,和你的代码毫无关系。

原因:这是 Qt 5.15.2 在 Windows 上搭配 MSVC2019 时,qmake生成的 Makefile 里写死了相对路径。常见触发条件是项目的构建目录(build 目录)和 Qt 安装目录不在同一个盘符,或者路径里有中文。..\..\..\..\..\..这个相对路径一直回溯到根目录再进 Qt include,一旦盘符不对直接失效。

解决:把项目路径放到纯英文且浅层目录,例如D:\qt_work\FlappyBird,构建目录用 Qt Creator 默认的 shadow build(在项目文件夹下的 build- 目录)。别把项目放在C:\Users\张三\桌面\Qt项目这种路径里,中文用户名和空格都会让 qmake 的路径解析出幺蛾子。如果还报错,就手动删除整个 build 目录,重新用 qmake 构建,别点“清理项目”,直接删文件夹最干净。

5.2 鼠标点击没反应,键盘按空格也没反应

现象:窗口能显示,柱子能滚,但点鼠标小鸟不跳,按空格也没反应。

原因:事件根本没传到 GameWidget。如果你创建 GameWidget 时用了布局或者把 GameWidget 设置为某个 QMainWindow 的 centralWidget,按键焦点可能被其他控件抢走。另外构造函数里没调用setFocusPolicy的话,QWidget 默认不接收键盘事件。

解决:构造函数里加setFocusPolicy(Qt::StrongFocus),并在鼠标点击事件里先setFocus()再处理跳跃。如果你是在 QMainWindow 里嵌入 GameWidget,要确保 GameWidget 能拿到焦点,最简单的办法是在窗口 show 之后主动gameWidget->setFocus()。这个坑我在课设互评时见过至少三个人踩。

5.3 QTimer 槽函数里 update() 频繁调用导致 CPU 占用 30% 以上

现象:游戏在 Debug 模式下 CPU 占用非常高,笔记本风扇狂转。

原因:QTimer 每 16ms 触发一次重绘,而 QWidget 的 paintEvent 里如果做了loadImage或者drawImage大图,每次重绘都要重新缩放图片,开销巨大。我把背景 PNG 在构造函数里加载成 QImage 缓存,paintEvent 里只 drawImage,不加载,CPU 占用立刻降下来。

解决:所有图片资源在构造函数或第一次 paintEvent 前加载完,paintEvent 只负责绘制不能做 IO。还有一个优化是只对场景变化区域重绘,但update()全窗口重绘在 420x640 的小窗口上完全够用,不用做区域裁剪。

5.4 Debug 模式正常,Release 模式一运行就闪退

现象:Debug 下游戏一切正常,切到 Release 编译,运行几秒后直接崩溃,没有任何提示。

原因:最常见的是未初始化的成员变量。Debug 模式下编译器会把未初始化内存填成 0,运气好不崩;Release 模式下内存里是随机值,比如m_birdY初始值如果是垃圾值,小鸟一开始就在碰撞状态,碰撞后访问空指针或者数组越界直接崩。另一个常被忽略的问题:QRandomGenerator::global()在多线程环境或 Release 优化下返回值异常。

解决:所有成员变量必须在构造函数初始化列表里赋初值,不要指望默认值。我第一次写 FlappyBird 时m_pipes容器忘了 clear,Debug 没事,Release 崩得莫名其妙。建议在构造函数里把所有数值型成员列成一张清单逐一初始化。

5.5 【Qt 5.15.2 专属】高 DPI 缩放下画面模糊,文字发虚

现象:在 Windows 屏幕缩放 150% 的机器上运行,整个窗口模糊,文字像蒙了一层雾。

原因:Qt 5.15 默认启用高 DPI 缩放,但你的程序没告诉系统自己支持缩放,Windows 就用位图拉伸兼容模式。解决是在 main.cpp 最前面设置QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);并在创建 QApplication 之前设置环境变量Qt::AA_EnableHighDpiScaling:

int main(int argc, char *argv[]) { QApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true); QApplication app(argc, argv); ... }

如果你的电脑是 1080P 100% 缩放,这个坑遇不到,但答辩现场的投影电脑很可能开了 125% 缩放,提前处理能省得当场翻车。相关热搜词里“qt崩溃”“qt界面设计”都有很多这个问题的讨论,属于 Qt 老用户都懂的玄学坑。

6. 从能运行到能答辩:状态机扩展、换肤与打包发布技巧

到这里,你的 FlappyBird 已经能玩、能计分、能死、能重开,但这只是“能运行”。课程设计得高分的关键是“能讲”。我建议按下面三条线打磨,每一条都对应一个答辩老师喜欢问的点。

第一是状态机可见化。在Ready状态画“点击屏幕开始”,在Paused状态画“暂停中”,在GameOver状态画“本次得分 XX 分,按 R 重开”。这个需求在代码里只需要一个switch分支,但展示效果好到出乎意料。答辩时老师可能问“你用了什么设计模式”,你回答“状态模式,枚举驱动状态切换”,就能解释清楚。

第二是一套换肤机制。把背景图片、小鸟图片、柱子颜色从代码里抽成资源路径,用一个简单的setTheme(QString themeName)函数切换。我课设时做了“经典白天”和“暗夜荧光”两套皮肤,只改三张图片和两个颜色常量。这个改动看着小,但能展示你对“数据和逻辑分离”的理解,比多写两百行业务代码更值钱。

第三是发布打包。Qt 5.15.2 在 Release 模式下构建完,生成的 exe 双击会提示缺少Qt5Widgets.dll和Qt5Core.dll。教学机器上装了 Qt 没事,但答辩教室不一定装。用windeployqt FlappyBird.exe命令自动把依赖 DLL 拷到 exe 同目录,是最省事的方案:

D:\Qt\5.15.2\msvc2019_64\bin\windeployqt.exe D:\build-FlappyBird\release\FlappyBird.exe

运行完之后,把整个 release 文件夹压缩成一个 ZIP 交作业,里面一定要带说明.txt,写清楚运行环境(Windows 10/11 64 位,需要 VC++ 运行库)和你用的 Qt 版本。我当年就在这栽过:打包的 exe 在老师电脑上运行失败,原因是缺vcruntime140.dll,后来装了Microsoft Visual C++ Redistributable才解决。答辩前一定要找一台没装 Qt 的干净电脑测试 exe 能不能跑,这一步比优化代码值钱得多。

最后说一个我的血泪经验:答辩演示前把窗口尺寸固定好,别让老师看到拉伸窗口后柱子间距变形的样子。setFixedSize虽然在第三章写了,但很多人会为了“能弹窗口”而改成resize,结果布局一乱,前面讲的架构再好也白搭。代码提交前再通读一遍,把“调试用”的qDebug()输出全部注释掉,尤其是每帧刷新坐标的调试信息,否则答辩时控制台疯狂刷屏,印象分会大打折扣。希望这些踩坑经验能帮你的 FlappyBird 课程设计少走弯路,把时间省下来琢磨游戏手感和你真正感兴趣的部分——Qt 的世界比这个小鸟和柱子大得多。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/31 16:49:30

生产级Agent三层架构:Harness、Loop与Graph实战解析

做 Agent 工程这两年&#xff0c;我最大的感受是&#xff1a;跑通一个 Demo 很容易&#xff0c;写一个能在生产环境扛住真实流量的 Agent 很难。难在"Agent"这三个字母背后藏着一堆没人替你分担的工程问题——工具怎么接、权限怎么控、循环怎么停、流程怎么排、出错了…

作者头像 李华
网站建设 2026/10/31 16:49:28

AI编码工具集体宕机后的容灾改造:Agent工作流如何应对API故障

那个周二早晨&#xff0c;我的 Agent 工作流差点断粮&#xff1a;Claude 的 API 开始间歇性返回 503&#xff0c;Codex 的会话在十几秒内全部过期&#xff0c;Grok 那边的 bot 任务也接二连三超时。本来半小时能跑完的编码 Agent 流水线&#xff0c;硬是变成了我在终端里反复重…

作者头像 李华
网站建设 2026/10/14 21:22:26

我的世界RPG服务器六年运营实战:从魂环机制到高效运维

六年前的寒假&#xff0c;我蹲在电脑前&#xff0c;把最后一道魂环特效绑进技能循环里。那是这款我的世界RPG服务器“猎马斗罗”的第一个版本&#xff0c;当时只有十几个朋友在临时开出来的测试服里打打闹闹。我完全没想过&#xff0c;它后来会以一个斗罗、斗破世界观为背景的原…

作者头像 李华
网站建设 2026/10/26 20:29:13

JavaWeb留言板实战:Eclipse+Tomcat+MySQL零配置落地指南

简介&#xff1a;这是一份面向高校计算机类专业学生&#xff08;如计科、人工智能、通信工程等&#xff09;的JavaWeb课程设计实战资源&#xff0c;聚焦留言板系统开发&#xff0c;适用于期末大作业、课程设计、毕设参考及初学者项目实践。资源包含完整可运行的Eclipse工程&…

作者头像 李华
网站建设 2026/10/14 23:22:11

校园点餐管理系统源代码:从跑通到上线的核心链路与避坑指南

简介&#xff1a;这是一套面向高校场景的校园点餐管理系统源代码&#xff0c;适合学习 Java Web 开发的学生与开发者作为课程设计或实战练手项目。系统基于 Java、Spring、Spring MVC、MyBatis 与 Tomcat 构建&#xff0c;配合 Maven 管理依赖&#xff0c;覆盖用户注册登录、菜…

作者头像 李华
网站建设 2026/10/17 12:17:01

汽车数字模型重拓扑实战:P6级机盖拓扑标准解析

1. 项目概述&#xff1a;这不是修图&#xff0c;是给汽车数字模型“做骨科手术”“拓车工坊”这四个字一出来&#xff0c;老司机和建模圈的人心里就都有数了——这不是教你怎么调色、怎么贴图的美工课&#xff0c;而是直奔汽车数字模型底层结构去的硬核训练。标题里那个“重拓扑…

作者头像 李华