CodeBuddy 学习(1):安装与使用
一、概述:什么是 CodeBuddy
1.1 产品定位
CodeBuddy(腾讯云代码助手)是腾讯云推出的全流程 AI 辅助编程工具,将 AI 深度嵌入 需求 → 设计 → 编码 → 部署 全链路,支持插件、IDE、CLI 三种形态,覆盖从初学者到企业团队的全场景。
1.2 工作原理简述
CodeBuddy 的核心工作流程分为以下几步:
- 上下文收集:分析当前项目结构、打开的文件、Git 历史、终端输出等环境信息。
- 意图理解:通过大语言模型(LLM)解析用户输入的自然语言指令,识别任务类型(问答 / 编写 / 规划 / 部署)。
- 能力调度:根据任务类型,调用对应的工具链——文件读写、终端命令执行、代码补全引擎、部署管道等。
- Diff 渲染:所有代码变更以 Diff 视图呈现,用户可以逐行审查后选择接受或拒绝。
关键概念:CodeBuddy 不是简单的"输入→输出"聊天机器人。它是一个具有读写权限的 AI Agent,可以自主完成文件创建、命令执行、环境配置等操作。理解这一点是高效使用 CodeBuddy 的基础。
1.3 核心能力数据
| 能力 | 说明 |
|---|---|
| 代码生成 | AI 代码占比 50%+,自动生成高质量代码 |
| 代码评审 | AI 评审占比 35%+,自动审查代码质量 |
| 编码提速 | 编码时间缩短 40%+ |
| 研发覆盖 | 内部实践覆盖 90%+ 研发场景 |
1.4 生态集成
- CloudBase / EdgeOne:一键部署到腾讯云
- Cloud Studio:云端 IDE 环境
- 微信开发者工具:小程序开发支持
1.5 行业验证
在游戏、微信、金融、电子等行业均有实践,AI 代码生成率达到 40-50%+。
二、安装指南
CodeBuddy 提供三种安装方式,适应不同使用场景。建议新手从方式一(VS Code 插件)开始。
| 方式 | 适用场景 | 特点 |
|---|---|---|
| VS Code 插件 | 已有 VS Code,需要轻量集成 | 最小安装,即装即用 |
| 独立 IDE | 需要完整的 AI 编程环境 | 开箱即用,深度集成 |
| CLI 命令行 | 终端重度用户,CI/CD 集成 | 纯命令行,灵活高效 |
2.1 方式一:VS Code 插件(推荐新手)
安装步骤:
- 打开 VS Code,点击左侧扩展图标
- 搜索 腾讯云代码助手 CodeBuddy
- 点击安装,安装完成后重启 VS Code
- 右下角弹出登录窗口,使用微信扫码或手机号登录
也可在 JetBrains 系列 IDE(IDEA / PyCharm 等)中安装: File → Settings → Plugins → Marketplace → 搜索 Tencent Cloud Code Assistant CodeBuddy → 安装 → 重启 → 登录
2.2 方式二:独立 IDE
安装步骤:
- 访问下载页面:
- 下载对应平台的安装包(Windows / macOS / Linux)
- 安装完成后直接启动,登录即可使用
2.3 方式三:CLI 命令行(完整示例)
原理讲解
CLI(Command Line Interface)是 CodeBuddy 的命令行版本。它的原理是:
- 全局 npm 包安装:通过 npm 将 CodeBuddy CLI 安装到系统全局路径(如 Windows 的
%APPDATA%/npm/,macOS/Linux 的/usr/local/lib/node_modules/)。 - PATH 注册:
npm install -g会在 Node.js 安装目录的node_modules/.bin/下创建可执行文件,并将其路径加入系统 PATH,使得在任意终端窗口中都可以直接执行codebuddy命令。 - API 通信:CLI 启动后,读取用户输入,通过 HTTP/HTTPS 协议与 CodeBuddy 云端服务通信,将结果渲染到终端。
此外,CodeBuddy CLI 还支持通过 Homebrew(无需预装 Node.js)和原生二进制安装,原理类似——它们都是将可执行文件放到系统路径中。
示例代码:完整安装与验证流程
# ============================================
# 前置步骤:安装 Node.js(如已安装可跳过)
# ============================================
# 1. 访问 https://nodejs.org/zh-cn/download/
# 2. 下载 LTS 版本(推荐 20.x)
# 3. 安装后验证:
node --version
# 预期输出:v20.x.x
npm --version
# 预期输出:10.x.x(随 Node.js 一起安装)
# ============================================
# 步骤 1:配置 npm 镜像(国内用户加速下载)
# ============================================
npm config set registry https://registry.npmmirror.com/
# 验证镜像是否切换成功:
npm config get registry
# 预期输出:https://registry.npmmirror.com/
# ============================================
# 步骤 2:安装 CodeBuddy CLI
# ============================================
npm install -g @tencent-ai/codebuddy-code
# 预期输出(示例):
# added 150 packages in 30s
# 15 packages are looking for funding
# run `npm fund` for details
# ============================================
# 步骤 3:验证安装
# ============================================
codebuddy --version
# 预期输出:x.x.x(显示当前版本号)
# ============================================
# 步骤 4:查看帮助信息
# ============================================
codebuddy --help
# 预期输出:显示所有可用命令和使用说明
# ============================================
# 步骤 5:启动登录
# ============================================
codebuddy
# 首次运行会引导登录流程,根据终端提示完成扫码或输入验证码
# ============================================
# 步骤 6:快速测试
# ============================================
codebuddy "用 JavaScript 写一个打印 Hello World 的函数"
# 预期输出:AI 会生成包含 function helloWorld() 的完整代码
其他安装方式
- Homebrew(macOS/Linux,无需 Node.js):
brew install codebuddy-code - 原生二进制(Beta):
- macOS/Linux:
curl -fsSL https://www.codebuddy.cn/cli/install.sh | bash - Windows:
irm https://www.codebuddy.cn/cli/install.ps1 | iex
- macOS/Linux:
调试过程
场景一:npm install -g 报权限错误(macOS/Linux)
# 错误信息示例:
# Error: EACCES: permission denied, access '/usr/local/lib/node_modules'
# 原因:当前用户对全局 node_modules 目录没有写入权限
# 排查步骤:
# 1. 确认 Node.js 安装路径
which node
# 预期:/usr/local/bin/node
# 2. 检查 node_modules 目录权限
ls -la /usr/local/lib/node_modules
# 预期:看到目录的权限信息
# 3. 修复方法(三选一):
# 方法 A:使用 npx 跳过全局安装
npx @tencent-ai/codebuddy-code
# 方法 B:修改 npm 全局目录(推荐)
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
npm install -g @tencent-ai/codebuddy-code
# 方法 C:在命令前加 sudo(不推荐,有安全风险)
sudo npm install -g @tencent-ai/codebuddy-code
场景二:codebuddy 命令找不到(Windows)
# 错误信息示例:
# 'codebuddy' 不是内部或外部命令,也不是可运行的程序
# 或
# command not found: codebuddy
# 原因:npm 全局安装路径未添加到系统 PATH
# 排查步骤:
# 1. 确认 npm 全局安装路径
npm config get prefix
# 预期输出(Windows 示例):C:\Users\你的用户名\AppData\Roaming\npm
# 2. 检查该目录下是否有 codebuddy 相关文件
dir %APPDATA%\npm\codebuddy*
# 预期:显示 codebuddy 和 codebuddy.cmd 文件
# 3. 将路径添加到 PATH:
# Windows:系统属性 → 环境变量 → 找到 Path → 新建
# 添加:%APPDATA%\npm
# 然后重新打开终端
# 3. 重新验证
codebuddy --version
# 预期:正常显示版本号
场景三:网络下载缓慢
# 错误信息示例:
# npm ERR! network timeout
# npm ERR! network This is a problem related to network connectivity.
# 原因:默认 npm registry 在国外,国内访问速度慢
# 排查与修复:
# 1. 检查当前镜像源
npm config get registry
# 预期输出可能是:https://registry.npmjs.org/
# 2. 切换至国内镜像
npm config set registry https://registry.npmmirror.com/
# 3. 验证切换
npm config get registry
# 预期:https://registry.npmmirror.com/
# 4. 重新安装
npm install -g @tencent-ai/codebuddy-code
场景四:Node.js 版本不兼容
# 错误信息示例:
# npm WARN EBADENGINE Unsupported engine
# npm WARN EBADENGINE required: { node: '>=18.20' }
# 排查步骤:
# 1. 确认当前版本
node --version
# 预期:显示 v16.x.x 或其他低于 18.20 的版本
# 2. 升级 Node.js:
# Windows / macOS:访问 https://nodejs.org/ 下载最新 LTS
# 或使用 nvm(Node Version Manager):
nvm install 20
nvm use 20
node --version
# 预期:v20.x.x
2.4 常用 CLI 命令速查
codebuddy "你的问题或指令" # 单次对话
cbc "你的问题或指令" # 简写形式
codebuddy --version # 查看版本
codebuddy --help # 查看帮助
三、快速上手:第一个对话
在深入各项功能之前,先完成一个有代表性的操作来建立直观感受。
3.1 示例:用 Ask 模式理解一段代码
原理讲解
Ask 模式是 CodeBuddy 的"只读问答"模式。其核心原理:
- 权限边界:Ask 模式下,AI 只能读取文件和项目上下文,不能修改任何文件或执行任何命令。这确保了安全性——你可以放心提问而不用担心代码被意外修改。
- 上下文注入:当你通过
@file引用文件时,CodeBuddy 会将文件内容注入到大语言模型的上下文中。模型看到的是完整的源代码,而非摘要。 - Token 约束:模型有上下文长度限制(即 token 上限),过长的文件会被截断。因此,引用时尽量精确到需要分析的具体文件,而不是整个项目目录。
Ask 模式适合:代码解释、方案讨论、学习新技术、代码审查建议等不需要修改代码的场景。
示例代码:待分析的代码文件
假设你的项目中有一个 utils.js 文件,内容如下:
// utils.js — 一个用于演示的实用工具文件
/**
* 防抖函数:在连续触发的事件中,只执行最后一次
* @param {Function} fn - 需要防抖的函数
* @param {number} delay - 延迟时间(毫秒)
* @returns {Function} - 包装后的防抖函数
*/
function debounce(fn, delay) {
let timer = null;
return function (...args) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
/**
* 节流函数:在指定时间间隔内,只执行一次
* @param {Function} fn - 需要节流的函数
* @param {number} interval - 时间间隔(毫秒)
* @returns {Function} - 包装后的节流函数
*/
function throttle(fn, interval) {
let lastTime = 0;
return function (...args) {
const now = Date.now();
if (now - lastTime >= interval) {
lastTime = now;
fn.apply(this, args);
}
};
}
module.exports = { debounce, throttle };
操作步骤
- 在 CodeBuddy 中打开
utils.js文件。 - 将工作模式切换到 Ask(在对话面板顶部选择)。
- 在对话框中输入
@file,从文件列表中选择utils.js。 - 输入你的问题,例如:
请解释 debounce 和 throttle 的区别,并举一个实际应用场景 - 按 Enter 发送,观察 AI 的回复。
预期输出
AI 会输出类似以下的分析:
debounce 和 throttle 的核心区别在于执行时机的控制策略:
**debounce(防抖)**:
- 原理:每次触发都重新计时,只有在停止触发 delay 毫秒后才执行。
- 类比:电梯门——有人进就重新计时,直到没人进了才关门。
- 应用:搜索输入框——用户停止输入 300ms 后再发请求,避免每次按键都请求。
**throttle(节流)**:
- 原理:每隔 interval 毫秒固定执行一次,不管触发有多频繁。
- 类比:红绿灯——每 60 秒放行一次,中间来了多少车不管。
- 应用:滚动事件——每 200ms 检查一次滚动位置,避免高频触发。
**关键区别**:
debounce 关注"最后一次",throttle 关注"固定频率"。
调试过程
场景一:Ask 模式下无法生成代码
现象:选中 Ask 模式后,AI 拒绝生成代码,只提供解释。
原因:这是 Ask 模式的预期行为——只读不写。
排查:检查对话面板顶部的模式选择器,确认当前处于 Ask 模式。
修复:如需生成和修改代码,切换到 Craft 模式或 Plan 模式。
场景二:@file 引用文件无反应
现象:输入 @file 后没有出现文件选择列表。
原因排查:
1. 确认当前已在 CodeBuddy 中打开了一个项目/文件夹。
如果 IDE 中没有打开任何文件夹,CodeBuddy 无法读取项目文件。
2. 确认模式已切换到 Ask / Craft(某些模式下 @ 上下文功能可能不同)。
修复:使用 "文件 → 打开文件夹" 打开项目,然后重试。
场景三:回复内容与预期不符(幻觉)
现象:AI 给出了看似合理但实际错误的解释。
原因:AI 的上下文窗口有限,如果引用的文件内容被截断或理解偏差,可能出现幻觉。
排查:
1. 检查 @file 引用是否正确指向了目标文件。
2. 将问题描述得更具体,例如加上"只看 debounce 函数的实现"。
修复:精简引用范围,避免一次引用过多文件;必要时将问题拆分为多个子问题分步提问。
四、核心功能详解
掌握基础交互后,逐一学习 CodeBuddy 的核心功能。
4.1 三种工作模式
原理讲解
CodeBuddy 的三种模式对应了三种不同的 权限等级 和 执行策略:
| 模式 | 权限 | 执行策略 | 适用场景 |
|---|---|---|---|
| Ask | 只读 | 纯问答,不执行任何写操作 | 咨询问题、代码解释、方案讨论 |
| Craft | 读写+命令 | 直接执行,边生成边修改 | 代码编写、项目构建、文件操作 |
| Plan | 读写+命令 | 先生成计划,用户确认后再执行 | 复杂需求、多步骤任务、大型重构 |
工作流选择策略:
- 简单咨询 → Ask:问 API 用法、解释报错、讨论架构方案。
- 明确需求 → Craft:创建一个 React 组件、修复一个已知 Bug、格式化一段代码。
- 复杂任务 → Plan:重构整个模块、搭建新项目脚手架、迁移技术栈。
最佳实践:不确定 AI 会做什么时,先用 Plan 模式让它制定计划,审查通过后再切换到 Craft 执行。
示例:用 Plan 模式重构代码
场景:项目中有一个 500 行的 app.js,需要拆分为多个模块。
操作步骤:
- 切换到 Plan 模式。
- 对话框输入:
@file app.js 请制定一个拆分方案,将这个文件按职责分为 controller、service、model 三层, 要求不影响现有功能。 - AI 输出拆分计划,列出每个模块的职责和依赖关系。
- 审查计划,如需调整则继续对话。
- 确认无误后,切换到 Craft 模式,说:"按计划执行"。
调试过程
场景:Plan 模式下 AI 直接开始修改代码
现象:切换到 Plan 模式后,AI 仍然直接修改了文件。
原因:可能是模式切换未生效,或 Craft 模式的残留行为。
排查:
1. 确认对话面板顶部显示的模式名称是 "Plan"。
2. 新建一个对话重新开始(避免历史上下文影响)。
修复:新建对话,重新选择 Plan 模式后发起请求。
4.2 切换模型
点击对话面板顶部的模型选择器,可切换不同的 AI 模型。不同模型在推理速度、代码生成质量和上下文长度上有所差异。
4.3 对话管理
- 新建对话:点击对话面板顶部的新建按钮(或使用快捷键)。
- 历史对话:在对话列表中切换查看历史记录。
- 注意事项:每次新建对话会清空上下文历史,意味着 AI 不再记得之前讨论过的内容。如果需要延续之前的讨论,请在同一个对话中继续,而不是新建。
4.4 @ 上下文引用(完整示例)
原理讲解
@ 引用是 CodeBuddy 最强大的功能之一。其原理是:
- 符号系统:
@是一个上下文调取指令,告诉 CodeBuddy"把某个实体的内容注入到当前对话中"。 - 内容注入方式:根据引用类型不同,CodeBuddy 读取不同来源的数据并序列化为文本,追加到每次请求的上下文窗口里。
- 实时性:
@terminal引用的是最近一次命令执行的输出,@git引用的是最新的提交记录——这些都是动态获取的实时数据 - 不持久化:只有在当前消息中通过
@引用的内容才会被注入;下一条消息若不再次引用,AI 就不知道那个文件的内容了。
| 引用类型 | 写法 | 说明 | 典型用途 |
|---|---|---|---|
| 文件 | @file | 引用项目中的文件 | 分析代码、查找 Bug、解释逻辑 |
| 文件夹 | @folder | 引用整个目录 | 了解项目结构、跨文件分析 |
| 终端输出 | @terminal | 引用终端命令输出结果 | 排查报错、分析运行日志 |
| Git 提交 | @git | 引用 Git 提交记录 | 了解变更历史、生成 commit message |
| 规则 | @rules | 引用项目规则配置 | 确认项目规范、约束 AI 行为 |
示例:组合使用多个 @ 引用排查问题
场景:项目运行时报错,需要排查原因。
操作步骤:
- 先在终端执行报错的命令:
node server.js - 终端输出类似如下错误:
Error: Cannot find module './config' Require stack: - /path/to/project/server.js - 在 CodeBuddy 对话框中输入:
@file server.js @terminal 请分析终端报错的原因,并给出修复方案 - AI 同时看到
server.js的代码和终端错误输出,能精确定位问题。
预期输出
错误原因分析:
server.js 第 3 行尝试 require('./config'),但当前目录下不存在 config.js
或 config/index.js 文件。
修复方案:
1. 检查 config 模块是否存在:ls config*
2. 如果需要从环境变量读取配置,创建 config.js 导出配置对象
3. 如果配置文件在其他路径,修正 require 的路径
调试过程
场景:@terminal 引用的不是最新的输出
现象:使用 @terminal 后,AI 分析的是旧的终端输出。
原因:每次执行命令后,@terminal 引用的是最近一次的输出内容,但前提是
该终端窗口是 CodeBuddy 的内置终端。如果在 VS Code 外部终端执行命令,
则 CodeBuddy 无法捕获。
排查:
1. 确认使用的是 CodeBuddy 内置终端,而非系统外部终端。
2. 重新在 CodeBuddy 内置终端中执行命令,然后引用 @terminal。
修复:在 CodeBuddy 内置终端重新执行命令。
4.5 内联编辑
原理讲解
内联编辑(Inline Edit)是在代码编辑区域直接触发 AI 修改的快捷方式:选中一段代码 → 按快捷键 → 输入自然语言指令 → AI 直接在文件内生成 Diff 变更。
快捷键:
| 平台 | 快捷键 |
|---|---|
| Windows | Alt + K |
| macOS | Cmd + K |
工作原理:
- 用户选中一段代码。
- 按键触发后,弹出一个输入框。
- 输入自然语言指令(如"添加错误处理")。
- AI 分析选中代码和指令,生成修改后的代码。
- 以 Diff 视图展示,用户选择接受或拒绝。
示例:为函数添加 JSDoc 注释
操作步骤:
- 在编辑器中选中以下代码:
function calculateTotal(items, discount) { const subtotal = items.reduce((sum, item) => sum + item.price * item.qty, 0); return subtotal * (1 - discount); } - 按
Alt + K(Windows)或Cmd + K(macOS)。 - 输入指令:
为这个函数添加 JSDoc 注释和参数校验 - 观察 Diff 视图中的变更。
预期输出(Diff 视图会显示新增内容为绿色):
/**
* 计算订单总价
* @param {Array<{price: number, qty: number}>} items - 商品列表
* @param {number} discount - 折扣比例(0-1)
* @returns {number} 折后总价
* @throws {Error} 如果参数类型不正确
*/
function calculateTotal(items, discount) {
if (!Array.isArray(items)) {
throw new Error('items 必须是数组');
}
if (typeof discount !== 'number' || discount < 0 || discount > 1) {
throw new Error('discount 必须是 0-1 之间的数字');
}
const subtotal = items.reduce((sum, item) => sum + item.price * item.qty, 0);
return subtotal * (1 - discount);
}
调试过程
场景:Alt+K / Cmd+K 没有反应
现象:选中代码后按快捷键,没有弹出输入框。
原因排查:
1. 快捷键被其他扩展或系统快捷键拦截。
2. CodeBuddy 扩展未正常加载。
排查步骤:
1. 检查 VS Code 右下角状态栏,确认 CodeBuddy 图标是否正常显示(不显示灰色)。
2. 打开快捷键设置:File → Preferences → Keyboard Shortcuts
搜索 "codebuddy",查看内联编辑的快捷键配置是否被覆盖。
3. 尝试先点一下编辑区域确保焦点在编辑器中,再按快捷键。
修复:
- 如果快捷键冲突,在 Keyboard Shortcuts 中重新绑定。
- 如果扩展异常,先禁用再重新启用 CodeBuddy 扩展。
4.6 Diff 视图操作
AI 生成或修改代码时,会以 Diff 视图展示变更:
- Accept:接受修改,变更写入文件。
- Reject:拒绝修改,文件保持原样。
操作建议:不要一键全部接受。逐段审查 Diff,确认每处修改的合理性后再接受。AI 可能在不相关的位置做出意外修改。
4.7 代码补全
原理讲解
CodeBuddy 的代码补全是实时触发的,不需要手动按键激活:
- 触发时机:在编辑器中进行代码编写时,CodeBuddy 持续分析光标前后的上下文(函数名、变量类型、注释等)。
- Ghost Text 展示:AI 预测到可能的补全时,会以灰色文字(Ghost Text)的形式展示在光标后方。
- 接受/忽略:按
Tab接受补全,按Esc忽略。
高级特性:CodeBuddy 支持多行补全——如果上下文暗示需要生成一整段逻辑(如在注释中描述了功能),补全可能是数行代码。
示例:触发代码补全
操作步骤:
- 在 JS 文件中输入以下注释:
// 将数组中的每个元素乘以 2,返回新数组 function doubleArray(arr) { - 换行后,观察光标后是否出现 Ghost Text。
- 如果补全内容正确,按
Tab接受。
预期 Ghost Text(灰色文字示例):
return arr.map(item => item * 2);
调试过程
场景:代码补全一直没有出现
现象:打了很多代码,始终没有看到灰色补全提示。
原因排查:
1. 网络连接问题——补全功能依赖云端模型,网络不通则不工作。
2. 扩展未成功登录——右下角检查登录状态。
3. 文件类型不支持——某些冷门语言可能没有补全服务。
排查步骤:
1. 检查 VS Code 右下角状态栏的 CodeBuddy 图标,确认登录状态正常。
2. 尝试在一个 JS/Python/TS 等主流语言文件中输入注释测试。
3. 检查网络:ping copilot.tencent.com 看是否连通。
修复:
- 如果未登录,点击图标重新登录。
- 如果是网络问题,检查代理/VPN 设置。
4.8 终端集成
CodeBuddy 内置终端支持 AI 辅助,在终端操作时也能调用 AI 能力。
典型用法:终端执行报错 → 选中错误信息 → 按内联编辑快捷键 → 让 AI 分析并修复。
4.9 内置预览
项目启动后(如 npm run dev),点击工具栏预览按钮,CodeBuddy 会在编辑器内打开预览链接,无需切换到浏览器。
五、云部署实战:贪吃蛇小游戏
这一节通过一个完整案例,演示如何从零到一完成一个项目的云部署。
5.1 原理讲解
CodeBuddy 的云部署本质是自动化 CI/CD 管道:
- 项目识别:CodeBuddy 分析项目结构,识别构建工具(Vite / Webpack / Next.js 等)和输出目录。
- 构建执行:在云端或本地容器中执行
npm install+npm run build。 - 资源上传:将构建产物(
dist/或build/)上传到指定的云平台。 - 域名绑定:自动生成公网访问 URL(如
xxx.edgeone.app),并生成二维码便于移动端扫码访问。
支持的部署平台:
| 平台 | 说明 |
|---|---|
| Tencent Cloud Studio | 腾讯云端 IDE,每月 10000 分钟免费 |
| EdgeOne Pages | 前端开发和部署平台,自动生成公网域名 |
5.2 示例:部署贪吃蛇小游戏
项目代码:完整可运行的贪吃蛇游戏
创建项目文件夹 snake-game,在其中创建 index.html:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>贪吃蛇小游戏</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.game-container {
text-align: center;
background: rgba(255, 255, 255, 0.05);
border-radius: 20px;
padding: 30px;
backdrop-filter: blur(10px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}
h1 {
color: #00ff88;
margin-bottom: 10px;
font-size: 2rem;
letter-spacing: 2px;
}
.score-board {
display: flex;
justify-content: center;
gap: 30px;
margin-bottom: 20px;
}
.score-item {
color: #ccc;
font-size: 1.1rem;
}
.score-item span {
color: #00ff88;
font-weight: bold;
font-size: 1.4rem;
margin-left: 5px;
}
canvas {
border: 2px solid #00ff88;
border-radius: 8px;
display: block;
background: #0a0a1a;
}
.controls {
margin-top: 20px;
}
.controls p {
color: #888;
margin-bottom: 10px;
}
.btn {
background: #00ff88;
color: #1a1a2e;
border: none;
padding: 12px 30px;
font-size: 1rem;
font-weight: bold;
border-radius: 8px;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 4px 15px rgba(0, 255, 136, 0.4);
}
.game-over-overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #ff4444;
font-size: 2rem;
font-weight: bold;
pointer-events: none;
opacity: 0;
transition: opacity 0.3s;
text-shadow: 0 0 10px rgba(255, 68, 68, 0.8);
}
.game-over-overlay.visible {
opacity: 1;
}
</style>
</head>
<body>
<div class="game-container">
<h1>🐍 贪吃蛇</h1>
<div class="score-board">
<div class="score-item">得分 <span id="score">0</span></div>
<div class="score-item">最高分 <span id="highScore">0</span></div>
</div>
<div style="position: relative;">
<canvas id="gameCanvas" width="400" height="400"></canvas>
<div class="game-over-overlay" id="gameOver">游戏结束!</div>
</div>
<div class="controls">
<p>方向键 / WASD 控制移动 | 空格键暂停</p>
<button class="btn" id="restartBtn">重新开始</button>
</div>
</div>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreEl = document.getElementById('score');
const highScoreEl = document.getElementById('highScore');
const gameOverEl = document.getElementById('gameOver');
const restartBtn = document.getElementById('restartBtn');
// 游戏配置
const GRID_SIZE = 20;
const CELL_SIZE = canvas.width / GRID_SIZE;
const BASE_SPEED = 100; // 基础速度(毫秒/帧)
// 游戏状态
let snake = [];
let food = {};
let direction = { x: 1, y: 0 };
let nextDirection = { x: 1, y: 0 };
let score = 0;
let highScore = 0;
let gameRunning = false;
let gamePaused = false;
let gameLoop = null;
let speed = BASE_SPEED;
// 从 localStorage 读取最高分
try {
highScore = parseInt(localStorage.getItem('snakeHighScore')) || 0;
highScoreEl.textContent = highScore;
} catch (e) {
// localStorage 不可用时忽略
}
/**
* 初始化游戏
*/
function initGame() {
// 蛇初始位置:中间偏左,长度为 3
snake = [
{ x: 10, y: 10 },
{ x: 9, y: 10 },
{ x: 8, y: 10 },
];
direction = { x: 1, y: 0 };
nextDirection = { x: 1, y: 0 };
score = 0;
speed = BASE_SPEED;
gamePaused = false;
gameOverEl.classList.remove('visible');
scoreEl.textContent = '0';
generateFood();
}
/**
* 在空白位置随机生成食物
*/
function generateFood() {
const occupied = new Set(snake.map(s => `${s.x},${s.y}`));
const available = [];
for (let x = 0; x < GRID_SIZE; x++) {
for (let y = 0; y < GRID_SIZE; y++) {
if (!occupied.has(`${x},${y}`)) {
available.push({ x, y });
}
}
}
if (available.length === 0) {
// 蛇已经占满所有格子 = 胜利!
endGame(true);
return;
}
food = available[Math.floor(Math.random() * available.length)];
}
/**
* 游戏主循环
*/
function update() {
if (!gameRunning || gamePaused) return;
// 应用方向
direction = { ...nextDirection };
// 计算新头部位置
const head = snake[0];
const newHead = {
x: head.x + direction.x,
y: head.y + direction.y,
};
// 检测墙壁碰撞
if (
newHead.x < 0 || newHead.x >= GRID_SIZE ||
newHead.y < 0 || newHead.y >= GRID_SIZE
) {
endGame(false);
return;
}
// 检测自身碰撞(排除尾部,因为尾部即将移除)
for (let i = 0; i < snake.length - 1; i++) {
if (snake[i].x === newHead.x && snake[i].y === newHead.y) {
endGame(false);
return;
}
}
// 添加新头部
snake.unshift(newHead);
// 是否吃到食物
if (newHead.x === food.x && newHead.y === food.y) {
score += 10;
scoreEl.textContent = score;
// 每吃 5 个食物加速一次
if (score % 50 === 0 && speed > 40) {
speed -= 10;
clearInterval(gameLoop);
gameLoop = setInterval(update, speed);
}
generateFood();
} else {
// 移除尾部
snake.pop();
}
draw();
}
/**
* 渲染画面
*/
function draw() {
// 清空画布
ctx.fillStyle = '#0a0a1a';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制网格线(弱化)
ctx.strokeStyle = 'rgba(255, 255, 255, 0.03)';
ctx.lineWidth = 0.5;
for (let i = 0; i <= GRID_SIZE; i++) {
ctx.beginPath();
ctx.moveTo(i * CELL_SIZE, 0);
ctx.lineTo(i * CELL_SIZE, canvas.height);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0, i * CELL_SIZE);
ctx.lineTo(canvas.width, i * CELL_SIZE);
ctx.stroke();
}
// 绘制食物(脉冲动画效果)
const pulse = 1 + 0.15 * Math.sin(Date.now() / 200);
const foodX = food.x * CELL_SIZE + CELL_SIZE / 2;
const foodY = food.y * CELL_SIZE + CELL_SIZE / 2;
const foodRadius = (CELL_SIZE / 2 - 2) * pulse;
ctx.fillStyle = '#ff4444';
ctx.shadowColor = '#ff4444';
ctx.shadowBlur = 10;
ctx.beginPath();
ctx.arc(foodX, foodY, foodRadius, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
// 绘制蛇身
snake.forEach((segment, index) => {
const x = segment.x * CELL_SIZE;
const y = segment.y * CELL_SIZE;
const padding = 1;
// 蛇头颜色不同
if (index === 0) {
ctx.fillStyle = '#00ff88';
ctx.shadowColor = '#00ff88';
ctx.shadowBlur = 8;
} else {
// 渐变颜色:越靠近尾部越暗
const alpha = 1 - (index / snake.length) * 0.6;
ctx.fillStyle = `rgba(0, 200, 100, ${alpha})`;
ctx.shadowBlur = 0;
}
ctx.beginPath();
ctx.roundRect(
x + padding,
y + padding,
CELL_SIZE - padding * 2,
CELL_SIZE - padding * 2,
3
);
ctx.fill();
});
ctx.shadowBlur = 0;
}
/**
* 结束游戏
* @param {boolean} won - 是否胜利
*/
function endGame(won) {
gameRunning = false;
clearInterval(gameLoop);
if (won) {
gameOverEl.textContent = '🎉 恭喜通关!';
gameOverEl.style.color = '#00ff88';
} else {
gameOverEl.textContent = '游戏结束!';
gameOverEl.style.color = '#ff4444';
}
gameOverEl.classList.add('visible');
// 更新最高分
if (score > highScore) {
highScore = score;
highScoreEl.textContent = highScore;
try {
localStorage.setItem('snakeHighScore', highScore);
} catch (e) {
// ignore
}
}
}
/**
* 开始游戏
*/
function startGame() {
initGame();
gameRunning = true;
draw();
if (gameLoop) clearInterval(gameLoop);
gameLoop = setInterval(update, speed);
}
// 键盘控制
document.addEventListener('keydown', (e) => {
if (!gameRunning && e.key !== 'r') return;
switch (e.key) {
case 'ArrowUp':
case 'w':
case 'W':
e.preventDefault();
if (direction.y !== 1) {
nextDirection = { x: 0, y: -1 };
}
break;
case 'ArrowDown':
case 's':
case 'S':
e.preventDefault();
if (direction.y !== -1) {
nextDirection = { x: 0, y: 1 };
}
break;
case 'ArrowLeft':
case 'a':
case 'A':
e.preventDefault();
if (direction.x !== 1) {
nextDirection = { x: -1, y: 0 };
}
break;
case 'ArrowRight':
case 'd':
case 'D':
e.preventDefault();
if (direction.x !== -1) {
nextDirection = { x: 1, y: 0 };
}
break;
case ' ':
e.preventDefault();
if (gameRunning) {
gamePaused = !gamePaused;
gameOverEl.textContent = '已暂停';
gameOverEl.style.color = '#ffaa00';
if (gamePaused) {
gameOverEl.classList.add('visible');
} else {
gameOverEl.classList.remove('visible');
}
}
break;
}
});
// 重新开始按钮
restartBtn.addEventListener('click', startGame);
// 自动开始
startGame();
</script>
</body>
</html>
部署步骤
步骤 1:准备项目
将上述代码保存为 snake-game/index.html,确保文件可以正常打开和游玩。
步骤 2:配置 CloudStudio MCP
- 访问 Cloud Studio 控制台,进入 设置 → 访问令牌。
- 登录腾讯云账号,生成 API Token(复制保存,仅显示一次)。
- 在 CodeBuddy 中打开 设置 → MCP,添加 CloudStudio MCP 服务。
- 将生成的 API Token 填入配置并保存。
步骤 3:一键部署
- 点击 CodeBuddy 工具栏的部署按钮。
- 选择 Tencent Cloud Studio 或 EdgeOne Pages。
- 首次使用需授权登录腾讯云账号。
- 点击 Deploy,CodeBuddy 自动完成构建和部署。
- 部署成功后自动生成访问链接和二维码。
步骤 4:验证部署
- 在浏览器中打开生成的链接。
- 使用方向键控制蛇的移动。
- 确认吃食物后分数增长,撞墙后显示"游戏结束"。
- 扫码在手机上测试移动端体验。
管理已部署应用
在应用管理中可查看已部署的应用,支持在线修改云端代码。
调试过程
场景一:部署失败,提示 Token 无效
现象:点击 Deploy 后报错 "Authentication failed" 或 "Invalid token"。
原因排查:
1. API Token 过期或被撤销。
2. Token 在复制粘贴时遗漏了部分字符。
3. Token 权限不足。
排查步骤:
1. 登录 Cloud Studio 控制台,检查 Token 状态。
2. 如果 Token 已过期,重新生成一个。
3. 在 CodeBuddy MCP 设置中重新填入完整 Token。
4. 确认 Token 具有部署所需权限(建议生成时勾选全部权限)。
修复:重新生成 Token 并配置。
场景二:构建失败
现象:部署过程中报错 "Build failed"。
原因排查:
1. 项目依赖未声明(如缺少 package.json)。
2. 构建命令不正确。
3. 构建产物路径与预期不符。
排查步骤:
1. 对于纯 HTML 项目(如本例),不需要构建步骤,
确认选择了"静态网站"类型的部署方式。
2. 如果是有构建步骤的项目,检查 package.json 中的 build 脚本。
3. 在本地先执行 npm run build,确认构建成功后再部署。
修复:
- 纯静态项目:直接上传文件,跳过构建。
- 前端框架项目:确保 package.json 中的 scripts.build 指向正确命令。
场景三:部署成功但页面空白
现象:打开部署链接后页面一片空白,控制台有报错。
原因排查:
1. HTML 文件编码问题(如中文乱码导致 JS 解析失败)。
2. 资源路径问题(使用了绝对路径而非相对路径)。
3. 使用了部署平台不支持的 API。
排查步骤:
1. 打开浏览器开发者工具(F12),查看 Console 报错。
2. 检查 Network 面板,确认所有资源都成功加载(状态码 200)。
3. 确认 HTML 文件头部有 <meta charset="UTF-8">。
修复依据具体报错:
- 编码问题:确保文件以 UTF-8 编码保存。
- 路径问题:将所有路径改为相对路径(如 ./style.css 而非 /style.css)。
六、快捷键速查
| 功能 | Windows | macOS |
|---|---|---|
| 内联编辑 | Alt + K | Cmd + K |
| 接受补全 | Tab | Tab |
| 忽略补全 | Esc | Esc |
| 新建对话 | Ctrl + Shift + L | Cmd + Shift + L |
七、常见问题排查
7.1 终端无法执行命令
现象:在 CodeBuddy 内置终端中执行命令无反应或报错。
原因:VS Code 的 Terminal Shell Integration 未启用。
排查:
VS Code 设置 → 搜索 "shell" →
确保 "Terminal > Integrated > Shell Integration: Enabled" 设为 true。
修复:启用后重启 VS Code。
7.2 C/C++ 扩展安装失败
现象:安装 C/C++ 语言扩展时报错。
原因:扩展版本与当前环境不兼容。
修复:
1. 尝试安装较低版本(在扩展页面点击齿轮 → 安装其他版本)。
2. 或改用 clangd 替代微软 C/C++ 扩展。
7.3 国内市场下载慢
现象:npm 安装速度极慢或超时。
原因:默认 npm registry 在国外。
修复:
npm config set registry https://registry.npmmirror.com/
7.4 CodeBuddy 登录后闪退
现象:登录成功后 IDE 闪退或卡死。
原因排查:
1. 系统资源不足(尤其是低配机器)。
2. 与其他扩展冲突。
排查步骤:
1. 关闭 VS Code,以安全模式启动(code --disable-extensions)。
2. 逐一启用扩展,定位冲突源。
修复:
- 如果内存不足,关闭不必要应用。
- 如果扩展冲突,禁用冲突扩展或向 CodeBuddy 团队反馈。
7.5 AI 回复内容质量差
现象:AI 生成的代码质量低,或答非所问。
原因排查:
1. 上下文不足:没有通过 @ 引用相关文件。
2. 问题描述不清晰:过于笼统或模糊。
3. 对话历史过长:上下文窗口被无关内容占满。
排查步骤:
1. 确保通过 @file / @folder 引用了相关代码文件。
2. 将需求拆分为具体的小步骤,逐条提问。
3. 如果对话很长,新建对话重新开始。
修复:遵循"具体>笼统、小步>大步、有上下文>无上下文"的原则提问。