C++控制台游戏开发实战:从零实现猫抓老鼠游戏
1. 项目概述从零构建一个C控制台游戏“猫抓老鼠”这个游戏相信是很多人童年记忆的一部分。它规则简单但策略性十足非常适合作为编程入门的实战项目。今天我想分享的就是如何用最纯粹的C在控制台环境下亲手实现这个经典游戏。这不仅仅是一个“Hello World”式的练习它涵盖了游戏循环、状态管理、用户输入、随机逻辑、碰撞检测等游戏开发的核心概念是检验和巩固C基础知识的绝佳试金石。这个项目适合所有正在学习C并且已经掌握了基础语法如变量、循环、条件判断、函数、数组的朋友。即使你还没接触过面向对象我们也可以先用过程化的方式来实现之后再探讨如何用类来重构让它更优雅。我们将从最简陋的文本界面开始一步步添加功能最终实现一个可玩性不错的版本。过程中我会穿插讲解为什么选择某种数据结构某个算法背后的考量以及我踩过的那些坑。我们的目标是写出来的代码不仅要能跑还要清晰、易维护让你真正理解每一行代码的作用。2. 核心设计思路与架构拆解在动手写代码之前花点时间想清楚整体架构能省去后期大量的重构时间。一个简单的“猫抓老鼠”游戏核心元素无非是一个棋盘地图、一只猫、一只或多只老鼠、以及一些可能的障碍物。游戏的核心循环是显示当前状态 - 获取玩家输入控制猫 - 更新游戏逻辑猫移动老鼠按某种规则移动 - 判断胜负条件。2.1 游戏状态的数据表示首先我们需要一种方式来“记住”棋盘上每个格子里有什么。最简单直接的方式就是使用一个二维字符数组或者vectorvectorchar。例如我们可以约定C代表猫M代表老鼠#代表墙或障碍物.代表空地*代表奶酪目标为什么用char而不用int或枚举在控制台显示时char可以直接打印非常方便。当然用枚举enum CellType来定义类型再用一个二维数组存储这些枚举值是更工程化的做法可读性更强。但对于第一个快速原型我们用char足以。猫和老鼠的位置我们可以用两个简单的结构体Point来记录包含x和y坐标。这样在移动逻辑中直接修改这两个点的坐标比遍历整个二维数组查找效率要高。struct Point { int x; // 行坐标 int y; // 列坐标 }; // 游戏地图例如 10x10 const int ROWS 10; const int COLS 10; char gameMap[ROWS][COLS]; Point catPos; Point mousePos;2.2 游戏主循环的结构游戏主循环是游戏的心脏它必须稳定且高效。一个经典的游戏循环结构如下bool gameRunning true; bool catWon false; while (gameRunning) { // 1. 渲染清屏并打印当前地图 system(cls); // Windows Linux/Mac 用 clear printMap(gameMap, ROWS, COLS); // 2. 处理输入获取玩家控制猫的方向 char input getPlayerInput(); // 3. 更新根据输入移动猫然后让老鼠自动移动 updateCatPosition(input, catPos, gameMap); updateMousePosition(mousePos, catPos, gameMap); // 4. 检测碰撞/胜负条件 if (catPos.x mousePos.x catPos.y mousePos.y) { gameRunning false; catWon true; } // 可以添加其他条件如老鼠到达奶酪游戏时间结束等 // 5. 控制游戏节奏避免循环过快 Sleep(100); // Windows 单位毫秒 } // 循环结束显示游戏结果 displayGameResult(catWon);这里有几个关键点清屏system(“cls”)是Windows特有的它依赖于操作系统。更可移植的做法是输出足够多的换行符或者使用像ncurses这样的库。但为了最初的原型简单我们可以先用它。输入获取getPlayerInput()需要实现非阻塞或半阻塞的输入。控制台默认是行缓冲的我们需要用_kbhit()和_getch()Windows或termios库Linux来获取单个即时按键。更新顺序先处理玩家输入猫再处理AI老鼠这样逻辑更符合直觉。延时Sleep(100)让每次循环间隔约0.1秒既保证了游戏有可玩的速度又不会过度消耗CPU。这个值可以根据需要调整。注意频繁调用system()函数存在安全风险和性能开销在产品级项目中应避免。这里仅用于教学演示。一个更好的做法是直接操作控制台API或使用跨平台库。2.3 老鼠的AI让游戏活起来老鼠不能傻站着需要一点简单的“智能”。这里就是体现设计思路的地方。我们可以设计几种不同复杂度的AI随机移动最简单。老鼠在每个回合随机选择上、下、左、右中的一个方向如果该方向可走。实现简单但行为完全不可预测缺乏挑战性。// 伪代码 int dir rand() % 4; // 0上1下2左3右 根据 dir 计算新位置 newPos; if (位置有效且不是墙) { mousePos newPos; }远离猫的移动增加一点策略。计算猫和老鼠的相对位置让老鼠倾向于向远离猫的方向移动。这需要计算距离。// 伪代码计算四个可能方向移动后与猫的欧几里得距离或曼哈顿距离 // 选择移动后距离最大的那个方向前提是可走。A*寻路算法最复杂但最智能。如果地图上有奶酪老鼠可以使用A*算法寻找通往奶酪的最短路径同时避开猫。这涉及到开放列表、封闭列表和启发函数是一个不小的挑战但实现后游戏性会大大提升。对于初版我强烈建议从随机移动开始。先让整个游戏流程跑通之后再迭代AI部分。这是项目管理的常见技巧先做出一个最小可行产品MVP。3. 核心模块实现与代码精讲有了设计蓝图我们来逐一实现各个模块。我会重点讲解容易出错的细节和性能考量。3.1 地图初始化与渲染地图初始化不只是填满字符。我们需要考虑可玩性墙要构成一定的迷宫格局猫和老鼠的初始位置不能重叠最好也不要太近。void initializeMap(char map[ROWS][COLS], Point cat, Point mouse) { // 1. 全部初始化为空地 for (int i 0; i ROWS; i) { for (int j 0; j COLS; j) { map[i][j] .; } } // 2. 放置围墙 for (int j 0; j COLS; j) { map[0][j] #; map[ROWS-1][j] #; } for (int i 0; i ROWS; i) { map[i][0] #; map[i][COLS-1] #; } // 3. 随机放置一些内部障碍物确保有通路 srand(time(nullptr)); int obstacleCount ROWS * COLS / 10; // 障碍物约占10%格子 for (int k 0; k obstacleCount; k) { int i rand() % ROWS; int j rand() % COLS; // 确保不放在边界和可能的主角初始位置上 if (map[i][j] . !(i 2 j 2)) { map[i][j] #; } } // 4. 放置猫和老鼠确保位置为空且不重叠 do { cat.x 1 rand() % (ROWS - 2); cat.y 1 rand() % (COLS - 2); } while (map[cat.x][cat.y] ! .); map[cat.x][cat.y] C; do { mouse.x 1 rand() % (ROWS - 2); mouse.y 1 rand() % (COLS - 2); } while (map[mouse.x][mouse.y] ! . || (abs(cat.x - mouse.x) abs(cat.y - mouse.y) 5)); // 确保初始距离不太近 map[mouse.x][mouse.y] M; // 5. 可以放置一个奶酪作为目标 // ... 类似逻辑 }渲染函数相对简单但要注意细节void printMap(const char map[ROWS][COLS], int rows, int cols) { for (int i 0; i rows; i) { for (int j 0; j cols; j) { std::cout map[i][j] ; // 加空格让显示更清晰 } std::cout std::endl; } std::cout \n控制: W(上) A(左) S(下) D(右) | Q(退出)\n; }实操心得在初始化随机位置时使用do...while循环比while循环更合适因为它至少会执行一次逻辑更清晰。条件abs(cat.x - mouse.x) abs(cat.y - mouse.y) 5使用了曼哈顿距离来确保两者初始有一定距离避免游戏一开始就结束这比简单的“坐标不相等”要求更高提升了游戏体验。3.2 非阻塞键盘输入处理这是控制台游戏的一个小难点。标准cin会等待回车不适合实时游戏。我们需要即时读取按键。Windows平台实现#include conio.h // 用于 _kbhit 和 _getch char getPlayerInput() { if (_kbhit()) { // 检查是否有按键按下 char ch _getch(); // 处理方向键扩展键码 if (ch 0 || ch -32) { // 方向键的第一个字符 ch _getch(); // 获取真正的方向码 switch (ch) { case 72: return W; // 上 case 80: return S; // 下 case 75: return A; // 左 case 77: return D; // 右 } } // 处理 WASD 和退出键 ch toupper(ch); if (ch W || ch A || ch S || ch D || ch Q) { return ch; } } return \0; // 没有有效输入 }Linux/macOS平台实现使用termios#include termios.h #include unistd.h #include fcntl.h char getPlayerInput() { struct termios oldt, newt; char ch; int oldf; // 获取当前终端设置并修改为“非规范模式”和“无回显” tcgetattr(STDIN_FILENO, oldt); newt oldt; newt.c_lflag ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, newt); // 设置文件描述符为非阻塞 oldf fcntl(STDIN_FILENO, F_GETFL, 0); fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); ch getchar(); // 恢复原有终端设置 tcsetattr(STDIN_FILENO, TCSANOW, oldt); fcntl(STDIN_FILENO, F_SETFL, oldf); if (ch ! EOF) { ch toupper(ch); if (ch W || ch A || ch S || ch D || ch Q) { return ch; } // Linux终端方向键处理更复杂通常先收到转义序列‘\033’这里为简化建议用WASD } return \0; }踩坑记录跨平台输入处理是控制台游戏的一大痛点。上面的Linux代码只是一个简化示例实际处理方向键需要解析\033[A这样的转义序列。对于学习项目我强烈建议统一使用WASD字母键这样可以极大简化代码保证在Windows和Linux/macOS上都能一致工作。这也是很多成熟控制台游戏的做法。3.3 移动逻辑与碰撞检测移动逻辑需要检查目标位置是否合法不超出边界且不是墙。bool isValidPosition(int x, int y, const char map[ROWS][COLS]) { return (x 0 x ROWS y 0 y COLS map[x][y] ! #); } void updateCatPosition(char input, Point cat, char map[ROWS][COLS]) { int newX cat.x, newY cat.y; switch (input) { case W: newX--; break; case S: newX; break; case A: newY--; break; case D: newY; break; default: return; // 非移动指令直接返回 } if (isValidPosition(newX, newY, map)) { // 更新地图旧位置变空地新位置放猫 map[cat.x][cat.y] .; cat.x newX; cat.y newY; map[cat.x][cat.y] C; } // 如果位置无效撞墙则猫不动 }老鼠的随机移动实现void updateMousePosition(Point mouse, const Point cat, char map[ROWS][COLS]) { // 简单随机移动AI int directions[4][2] {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // 上下左右 int randomIndex rand() % 4; int newX mouse.x directions[randomIndex][0]; int newY mouse.y directions[randomIndex][1]; if (isValidPosition(newX, newY, map)) { map[mouse.x][mouse.y] .; mouse.x newX; mouse.y newY; map[mouse.x][mouse.y] M; } // 如果随机方向不可走则本轮老鼠不动也可以尝试其他方向 }碰撞检测在游戏主循环中已经做了就是简单的坐标比较。但这里有一个关键细节我们是在猫和老鼠都移动完之后才检测的。如果猫移动后抓住了老鼠那么老鼠在地图上的‘M’会被猫的‘C’覆盖这没问题。但如果我们想实现“老鼠被抓住的瞬间有特殊显示”就需要在更新地图前进行检测。4. 功能增强与代码重构一个基础版本完成后我们可以考虑添加更多功能让游戏更好玩同时重构代码让其更健壮。4.1 添加游戏元素与状态奶酪与胜负条件在地图上随机放置一块奶酪‘*’。老鼠的目标是吃到奶酪猫的目标是抓住老鼠。游戏胜负条件变为猫鼠同格 - 猫赢。鼠与奶酪同格 - 鼠赢。可以加入回合限制超时则为平局或猫赢。分数与回合计数记录猫移动的步数步数越少得分越高。或者记录游戏进行的回合数。多个老鼠将mousePos改为vectorPoint每只老鼠独立移动。猫需要抓住所有老鼠才能赢或者只要抓住一只就赢。更复杂的地形引入多种地形例如‘~’水域猫不能进入老鼠可以。‘’传送点进入后随机传送到另一个传送点。这些地形需要在isValidPosition和移动逻辑中做特殊判断。4.2 使用面向对象重构当功能越来越多过程式编程会显得混乱。用类来组织代码是必然的选择。class GameEntity { public: Point position; char symbol; GameEntity(int x, int y, char s) : position{x, y}, symbol(s) {} virtual void move(const GameMap map) 0; // 纯虚函数不同实体移动逻辑不同 // ... 其他公共属性和方法 }; class Cat : public GameEntity { public: Cat(int x, int y) : GameEntity(x, y, C) {} void move(const GameMap map) override { // 依赖外部输入这里可能只是更新位置输入由Game类传入 } }; class Mouse : public GameEntity { public: Mouse(int x, int y) : GameEntity(x, y, M) {} void move(const GameMap map) override { // 实现AI移动逻辑 } }; class GameMap { private: std::vectorstd::vectorCell grid; // Cell是一个包含类型和属性的结构体/类 public: void render() const; bool isCellWalkable(const Point p) const; void setCell(const Point p, CellType type); // ... }; class Game { private: GameMap map; std::unique_ptrCat cat; std::vectorstd::unique_ptrMouse mice; bool isRunning; // ... public: void run(); // 主游戏循环 void processInput(); void update(); void render(); };重构后职责清晰Game类管理主循环和全局状态GameMap管理地图数据与查询GameEntity及其子类负责各自的行为。添加新生物比如狗只需要继承GameEntity并实现move方法即可符合开闭原则。4.3 引入简单的状态机游戏可能有多个状态开始菜单、游戏中、暂停、胜利/失败画面。用一个简单的枚举和状态机来管理会使逻辑更清晰。enum class GameState { MAIN_MENU, PLAYING, PAUSED, CAT_WON, MOUSE_WON }; class Game { GameState currentState; // ... void run() { while (true) { switch (currentState) { case GameState::MAIN_MENU: renderMainMenu(); processMainMenuInput(); break; case GameState::PLAYING: renderGame(); processGameInput(); updateGameLogic(); checkWinCondition(); // 可能切换状态到 CAT_WON 等 break; case GameState::CAT_WON: renderWinScreen(Cat Wins!); if (pressAnyKeyToRestart()) resetGame(); break; // ... 其他状态 } } } };5. 调试技巧、常见问题与优化建议即使是一个小游戏调试起来也可能让人头疼。下面分享一些我实践中总结的经验。5.1 调试技巧让问题无处遁形打印调试信息在关键函数入口、变量改变处打印日志。例如在updateMousePosition里打印老鼠的新旧坐标。std::cout [DEBUG] Mouse moving from ( mouse.x , mouse.y ) to ( newX , newY )\n;使用调试器如果你使用Visual Studio、CLion或VSCode配合GDB/LLDB学会设置断点、单步执行、查看变量值。这是定位逻辑错误最强大的武器。特别是对于随机性的问题断点比cout更有效。控制随机性调试AI时随机行为难以复现问题。可以暂时将srand(time(nullptr))改为srand(0)这样每次运行随机序列都相同便于定位。地图快照当游戏行为异常时写一个函数把当前地图状态完整输出到一个文本文件方便离线分析。5.2 常见问题排查表问题现象可能原因排查方法猫或老鼠“穿墙”isValidPosition函数边界检查错误或地图数组越界。1. 检查ROWS和COLS定义。2. 在isValidPosition中打印传入的x, y值。3. 确保移动逻辑 (newX cat.x - 1) 正确。游戏画面闪烁严重清屏 (system(“cls”)) 和打印之间没有延时或打印内容太多。1. 在主循环中增加Sleep时间。2. 尝试只重绘变化的部分更复杂。3. 使用双缓冲技术先准备完整帧再一次性输出。键盘输入无反应或反应迟滞输入函数getPlayerInput实现有误可能是阻塞的。1. 确认使用的是_kbhit(Win) 或非阻塞getchar(Linux)。2. 检查是否正确处理了按键释放和特殊键。回归基础先用WASD测试。老鼠有时会“卡住”不动随机移动的方向恰好是墙而代码没有“尝试其他方向”的逻辑。在updateMousePosition中如果随机方向不行可以尝试遍历所有方向直到找到一个可行的。或者增加一个计数器连续多次失败后强制移动。游戏运行一段时间后崩溃内存访问越界、无限递归或未初始化的变量。1. 使用valgrind(Linux) 或AddressSanitizer检查内存错误。2. 检查所有数组索引。3. 检查递归函数是否有终止条件。5.3 性能与代码优化建议减少不必要的重绘我们的简单实现是每帧清屏并重绘整个地图。对于10x10的网格没问题。但如果网格很大比如50x50频繁的cout操作会成为瓶颈。优化思路是“脏矩形”渲染只重绘那些发生变化的格子。避免频繁的系统调用system(“cls”)和Sleep()都是系统调用。对于游戏循环来说可以自己实现一个更精确的帧率控制例如使用chrono库来计算帧时间。使用更高效的数据结构当有几十上百只老鼠时用vectorPoint存储并遍历更新是O(n)。如果需要进行空间查询如“找到3格内的所有老鼠”可以考虑使用空间划分数据结构如网格分区Spatial Grid将地图划分为大格子每个格子维护其中的实体列表查询时只需检查相邻的几个大格子。预计算可行走区域如果地图是固定的可以在游戏初始化时就计算好每个格子是否是“可行走”的并存储在一个bool二维数组中。这样在isValidPosition中只需要做一次数组查找比判断map[x][y] ! ‘#’可能更快虽然对于字符比较来说差异不大但思路可以借鉴。代码可读性给魔法数字如72,80方向键码和字符常量如‘#’,‘C’起有意义的名字使用枚举或常量定义。这不会提升运行性能但会极大提升你和其他人阅读、维护代码的效率减少bug。写完基础版本后不要停下。尝试去实现我提到的“功能增强”里的任意一点或者尝试用不同的AI算法。这个过程里遇到的每一个问题和解决它的过程才是这个项目带给你的最大价值。编程就像这个“猫抓老鼠”的游戏你需要不断地探索、试错、优化最终抓住那个名为“解决方案”的老鼠。

相关新闻

Stable Diffusion全身一致性难题:为什么你的角色总“断手断脚”?97%新手忽略的4个隐式约束条件

Stable Diffusion全身一致性难题:为什么你的角色总“断手断脚”?97%新手忽略的4个隐式约束条件

更多请点击: https://kaifayun.com 第一章:Stable Diffusion全身一致性难题:为什么你的角色总“断手断脚”? 当使用 Stable Diffusion 生成人物全身像时,模型常出现肢体错位、关节断裂、比例失调等现象——例如手臂延…

2026/10/8 2:10:32 阅读更多 →
SimWalk人群仿真软件操作指南与实战技巧

SimWalk人群仿真软件操作指南与实战技巧

1. SimWalk用户界面概览:从零开始的导航指南第一次打开SimWalk的人群仿真界面时,那种扑面而来的专业感可能会让新手感到些许压力。左侧是层级分明的场景树状图,中央占据70%面积的是3D可视化主窗口,右侧则是参数调节面板——这种三…

2026/10/6 9:15:23 阅读更多 →
AI邀请函生成效率革命(实测数据:从2小时→83秒):2024最新Prompt+模板+平台选型全拆解

AI邀请函生成效率革命(实测数据:从2小时→83秒):2024最新Prompt+模板+平台选型全拆解

更多请点击: https://codechina.net 第一章:AI邀请函生成效率革命(实测数据:从2小时→83秒):2024最新Prompt模板平台选型全拆解 传统人工撰写活动邀请函平均耗时127分钟——含需求确认、文案润色、格式排版…

2026/10/11 0:23:13 阅读更多 →

最新新闻

门禁监控各管一摊?IT外包让弱电系统拧成一股绳

门禁监控各管一摊?IT外包让弱电系统拧成一股绳

写在前面一个客户找我,说想调上周三晚上的监控。结果是这样:门禁是A家的系统,监控是B家装的,考勤机是C家的,三个后台三套密码,装系统的师傅一个都联系不上了。最后只能翻硬盘文件,折腾了两个小时…

2026/10/14 6:44:30 阅读更多 →
如何用 BepInEx 6 给 Unity 游戏装模组:新手完整指南

如何用 BepInEx 6 给 Unity 游戏装模组:新手完整指南

如何用 BepInEx 6 给 Unity 游戏装模组:新手完整指南 【免费下载链接】BepInEx Unity / XNA game patcher and plugin framework 项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx BepInEx 是面向 Unity 与 .NET 游戏的插件框架,让不给…

2026/10/14 6:44:30 阅读更多 →
Oracle补丁包完整运维指南:从命名识别到安全回滚

Oracle补丁包完整运维指南:从命名识别到安全回滚

简介:数据库系统的长期稳定运行离不开规范的补丁管理,尤其在涉及安全修复与稳定性增强的正式环境中,补丁升级是运维工程师必须掌握的基础技能。补丁包的命名规则包含产品版本、平台类型与补丁编号等关键信息,而安装过程则依赖OPat…

2026/10/14 6:44:30 阅读更多 →
COMSOL卡门涡街压电发电仿真建模全流程与参数优化指南

COMSOL卡门涡街压电发电仿真建模全流程与参数优化指南

我没有想到,卡门涡街这个老掉牙的流体现象,竟然能靠COMSOL做成一个发电模型,还能把整套仿真流程跑得又稳又准。这个模型不复杂,核心就是把圆柱绕流产生的周期性旋涡脱落,变成悬臂梁的强迫振动,再接上压电片…

2026/10/14 6:44:30 阅读更多 →
WorkBuddy:让ComfyUI支持任务队列与参数化流水线的工业级调度器

WorkBuddy:让ComfyUI支持任务队列与参数化流水线的工业级调度器

1. 项目概述:当 ComfyUI 不再是“点一下出一张图”的玩具“我用 WorkBuddy 把本地 ComfyUI 管成了一条出图流水线”——这句话刚在技术群刷出来时,我盯着看了三秒。不是因为听不懂,而是太懂了:ComfyUI 本身是个节点式图像生成工作…

2026/10/14 6:44:30 阅读更多 →
后端接口没就绪?前端用Mock与契约治理实现自救

后端接口没就绪?前端用Mock与契约治理实现自救

做前端的兄弟应该都有过这种经历:排期压到眼前,后端接口却迟迟不来,你能拿到的只有一句话“接口下周给你”,或者一封只有路径没有字段的文档。这几年 Vibe Coding 火起来之后,很多前端同学开始用 AI 助手批量生成对接代…

2026/10/14 6:43:30 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →