中国版 Cursor---腾讯云 CodeBuddy | 从安装VSCode到数独小游戏问世
引言
在正文开始之前,先引入一下故事背景:其实,自己最初选择编程行业,也是想自己开发一个小游戏啥的,主要是为了娱乐。没想到进入了编程行业之后,就变成了后端Java 开发者,虽然可能和自己期望的有点差距,但是在Java 语言行业待久了,也就习惯了。只是心里对于做一个小游戏的念想一直还在。恰逢中国版Cursor—- 腾讯云CodeBuddy 来了,对于小游戏的实现也看到了曙光,下面闲话少说,先来介绍一下我们今天的主角。什么是CodeBuddy?
CodeBuddy
腾讯云CodeBuddy,也就是腾讯云代码助手,是由腾讯云自研的一款编程提效辅助工具,以插件形式安装到编辑器(VS Code 或者 JetBrains 系列 IDE)中辅助编程;是基于腾讯混元+DeepSeek双轮模型,为开发者提供AI 技术问答、全新开发智能体Craft、代码补全、单元测试、代码诊断和智能评审等多Agent能力,兼容MCP 开放生态,并支持团队知识库管理、自定义智能体等功能,辅助开发者提高编码效率和质量,助力开发者提质增效。
腾讯云CodeBuddy 目前支持的语言及框架,理论上,腾讯云代码助手不限制任何类型的代码语言,甚至对于中文内容的输入,都能进行自动补全
在对腾讯云CodeBuddy 有了基础的了解之后,下面我们直接来上手感受一下吧。正所谓“纸上得来终觉浅,绝知此事要躬行”,就是这个道理。
环境准备
在开始做自己的小游戏之前,首先需要定个游戏设计方向。那么作为我个人的话,比较喜欢的数独小游戏,那么我们今天的目标就是基于腾讯云 CodeBuddy 来0手写代码实现数独小游戏。那么有了小游戏开发方向之后,我们就需要先准备好我们的开发工具,这里我们需要用到的是vscode 前端开发工具。这个个人作为一个java 后端开发者,本地电脑还没有前端开发工具环境,那么这里我就先准备一下环境吧。
VSCode
这里我找到了VSCode 的官方下载网址:https://code.visualstudio.com/Download 在浏览器打开网址后,你可以根据自身电脑不同的操作系统选择不同的vscode 版本,这里我选择 Windows 版本的 vscode 并下载
下载完成后,直接双击VSCodeUserSetup-x64-1.100.0.exe 打开文件,选择同意协议后指定 D盘安装,默认是C盘,但是考虑到系统盘磁盘容易满,影响电脑开机速度,这里我选择 D盘
后面其他的选择默认即可,等待 vscode 安装完成之后就可以看到如下页面
点击【完成】启动vscode,下面我们就需要为我们的vscode 安装腾讯云 CodeBuddy 插件。
CodeBuddy
在安装CodeBuddy 之前,首先需要确定你本地开发工具 IDE 满足版本要求,如果你本地的开发工具不能满足 CodeBuddy 对开发工具 的最低版本要求,那么需要你升级本地开发工具后再次尝试后面的安装
在打开的vscode 开发工具页面,点击【设置】-【Extensions】,在搜索框中输入【腾讯云代码助手】,点击【Install】
在弹出的弹框【Do you trust the publisher “Tencent Cloud”?】中选择【Trust Publisher & Install】开始安装CodeBuddy 插件
安装完成后微信扫码登录 CodeBuddy 后就可以看到我们的 vscode 开发工具页面已经有了CodeBuddy 的操作页面
Node.js下载安装
这里如果你的本地没有安装Node.js 的话,你需要在你的本地先安装Node.js,后面会用到。在浏览器打开Node.js 的官网地址:https://nodejs.org/zh-cn 在官网首页直接点击【下载Node.js (LTS)】下载Node.js 到本地并双击安装
整个安装过程全部默认即可,安装完成后打开cmd 命令输入以下命令验证 Node.js 是否安装成功
node -v
npm -v
执行完成后可以看到如下内容,表示Node.js 安装成功
游戏开发
在上面我们已经安装好了我们的 vscode 开发工具以及CodeBuddy AI 代码辅助编程工具,那么下面我们就来提出我们的想法吧。
Craft模型
腾讯云 Craft 预置了 hunyuan 和 deepseek-v3最新模型,默认(default)为 hunyuan 模型,支持你对模型进行切换,这里我们就默认选择就可以
一句话生成数独游戏
其实从AI 对话发展到现在,大家对于与AI 对话的技巧上基本上都有一定的认知了,想让AI 回答准确的话,那么最常用的就是定角色(是什么)+发任务(做什么)+提要求(什么要求)。
那么我的需求就出来了【你是一个小游戏开发专家,具有丰富的游戏开发经验,我需要你开发一个数独小游戏,需要支持难,中,易三种难易度切换,锻炼玩家数字敏感性。现在,帮我生成完整的代码吧。】在输入我们的要求后,Craft会对我们的需求进行一个分析整理,包括游戏的核心功能、复杂度评估、实现计划等
让我们在心里首先对我们的需求有一个大概的直观的认识,随后Craft 会按照上面设定好的【实现计划】逐步生成对应的文件。首先开始生成第一个文件,文件生成之后需要我们点击【修改】确认,然后才会进行下一步的任务代码生成,或者我们也可以直接设置【每次询问】为【自动修改文件】
等待所有文件全部生成完成之后,Craft 会直接在AI 对话内容展示区域提示【数独游戏开发完成】并对已经创建的文件进行一个简单的介绍。在文件接受区域我们选择【全部接受】就可以完成本次数独游戏开发整个计划中新建文件的保存
这里Craft 除了生成数独游戏需要的文件外,还对当前数独游戏的功能特点(包括游戏的难易度介绍、游戏特性自动生成题目、答案检查等)以及如何运行游戏都进行了详细的说明,方便我们后续直接体验
游戏体验
下面我们按照Craft 的提示找到 index.html 的文件,选中 index.html 文件后右键选择【Copy Path】,可以获取到 index.html 文件的本地路径,
我们将复制的 index.html 本地路径地址放在浏览器,可以看到我们的数独小游戏已经成功展现在我们的面前了,从色彩搭配上以及功能上,感觉还是很不错的。同时数独游戏也具备了我们在生成游戏时提出的需要数独游戏具有难中易三种难度切换的需求,下面我们来看一下效果吧
这里我简单体验了一下,效果很不错,每完成一个可以再次点击【新游戏】重新开始,闲暇之余放松身心,让大脑换个方向运转一下,体验感还是不错的。那么到这里我想,是不是可以给页面增加一个计时的展示,不然都不知道自己玩数独游戏有没有提升,加了计时器之后,就可以方便的看到我们完成当前的数独游戏耗时多少,于是我继续提出我的需求【为数独游戏增加一个计时功能,可以看到每一局耗时多少,展示形式以分钟:秒 的形式展示】这里我们可以看到,在收到我们的需求后,Craft 会对当前的需求进行分析后,基于现有的页面进行功能的改造,
这里我们可以看到Craft 在对现有的文件进行修改的时候,会基于已经发生的情况再次就行判断修改,就像上面对我们的script.js 文件进行了多轮次的分析修改,最终完成对数独游戏计时功能的添加。下面我们在浏览器刷新我们的本地 index.html 页面,就可以看到我们的数独游戏已经增加了计时功能,同时每次点击【新游戏】会自动重置计时器
在官方文档关于VSCode 插件更新记录中我们可以看到,本次 VSCode 的CodeBuddy 插件更新后的Craft 支持 MCP 扩展能力,支持在 MCP 市场中主流 MCP 服务一键安装、自定义配置 MCP
那么既然Craft 支持 MCP扩展能力,那么这么好玩的数独游戏,只能自己在本地玩儿的话,是不是有点太小气了,完全可以通过MCP 来发布出来让大家都可以体验一下数独游戏的魅力,正所谓“独乐乐不如众乐乐”,下面说干就干。在开始之前先容我介绍一下后面用到的EdgeOne Pages 和 MCP ,方便大家更好的理解为什么可以这么干。
EdgeOne Pages
什么是EdgeOne Pages?EdgeOne Pages 是基于 Tencent EdgeOne 基础设施打造的前端开发和部署平台,专为现代 Web 开发设计,帮助开发者快速构建、部署静态站点和无服务器应用。通过集成边缘函数能力,实现高效的内容交付和动态功能扩展,支持全球用户的快速访问。
我们使用 EdgeOne Pages,可以高效快速的构建、部署无服务应用,从而大大缩短从代码编写到部署上线的时间,保证项目的快速迭代,帮助企业迅速应对市场需求;同时无需配置和管理服务器等基础设施,通过 JS 在靠近用户的边缘节点编写超低延时的服务端逻辑。而本地部署,一方面需要依赖特定运行时环境(如 Node.js、Python 或 Docker),限制了可落地的应用场景,操作复杂,另一方面对技术有一定要求,需要有一定的技术基础才能操作,导致应用相对会收到限制。
MCP
那么什么是MCP呢?MCP 是模型上下文协议(Model Context Protocol)的简称,是一个开源协议,由Anthropic(Claude开发公司)开发,旨在让大型语言模型(LLM)能够以标准化的方式连接到外部数据源和工具。有了 MCP 标准协议,就像给 AI 大模型装了一个 “万能接口”,让 AI 模型能够与不同的数据源和工具进行无缝交互。它就像 USB-C 接口一样,提供了一种标准化的方法,将 AI 模型连接到各种数据源和工具。同时,MCP 可以在不同的应用 / 服务之间保持上下文,增强整体自主执行任务的能力
Pages MCP Server
那么什么是Pages MCP Server?EdgeOne Pages Deploy MCP 是一项专用服务,能够将 HTML 内容快速部署到 EdgeOne Pages 并生成公开访问链接。看到没,刚才我说的,自己用Craft 生成了一个数独游戏,但是只能自己在本地玩儿,有点太小气,那么我们就可以通过EdgeOne Pages Deploy MCP 将我们的数独小游戏 HTML 页面快速部署到EdgeOne Pages 并生成公开访问链接,有了公开访问链接,我们就可以让更多的小伙伴一起玩耍起来了。
配置 MCP Server
那么我们首先需要为我们的开发工具 VSCode的 Craft 配置 MCP Server ,点击AI 对话框 的MCP 图标
在CodeBuddy 对话框选择【MCP 市场】,找到我们需要的MCP 并点击右侧的【安装】,这里需要说明的是如果本地没有安装Node.js 的话,这里点击安装会安装失败,需要你安装Node.js之后再尝试
安装完成后,切换tab的【已安装】后打开json 参数配置页面
在右侧打开的配置 MCP Server 的文件【Craft_mcp_settings.json】中输入一下配置内容后保存配置文件
{
"mcpServers": {
"edgeone-pages-mcp-server": {
"command": "npx",
"args": ["edgeone-pages-mcp"]
}
}
}
复制上面配置到 Craft_mcp_settings.json 文件后可以看到 MCP Server 已经到达正常状态
点击MCP Server 的执行按钮,可以在我们的Craft 对话框看到如下测试内容
访问测试页面地址可以看到已经发布成功的测试页面的内容
下面我们在Craft 的AI 对话框中输入我们的需求【通过我们配置的edgeone-pages-mcp-server发布我们生成的数独小游戏】,但是这里提示完成扫描目录之后没找到之前生成的数独游戏文件,可能是因为我重启电脑后导致原来的会话丢失,
但是我看到上一次数独游戏的文件还在本地,那么我通过选择文件的方式再次尝试发布数独小游戏
第一次选择文件发布尝试失败,可能是网络波动问题导致,
再次在选择了指定数独小游戏的文件AI 对话框中输入【发布我们已经生成的数独小游戏】后,等待了大概5分钟终于看到发布成功了,
以及完整的游戏说明,游戏访问链接:https://mcp.edgeone.site/share/n6K0vNGxD3GuMuQyVD3sZ
游戏源码
这里想到大家可能有需要,想要自己在本地基于现有我生成的这一版数独小游戏再次进行优化尝试,那么这里我将Craft 生成的数独小程序的源码贴出来供大家选择,这里需要说明一点的是,整个数独小游戏的源码我一个字母也没有敲,完全是Craft 为我生成的我直接用的,下面提供相应的源码
index.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>数独游戏</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>数独游戏</h1>
<div class="controls">
<div class="timer" id="timer">00:00</div>
<select id="difficulty">
<option value="easy">简单</option>
<option value="medium">中等</option>
<option value="hard">困难</option>
</select>
<button id="new-game">新游戏</button>
</div>
<div class="board" id="board">
<!-- 9x9的数独格子将由JavaScript动态生成 -->
</div>
<div class="message" id="message"></div>
<button id="check">检查答案</button>
</div>
<script src="script.js"></script>
</body>
</html>
style.css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.container {
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
h1 {
text-align: center;
color: #333;
margin-bottom: 20px;
}
.controls {
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
margin-bottom: 20px;
}
.timer {
background-color: #333;
color: #fff;
padding: 8px 16px;
border-radius: 5px;
font-size: 18px;
font-family: monospace;
min-width: 80px;
text-align: center;
}
select, button {
padding: 8px 16px;
font-size: 16px;
border: none;
border-radius: 5px;
cursor: pointer;
}
select {
background-color: #fff;
border: 1px solid #ccc;
}
button {
background-color: #4CAF50;
color: white;
transition: background-color 0.3s;
}
button:hover {
background-color: #45a049;
}
.board {
display: grid;
grid-template-columns: repeat(9, 1fr);
gap: 1px;
background-color: #999;
border: 2px solid #333;
margin-bottom: 20px;
}
.cell {
width: 40px;
height: 40px;
background-color: white;
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
font-weight: bold;
}
.cell input {
width: 100%;
height: 100%;
border: none;
text-align: center;
font-size: 20px;
font-weight: bold;
color: #444;
}
.cell input:focus {
outline: none;
background-color: #e8f0fe;
}
.cell.given {
background-color: #f0f0f0;
}
.cell.invalid {
background-color: #ffebee;
}
/* 3x3宫格边框 */
.cell:nth-child(3n) {
border-right: 2px solid #333;
}
.cell:nth-child(9n) {
border-right: none;
}
.board > div:nth-child(n+19):nth-child(-n+27),
.board > div:nth-child(n+46):nth-child(-n+54) {
border-bottom: 2px solid #333;
}
.message {
text-align: center;
margin: 10px 0;
padding: 10px;
border-radius: 5px;
display: none;
}
.message.success {
display: block;
background-color: #e8f5e9;
color: #2e7d32;
}
.message.error {
display: block;
background-color: #ffebee;
color: #c62828;
}
@media (max-width: 500px) {
.cell {
width: 30px;
height: 30px;
font-size: 16px;
}
.cell input {
font-size: 16px;
}
.container {
padding: 10px;
}
}
script.js
class Sudoku {
constructor() {
this.board = Array(9).fill().map(() => Array(9).fill(0));
this.solution = Array(9).fill().map(() => Array(9).fill(0));
}
// 生成新游戏
generate(difficulty) {
// 清空棋盘
this.board = Array(9).fill().map(() => Array(9).fill(0));
this.solution = Array(9).fill().map(() => Array(9).fill(0));
// 生成完整的解决方案
this.fillBoard(0, 0);
// 复制解决方案
this.solution = this.board.map(row => [...row]);
// 根据难度挖空
this.removeNumbers(difficulty);
}
// 填充数独板(回溯算法)
fillBoard(row, col) {
if (col >= 9) {
row++;
col = 0;
}
if (row >= 9) {
return true;
}
const numbers = this.shuffle([1, 2, 3, 4, 5, 6, 7, 8, 9]);
for (let num of numbers) {
if (this.isValid(row, col, num)) {
this.board[row][col] = num;
if (this.fillBoard(row, col + 1)) {
return true;
}
this.board[row][col] = 0;
}
}
return false;
}
// 检查数字在当前位置是否有效
isValid(row, col, num) {
// 检查行
for (let x = 0; x < 9; x++) {
if (this.board[row][x] === num) return false;
}
// 检查列
for (let x = 0; x < 9; x++) {
if (this.board[x][col] === num) return false;
}
// 检查3x3方格
let startRow = row - row % 3;
let startCol = col - col % 3;
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (this.board[i + startRow][j + startCol] === num) return false;
}
}
return true;
}
// 随机打乱数组
shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
// 根据难度移除数字
removeNumbers(difficulty) {
let cellsToRemove;
switch(difficulty) {
case 'easy':
cellsToRemove = 40; // 保留41个数字
break;
case 'medium':
cellsToRemove = 50; // 保留31个数字
break;
case 'hard':
cellsToRemove = 60; // 保留21个数字
break;
default:
cellsToRemove = 45;
}
let count = 0;
while (count < cellsToRemove) {
const row = Math.floor(Math.random() * 9);
const col = Math.floor(Math.random() * 9);
if (this.board[row][col] !== 0) {
this.board[row][col] = 0;
count++;
}
}
}
// 检查当前填写是否正确
checkSolution(currentBoard) {
for (let i = 0; i < 9; i++) {
for (let j = 0; j < 9; j++) {
if (currentBoard[i][j] !== this.solution[i][j]) {
return false;
}
}
}
return true;
}
}
// 游戏管理类
class Game {
constructor() {
this.sudoku = new Sudoku();
this.currentBoard = Array(9).fill().map(() => Array(9).fill(0));
this.timer = null;
this.startTime = null;
this.timerElement = null;
this.initializeGame();
}
// 格式化时间显示
formatTime(seconds) {
const minutes = Math.floor(seconds / 60);
const remainingSeconds = seconds % 60;
return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
}
// 启动计时器
startTimer() {
if (this.timer) {
clearInterval(this.timer);
}
this.startTime = Date.now();
this.timerElement.textContent = "00:00";
this.timer = setInterval(() => {
const currentTime = Date.now();
const elapsedSeconds = Math.floor((currentTime - this.startTime) / 1000);
this.timerElement.textContent = this.formatTime(elapsedSeconds);
}, 1000);
}
// 停止计时器
stopTimer() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
}
initializeGame() {
this.boardElement = document.getElementById('board');
this.messageElement = document.getElementById('message');
this.difficultySelect = document.getElementById('difficulty');
this.timerElement = document.getElementById('timer');
// 初始化事件监听
document.getElementById('new-game').addEventListener('click', () => {
this.startNewGame();
});
document.getElementById('check').addEventListener('click', () => {
this.checkGame();
});
// 开始新游戏
this.startNewGame();
}
startNewGame() {
const difficulty = this.difficultySelect.value;
this.sudoku.generate(difficulty);
this.currentBoard = this.sudoku.board.map(row => [...row]);
this.renderBoard();
this.messageElement.className = 'message';
this.messageElement.textContent = '';
// 启动新的计时器
this.startTimer();
}
renderBoard() {
this.boardElement.innerHTML = '';
for (let i = 0; i < 9; i++) {
for (let j = 0; j < 9; j++) {
const cell = document.createElement('div');
cell.className = 'cell';
if (this.currentBoard[i][j] !== 0) {
cell.classList.add('given');
cell.textContent = this.currentBoard[i][j];
} else {
const input = document.createElement('input');
input.type = 'number';
input.min = 1;
input.max = 9;
input.addEventListener('input', (e) => {
const value = parseInt(e.target.value) || 0;
if (value >= 0 && value <= 9) {
this.currentBoard[i][j] = value;
}
});
cell.appendChild(input);
}
this.boardElement.appendChild(cell);
}
}
}
checkGame() {
const isComplete = this.currentBoard.every(row =>
row.every(cell => cell !== 0)
);
if (!isComplete) {
this.messageElement.className = 'message error';
this.messageElement.textContent = '请填完所有空格!';
return;
}
const isCorrect = this.sudoku.checkSolution(this.currentBoard);
if (isCorrect) {
this.stopTimer();
const finalTime = this.timerElement.textContent;
this.messageElement.className = 'message success';
this.messageElement.textContent = `恭喜!你已经成功解开这个数独!完成时间:${finalTime}`;
} else {
this.messageElement.className = 'message error';
this.messageElement.textContent = '答案不正确,请继续尝试!';
}
}
}
// 启动游戏
window.addEventListener('DOMContentLoaded', () => {
new Game();
});
总结
到这里我想说,虽然我本身并不是前端开发者,前端开发工具VSCode也是今天刚下载安装的,Node.js 部署环境也是现装的,但是真的实现一个数独小游戏,却是一点也不难。感觉上就是有了CodeBuddy ,即使是陌生的环境,陌生的开发工具,一样可以达到自己期待的效果,并且效果还不错。
对于开发者来说,CodeBuddy的出现似乎打破了不同开发语言之间的壁垒,过去你可能说你精通一门语言之后,你再学习其他开发语言,你的学习效率会大大提升,但是大家注意,你还是有一个【学习】的过程,还是需要学习了之后才能接手开发。那么现在呢,有了CodeBuddy 之后,我不懂前端,我只要下载一个前端开发工具,安装腾讯云CodeBuddy 插件之后,我就可以在前端开发工具里面实现我想要的。我不懂python 开发语言,那么我下载了 PyCharm开发工具,同样安装了腾讯云CodeBuddy 插件后,我想实现的,比如数据抓取什么的,我掌握好AI对话三要素,我一样可以很高效的做到。
脑中闪现了一个梗,对于开发者来说,替代你的可能不是你的同行(相同语言开发者),而可能是你的跨行(不同语言开发者),就像娱乐圈一样,各种跨行表演,哈哈。