C++与EasyX坦克大战游戏源码实战:从窗口初始化到敌人AI
简介这是一份面向C初学者与游戏开发爱好者的坦克大战游戏源码基于C语言与easyX图形库实现适合用来练习Windows平台图形编程、理解游戏循环与模块化设计。压缩包共29个文件约692KB包含5个cpp源文件与5个头文件构成核心逻辑7个png与7个jpg图片用于坦克、地图与界面素材2个wav音频提供音效另有vcxproj项目文件、filters过滤器及readme说明可直接用Visual Studio打开编译运行。项目按坦克、子弹、地图、菜单等模块拆分便于阅读与二次扩展已有293人学习下载。读者可从中掌握事件处理、碰撞检测、资源加载与音效播放等关键环节并借鉴其目录组织方式作为课程设计或自学练手项目都较为合适。1. 从一张贴图到可玩关卡C 与 EasyX 做坦克大战到底在做什么很多人第一次听到「基于 C 和 EasyX 引擎的坦克大战游戏设计源码」脑子里浮现的是小时候红白机那个双人对战画面但真正动手时卡住的地方往往不是游戏逻辑而是「窗口怎么开、图怎么贴、键怎么读」。EasyX 是 Windows 平台上一套轻量的 C 图形库它把 GDI 那套繁琐的绘图接口封装成initgraph、loadimage、putimage这类直白函数配合 Visual Studio 或 Dev-C 就能在半小时内让一个方块动起来。坦克大战这个题材恰好覆盖了游戏开发最核心的几件事实时输入、帧循环、碰撞检测、地图数据、状态机。它不像贪吃蛇那样简单到没有架构也不像 3D 引擎那样一上来就被数学劝退是 C 入门到小游戏实战之间最合适的练手项目。这篇笔记面向的是想拿一份能跑、能改、能扩展的坦克大战源码的 C 学习者以及需要课程设计案例的在校同学我会把窗口初始化、地图表示、坦克移动、子弹与碰撞、关卡数据这几条主线拆开讲清楚参数怎么设、哪里容易翻车都写明白。2. 环境搭建与 EasyX 最小可运行框架先让窗口活起来2.1 为什么选 EasyX 而不是 SDL 或 Qt选型这件事得先讲清楚否则后面踩坑会怀疑人生。EasyX 的本质是对 Windows GDI 的 C 封装它的优势是零依赖、头文件加库文件丢进工程就能用绘图 API 是同步阻塞式的putimage调用完图就已经在屏幕上了不需要理解渲染管线、双缓冲交换、事件队列这些概念。对于坦克大战这种 2D、像素级、帧率要求不高的项目EasyX 的开发效率远高于 SDL。代价是它只支持 Windows且没有硬件加速画面元素上千后会有明显掉帧。如果你的目标是课程设计或者个人练手EasyX 完全够用如果要做跨平台或者商业级 2D 游戏SDL2 或 raylib 更合适。这里锁定 EasyX因为标题里的技术栈就是它。环境上最常见的组合是 Visual Studio 2019/2022 社区版加 EasyX 官方安装包安装程序会自动把graphics.h、easyx.h和对应的 lib 文件放进 VS 的 include 与 lib 目录。如果你用 VS Code需要手动配置c_cpp_properties.json里的 includePath 和 tasks.json 里的链接参数这一步是新手翻车高发区后面避坑章节会细说。Dev-C 也能用但它的编译器版本较老对 C11 以上特性支持不完整不建议。2.2 一个能编译能出画面的最小骨架先别急着写坦克把最小骨架跑通确认环境没问题再往上堆逻辑。下面这段代码创建 640x480 的窗口加载一张背景图并进入消息循环按 ESC 退出。#include graphics.h #include conio.h int main() { // 创建 640x480 的窗口第三个参数不加就是无边框 initgraph(640, 480); // 设置背景色为黑色清屏一次 setbkcolor(BLACK); cleardevice(); // 开启批量绘图减少闪烁这是 EasyX 双缓冲的关键 BeginBatchDraw(); while (true) { // 处理 Windows 消息防止窗口无响应 ExMessage msg; while (peekmessage(msg, EX_KEY)) { if (msg.message WM_KEYDOWN msg.vkcode VK_ESCAPE) { EndBatchDraw(); closegraph(); return 0; } } // 这里后续放游戏逻辑与绘制 cleardevice(); setfillcolor(GREEN); fillrectangle(100, 100, 140, 140); // 先画个方块占位 FlushBatchDraw(); // 把这一帧真正刷到屏幕 Sleep(16); // 约 60 帧每秒 } }逻辑说明initgraph负责创建窗口和设备上下文BeginBatchDraw与FlushBatchDraw配对使用所有绘制先画在内存 DC 上最后一次性提交这是消除画面闪烁的标准做法。peekmessage是非阻塞取消息只取键盘事件避免鼠标移动消息把队列塞满。Sleep(16)控制帧间隔16 毫秒约等于 60 FPS这个值直接决定游戏手感后面调参还会提到。参数说明initgraph的宽高建议用 640x480 或 800x600坦克大战的经典地图是 13x13 格每格 32 或 48 像素640 宽刚好放 13 个 48 像素格加边距。Sleep的值不要低于 10否则 CPU 占用飙升也不要高于 33否则移动会有明显拖影。peekmessage的第二个参数用EX_KEY只过滤键盘消息如果你要加鼠标点击菜单改成EX_MOUSE | EX_KEY。提示如果你的 VS 报「无法打开 graphics.h」九成是 EasyX 没装到当前 VS 版本对应的目录重装时注意勾选正确的 VS 版本。3. 地图数据与坦克移动把格子、坐标和按键串起来3.1 用二维数组表示地图别用像素硬编码坦克大战的地图本质是一张网格墙、草地、河流、基地各占一格。最忌讳的做法是把每个障碍物的像素坐标一个个写死那样改地图等于重写代码。正确做法是用二维整型数组存地图每个数字代表一种地形绘制和碰撞都查这张表。// 0 空地 1 砖墙 2 钢墙 3 草地 4 河流 5 基地 const int MAP_W 13; const int MAP_H 13; const int TILE 48; // 每格 48 像素 int map[MAP_H][MAP_W] { {2,2,2,2,2,2,2,2,2,2,2,2,2}, {2,0,0,0,0,0,0,0,0,0,0,0,2}, {2,0,1,1,0,0,0,0,0,1,1,0,2}, {2,0,1,0,0,0,0,0,0,0,1,0,2}, {2,0,0,0,0,3,3,3,0,0,0,0,2}, {2,0,0,0,0,3,5,3,0,0,0,0,2}, {2,0,0,0,0,3,3,3,0,0,0,0,2}, {2,0,1,0,0,0,0,0,0,0,1,0,2}, {2,0,1,1,0,0,0,0,0,1,1,0,2}, {2,0,0,0,0,0,0,0,0,0,0,0,2}, {2,0,0,0,0,0,0,0,0,0,0,0,2}, {2,0,0,0,0,0,0,0,0,0,0,0,2}, {2,2,2,2,2,2,2,2,2,2,2,2,2} }; // 把格子坐标转成屏幕像素坐标 inline int ToPixelX(int col) { return col * TILE; } inline int ToPixelY(int row) { return row * TILE; }逻辑说明地图数组的每个元素对应一个格子绘制时双重循环遍历根据数值选颜色或贴图。碰撞检测时把坦克的像素坐标除以TILE得到格子坐标查数组判断能不能走。这种「逻辑格子 像素渲染」的分离是 2D 游戏的标准架构改地图只动数组不动渲染代码。参数说明TILE取 48 是因为 640/13 约等于 49取 48 留出边距如果你用 800x600 窗口TILE可以取 60。地图数组的边界建议全填钢墙省得写越界判断。基地那格用 5 标记游戏结束条件就是这格被子弹打中。3.2 坦克移动按键状态、方向与格子对齐坦克移动最容易翻车的地方是「按住方向键只动一格就停」或者「斜着穿墙」。根因是没有区分「按键按下」和「按键持续按住」以及没有做移动前的碰撞预判。EasyX 里用GetAsyncKeyState可以拿到按键的实时状态比消息循环更适合做持续移动。struct Tank { int x, y; // 像素坐标左上角 int dir; // 0 上 1 右 2 下 3 左 int speed; // 每帧移动像素 bool alive; }; // 判断某个像素矩形是否与障碍物重叠 bool CanMoveTo(int px, int py, int size) { int left px / TILE; int right (px size - 1) / TILE; int top py / TILE; int bottom (py size - 1) / TILE; for (int r top; r bottom; r) for (int c left; c right; c) { if (r 0 || r MAP_H || c 0 || c MAP_W) return false; if (map[r][c] 1 || map[r][c] 2 || map[r][c] 4) return false; } return true; } void UpdateTank(Tank t) { int nx t.x, ny t.y; if (GetAsyncKeyState(VK_UP) 0x8000) { t.dir 0; ny - t.speed; } if (GetAsyncKeyState(VK_RIGHT) 0x8000) { t.dir 1; nx t.speed; } if (GetAsyncKeyState(VK_DOWN) 0x8000) { t.dir 2; ny t.speed; } if (GetAsyncKeyState(VK_LEFT) 0x8000) { t.dir 3; nx - t.speed; } if (CanMoveTo(nx, ny, TILE)) { t.x nx; t.y ny; } }逻辑说明GetAsyncKeyState返回值的最高位为 1 表示当前按下 0x8000就是取这一位。每次移动前先算出目标坐标用CanMoveTo检查目标矩形覆盖的所有格子是否可通行全部可通行才真正赋值。这样坦克永远不会穿墙也不会卡进障碍物里出不来。参数说明speed建议取 2 到 4 像素每帧取 1 太慢取 8 会直接穿过一格导致碰撞检测失效。坦克尺寸用TILE即 48 像素和格子对齐这样CanMoveTo的边界计算最简单。如果你想让坦克比格子小一点比如 40 像素留出视觉间隙CanMoveTo的 size 参数传 40 即可但要注意居中偏移。注意GetAsyncKeyState在窗口失焦时依然会返回按键状态正式项目里应该先判断窗口是否激活否则切出去按方向键坦克还在动。4. 子弹、碰撞与敌人 AI让游戏真正跑起来4.1 子弹的生成、飞行与销毁子弹逻辑看着简单但它是内存泄漏和性能问题的重灾区。常见错误是用new动态创建子弹却忘了delete或者子弹飞出屏幕后还在数组里占位。稳妥做法是用固定大小的数组加alive标记复用槽位。struct Bullet { int x, y; int dir; int speed; bool alive; bool fromPlayer; }; const int MAX_BULLETS 64; Bullet bullets[MAX_BULLETS]; void FireBullet(Tank t, bool fromPlayer) { for (int i 0; i MAX_BULLETS; i) { if (!bullets[i].alive) { bullets[i].alive true; bullets[i].fromPlayer fromPlayer; bullets[i].dir t.dir; bullets[i].speed 8; // 从坦克中心发出 bullets[i].x t.x TILE / 2 - 4; bullets[i].y t.y TILE / 2 - 4; return; } } } void UpdateBullets() { for (int i 0; i MAX_BULLETS; i) { if (!bullets[i].alive) continue; if (bullets[i].dir 0) bullets[i].y - bullets[i].speed; if (bullets[i].dir 1) bullets[i].x bullets[i].speed; if (bullets[i].dir 2) bullets[i].y bullets[i].speed; if (bullets[i].dir 3) bullets[i].x - bullets[i].speed; // 出界销毁 if (bullets[i].x 0 || bullets[i].x 640 || bullets[i].y 0 || bullets[i].y 480) { bullets[i].alive false; continue; } // 撞墙检测 int col (bullets[i].x 4) / TILE; int row (bullets[i].y 4) / TILE; if (row 0 row MAP_H col 0 col MAP_W) { if (map[row][col] 1) { map[row][col] 0; bullets[i].alive false; } else if (map[row][col] 2) { bullets[i].alive false; } else if (map[row][col] 5) { /* 基地被毁游戏结束 */ } } } }逻辑说明FireBullet遍历子弹池找空槽找不到就丢弃这次开火避免无限增长。UpdateBullets每帧更新位置出界或撞墙就置alive false槽位自动回收。砖墙被打中变成空地钢墙只销毁子弹不改变地形这是坦克大战的经典规则。参数说明MAX_BULLETS取 64 对单人关卡绰绰有余双人加敌人同屏一般不超过 20 发。子弹速度取 8 比坦克的 2 到 4 快一倍以上手感才对。子弹尺寸这里用 8x8检测时加 4 是取中心点如果你把子弹画成 6x6偏移量要相应改成 3。4.2 敌人 AI别一上来就写寻路敌人 AI 是很多人卡住的地方一上来就想写 A* 寻路结果代码量爆炸还跑不通。坦克大战的敌人行为其实很简单随机选一个方向走撞墙或走到路口时按一定概率换方向看到玩家或基地在正前方就开火。用状态机加随机数就够了。#include cstdlib struct Enemy { Tank tank; int moveTimer; // 还有多少帧换方向 int fireCooldown; }; void UpdateEnemy(Enemy e) { if (!e.tank.alive) return; // 计时到了就随机换方向 if (--e.moveTimer 0) { e.tank.dir rand() % 4; e.moveTimer 30 rand() % 60; // 0.5 到 1.5 秒 } int nx e.tank.x, ny e.tank.y; if (e.tank.dir 0) ny - e.tank.speed; if (e.tank.dir 1) nx e.tank.speed; if (e.tank.dir 2) ny e.tank.speed; if (e.tank.dir 3) nx - e.tank.speed; // 走不通就立刻换方向不等计时器 if (CanMoveTo(nx, ny, TILE)) { e.tank.x nx; e.tank.y ny; } else { e.moveTimer 0; } // 冷却好了就开火 if (--e.fireCooldown 0) { FireBullet(e.tank, false); e.fireCooldown 60 rand() % 60; } }逻辑说明moveTimer控制换方向频率撞墙时直接清零让它下一帧就换避免卡在墙角抖动。开火用独立的冷却计时器和移动解耦。rand()需要先srand(time(nullptr))播种否则每次运行行为完全一样。参数说明moveTimer初始值 30 到 90 帧对应 0.5 到 1.5 秒太短敌人像无头苍蝇太长显得呆滞。fireCooldown取 60 到 120 帧即 1 到 2 秒一发比玩家慢给玩家反应时间。敌人速度建议比玩家慢 1 像素取 1 到 2。提示rand()的随机性对游戏来说够用但如果你要做回放或联机同步得换成带种子的确定性随机否则两边行为对不上。5. 避坑与排查EasyX 坦克大战最常见的五个翻车点5.1 画面疯狂闪烁方块像在抽搐现象坦克和子弹移动时整个画面一闪一闪眼睛受不了。原因没有用BeginBatchDraw/FlushBatchDraw每次putimage或fillrectangle都直接写显存绘制过程中屏幕被刷新了多次。解决在initgraph之后立刻调用BeginBatchDraw()所有绘制完成后调用FlushBatchDraw()退出前EndBatchDraw()。注意cleardevice要放在批量绘制内部不能放在FlushBatchDraw之后。5.2 按键没反应或者按一下动十格现象方向键按了坦克不动或者轻轻一按冲出去老远。原因用了getch()这类阻塞函数或者把GetAsyncKeyState的返回值直接当布尔用而没取0x8000位。解决持续移动一律用GetAsyncKeyState(VK_XX) 0x8000单次触发比如发射子弹才用消息循环里的WM_KEYDOWN。另外检查窗口是否获得焦点失焦时GetAsyncKeyState仍返回按下状态。5.3 坦克卡在墙角来回抖动现象坦克贴着墙走时左右横跳或者卡在两块砖之间出不来。原因碰撞检测只判断了目标点没有判断坦克整个矩形覆盖的所有格子导致部分嵌入墙体后无法脱出。解决CanMoveTo必须用坦克的左上角和右下角算出覆盖的格子范围逐格检查。坦克尺寸和TILE对齐能大幅减少这类问题如果坦克比格子小要保证居中偏移量在计算时被正确加上。5.4 子弹打中砖墙但墙不消失现象子弹碰到砖墙就没了墙还在。原因子弹的碰撞检测用的是子弹中心点所在格子但子弹速度是 8一帧跨过了 8 像素可能直接跳过了薄墙所在的格子。解决子弹速度不要超过TILE的一半或者做连续碰撞检测即从上一帧位置到当前位置之间采样多个点逐个判断。最省事的做法是把子弹速度降到 6 以下配合 48 像素的格子基本不会穿透。5.5 敌人越打越多帧率越来越低现象玩了几分钟后画面变卡敌人数量异常增长。原因敌人被击毁后alive置了 false但生成新敌人的逻辑没有检查上限或者子弹数组满了之后FireBullet静默失败但敌人仍在疯狂调用。解决给敌人数量设硬上限比如同屏最多 4 个用计数器维护子弹池满了就跳过开火不要动态扩容。每帧遍历数组时先判断alive再处理避免对已销毁对象做无效计算。6. 从能跑到好玩关卡数据外置与手感调参的实战技巧把游戏跑通只是第一步真正让它像个作品的是关卡设计和手感调参。我一般会把地图数据从代码里抽出来放到单独的文本文件或者头文件里用二维数组初始化这样改关卡不用重新编译逻辑代码。具体做法是定义一个levels.h里面放多个int level1[13][13]、int level2[13][13]主程序用一个指针指向当前关卡通关后切换指针并重置坦克和子弹状态。这样加十关也只是复制数组改数字的事。手感调参有几个关键值值得反复试。坦克速度我试过 1、2、3、4最后定在 3因为 2 太拖沓4 在 48 像素格子里转向时会有明显的「滑步」感。子弹速度定在 10比坦克快三倍多打出去有干脆利落的感觉。敌人开火冷却从 60 帧调到 90 帧玩家才有空间走位。帧间隔Sleep(16)是 60 FPS 的基准如果你发现移动有细微抖动可以改成Sleep(15)或Sleep(17)微调但不要低于 10。验证游戏是否真的稳定我有个笨办法但很管用让敌人 AI 自己跑十分钟玩家不操作看会不会崩溃、内存是否持续增长、帧率是否下降。用任务管理器盯住进程的内存占用如果十分钟后涨了几十 MB八成是某个数组在偷偷扩容或者贴图资源重复加载。EasyX 的loadimage每调用一次都会占内存正确做法是在initgraph之后统一加载所有贴图到IMAGE对象游戏循环里只putimage绝不重复加载。最后说个我踩过的坑透明贴图。坦克和子弹如果直接用putimage贴上去图片的白色背景会把地图盖住。EasyX 里要用putimage的掩码版本或者先用SetWorkingImage处理最简单的办法是把图片做成带 Alpha 通道的 PNG然后用putimage配合SetImageTransparent之类的接口。我当初不知道这个坦克开过草地时屁股后面拖着一块白方块被同学笑了半天。后来养成习惯所有精灵图先确认透明通道再写渲染代码。这套源码的价值不在于它有多完整而在于它把 C 的类、数组、循环、条件判断和 EasyX 的绘图、输入、计时全部串在了一起改一个参数就能看到画面变化这种即时反馈是看书学不来的。如果你打算拿它做课程设计建议在敌人 AI 和关卡编辑上多花时间这两块最能体现工作量。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

养老统筹怎么交:从入门到精通的避坑实战指南

养老统筹怎么交:从入门到精通的避坑实战指南

养老统筹怎么交:从入门到精通的避坑实战指南 刚学完基础语法,代码能跑通,一动手搭项目就崩?这种“手残”时刻我太熟悉了。很多新人卡在配置环境、依赖管理或者数据落库的环节,明明教程里的代码是好的,自己一抄就报错。这就是从入门到精通最大的鸿沟,不…

2026/9/23 18:24:39 阅读更多 →
Stylelint 规则 `custom-property-empty-line-before`:自定义属性空行规范配置全解

Stylelint 规则 `custom-property-empty-line-before`:自定义属性空行规范配置全解

Stylelint 规则 custom-property-empty-line-before:自定义属性空行规范配置全解 【免费下载链接】stylelint A mighty CSS linter that helps you avoid errors and enforce conventions. 项目地址: https://gitcode.com/gh_mirrors/st/stylelint 导读 cus…

2026/9/23 18:24:39 阅读更多 →
基于相关性分析的CNN-Attention-LSTM期货价格预测模型实战解析

基于相关性分析的CNN-Attention-LSTM期货价格预测模型实战解析

简介:基于相关性分析的CNN-Attention-LSTM期货价格预测完整项目,面向深度学习、量化金融方向的毕设或课设研究,也适合希望用混合神经网络做时序预测的入门进阶者。代码覆盖数据相关性分析、时间步处理、模型定义、训练与预测全流程&#xff0…

2026/9/23 18:24:39 阅读更多 →

最新新闻

打不死的小强:后端高可用架构最佳实践与面试避坑指南

打不死的小强:后端高可用架构最佳实践与面试避坑指南

打不死的小强:后端高可用架构最佳实践与面试避坑指南 配置环境就卡半天,调试服务又超时,这种“打不死的小强”般的故障排查体验,谁还没经历过?在准备后端高级开发或架构师面试时,面试官最爱拿这种“顽固”的系统稳定性问题来考察你的底层功底。今天咱们…

2026/9/23 18:58:12 阅读更多 →
别死磕语法!sql select 性能调优入门到精通,3个致命坑一次讲透

别死磕语法!sql select 性能调优入门到精通,3个致命坑一次讲透

别死磕语法!sql select 性能调优入门到精通,3个致命坑一次讲透 你是不是也遇到过这种崩溃时刻?从网上复制了一段看起来很牛的 SQL…

2026/9/23 18:58:12 阅读更多 →
3步搞定整体与部分:后端开发者的保姆级教程

3步搞定整体与部分:后端开发者的保姆级教程

3步搞定整体与部分:后端开发者的保姆级教程 复制来的代码跑不通,报错日志一屏屏往外跳,你盯着屏幕发呆,完全不知道从哪下手调?别急,这种“整体混乱、部分断裂”的情况,在房建工程信息化和后端开发里太常见了。 今天这篇 保姆级教程…

2026/9/23 18:58:12 阅读更多 →
猪只检测实战数据集:VOC+YOLO双格式、3万标注、适配YOLOv8小目标优化

猪只检测实战数据集:VOC+YOLO双格式、3万标注、适配YOLOv8小目标优化

简介:本资源是面向农业AI与智能养殖领域的猪只目标检测专用数据集,适用于计算机视觉初学者、算法工程师及智慧畜牧项目开发者,解决猪只识别、行为分析与状态监测等实际落地问题。数据集包含2000张养猪场监控实拍图像,覆盖3万多个真…

2026/9/23 18:57:12 阅读更多 →
手势识别数据集构建全指南:从公开数据选择到自采标注避坑

手势识别数据集构建全指南:从公开数据选择到自采标注避坑

简介:面向手势识别与目标检测的深度学习数据集,适合需要训练YOLO系列、Faster Rcnn、SSD等模型的开发者和研究者使用。数据集共包含2400张图片,标注有拳头、无手势、竖大拇指、OK、手掌五个手势类别,并已将图片和文本标注按训练集…

2026/9/23 18:57:12 阅读更多 →
绿幕抠像软件选型速查手册:5款主流工具硬核对比

绿幕抠像软件选型速查手册:5款主流工具硬核对比

绿幕抠像软件选型速查手册:5款主流工具硬核对比 屏幕上一长串红色的 StackTrace,看着就头大。 是不是刚跑完一段 Python 代码,结果终端里全是 ModuleNotFoundError 或者 CUDA out of…

2026/9/23 18:57:12 阅读更多 →

日新闻

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A…

2026/9/23 0:00:23 阅读更多 →
2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我 刚把开发环境的显示器从1080P换到2K,跑老项目直接报错,版本升级后 API…

2026/9/23 0:01:25 阅读更多 →
3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点 官方文档翻了三遍还是云里雾里?别急,美眉图在实战项目中常被用来做数据可视化,但它的原理比你想的简单。今天咱们直接上手,用一个完整的小项目把美眉图跑通,不再死磕那些冗长的理论说明。…

2026/9/23 0:01:25 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →