用trae完全自动化开发一款网页版的俄罗斯方块游戏

用trae完全自动化开发一款网页版的俄罗斯方块游戏

阅读原文

建议阅读原文,始终查看最新文档版本,获得最佳阅读体验:《用trae完全自动化开发一款网页版的俄罗斯方块游戏》

deepseek-R1-0528已经上传到Huggingface

参考资料:deepseek-ai/DeepSeek-R1-0528 · Hugging Face

2025年5月28日deepseek对deepseek R1模型进行了小幅度更新,据说编程性能大幅提升,甚至能媲美claude 4,我马上就想要测试一下。想着利用deepseek-R1-0528开发一个俄罗斯方块游戏。

可以看到,模型参数是6850亿,但当前还没有详细的模型描述

image.png

通过api询问当前聊天模型是否是最新的deepseek R1-0528版本的

curl --request POST \
  -H "Content-Type: application/json" \
  --header 'Authorization: Bearer <此处替换为你的deepseek API KEY>' \
  --url https://api.deepseek.com/chat/completions \
  --data '{"messages":[{"role":"user","content":"请问你是deepseek最新发布的DeepSeek R1-0528大模型吗?2025年5月28日发布的"}],"model":"deepseek-reasoner"}' | jq .

输出表明,通过api调用,仍然还是旧版本的deepseek R1(2025年5月29日14点测试的)

image.png

如果直接在网页端询问,给出的回答是最新版本的R1

image.png

让trae自动开发游戏

使用自定义大模型

我使用的是自定义的大模型,因为我本来以为通过api调用是可以用上最新版本的deepseek R1的。

image.png

提示词

提示词非常简单,就一句话“开发一款网页版的俄罗斯方块游戏”

image.pngimage.png

一开始生成的代码只能利用方向键移动方块,我希望除了这种方式,还能利用WASD键操作方块,更加符合人类的习惯。

image.png

生成的代码

代码也不多,只有三个文件

image.png

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>网页版俄罗斯方块</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="game-container">
        <h1>俄罗斯方块</h1>
        <div class="game-info">
            <div>分数: <span id="score">0</span></div>
            <div>等级: <span id="level">1</span></div>
            <div>下一块:</div>
            <canvas id="next-piece" width="100" height="100"></canvas>
        </div>
        <canvas id="game-board" width="300" height="600"></canvas>
        <div class="controls">
            <button id="start-btn">开始游戏</button>
            <button id="pause-btn">暂停</button>
        </div>
    </div>
    <script src="game.js"></script>
</body>
</html>
body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #f0f0f0;
    font-family: 'Microsoft YaHei', sans-serif;
}

.game-container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

h1 {
    color: #333;
    margin-bottom: 20px;
}

#game-board {
    border: 2px solid #333;
    background-color: #111;
}

.game-info {
    margin-bottom: 15px;
    text-align: center;
    font-size: 18px;
}

.controls {
    margin-top: 15px;
}

button {
    padding: 10px 20px;
    margin: 0 5px;
    font-size: 16px;
    cursor: pointer;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 4px;
}

button:hover {
    background-color: #45a049;
}

#next-piece {
    display: block;
    margin: 10px auto;
    background-color: #222;
}
// 游戏常量
const COLS = 10;
const ROWS = 20;
const BLOCK_SIZE = 30;
const COLORS = [
    null,
    '#FF0D72', // I
    '#0DC2FF', // J
    '#0DFF72', // L
    '#F538FF', // O
    '#FF8E0D', // S
    '#FFE138', // T
    '#3877FF'  // Z
];

// 方块形状定义
const SHAPES = [
    [],
    [[0,0,0,0], [1,1,1,1], [0,0,0,0], [0,0,0,0]], // I
    [[0,0,0], [1,0,0], [1,1,1], [0,0,0]],         // J
    [[0,0,0], [0,0,1], [1,1,1], [0,0,0]],         // L
    [[0,0,0,0], [0,1,1,0], [0,1,1,0], [0,0,0,0]], // O
    [[0,0,0], [0,1,1], [1,1,0], [0,0,0]],         // S
    [[0,0,0], [0,1,0], [1,1,1], [0,0,0]],         // T
    [[0,0,0], [1,1,0], [0,1,1], [0,0,0]]          // Z
];

// 游戏状态
let board = createBoard();
let score = 0;
let level = 1;
let gameOver = false;
let dropInterval = 1000; // 初始下落速度(毫秒)
let dropStart = Date.now();
let requestId = null;

// DOM元素
const canvas = document.getElementById('game-board');
const nextCanvas = document.getElementById('next-piece');
const ctx = canvas.getContext('2d');
const nextCtx = nextCanvas.getContext('2d');
const scoreElement = document.getElementById('score');
const levelElement = document.getElementById('level');
const startBtn = document.getElementById('start-btn');
const pauseBtn = document.getElementById('pause-btn');

// 初始化游戏板
function createBoard() {
    return Array.from(Array(ROWS), () => Array(COLS).fill(0));
}

// 当前方块
let piece = {
    pos: {x: 0, y: 0},
    matrix: null,
    type: null
};

// 下一个方块
let nextPiece = {
    matrix: null,
    type: null
};

// 绘制单个方块
function drawBlock(ctx, x, y, type) {
    ctx.fillStyle = COLORS[type];
    ctx.fillRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
    
    ctx.strokeStyle = '#000';
    ctx.lineWidth = 1;
    ctx.strokeRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
}

// 绘制游戏板
function drawBoard() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    
    // 绘制已落下的方块
    board.forEach((row, y) => {
        row.forEach((value, x) => {
            if (value !== 0) {
                drawBlock(ctx, x, y, value);
            }
        });
    });
    
    // 绘制当前方块
    if (piece.matrix) {
        piece.matrix.forEach((row, y) => {
            row.forEach((value, x) => {
                if (value !== 0) {
                    drawBlock(ctx, x + piece.pos.x, y + piece.pos.y, piece.type);
                }
            });
        });
    }
}

// 绘制下一个方块预览
function drawNextPiece() {
    nextCtx.clearRect(0, 0, nextCanvas.width, nextCanvas.height);
    
    if (nextPiece.matrix) {
        nextPiece.matrix.forEach((row, y) => {
            row.forEach((value, x) => {
                if (value !== 0) {
                    nextCtx.fillStyle = COLORS[nextPiece.type];
                    nextCtx.fillRect(x * 20, y * 20, 20, 20);
                    
                    nextCtx.strokeStyle = '#000';
                    nextCtx.lineWidth = 1;
                    nextCtx.strokeRect(x * 20, y * 20, 20, 20);
                }
            });
        });
    }
}

// 碰撞检测
function collide(board, piece) {
    const [m, o] = [piece.matrix, piece.pos];
    for (let y = 0; y < m.length; y++) {
        for (let x = 0; x < m[y].length; x++) {
            if (m[y][x] !== 0 &&
                (board[y + o.y] &&
                board[y + o.y][x + o.x]) !== 0) {
                return true;
            }
        }
    }
    return false;
}

// 旋转方块 - 修复非方阵旋转问题
function rotate(matrix) {
    const rows = matrix.length;
    const cols = matrix[0].length;
    const rotated = Array(cols).fill().map(() => Array(rows).fill(0));
    
    for (let y = 0; y < rows; y++) {
        for (let x = 0; x < cols; x++) {
            rotated[x][rows - 1 - y] = matrix[y][x];
        }
    }
    return rotated;
}

// 合并方块到游戏板
function merge(board, piece) {
    piece.matrix.forEach((row, y) => {
        row.forEach((value, x) => {
            if (value !== 0) {
                board[y + piece.pos.y][x + piece.pos.x] = piece.type;
            }
        });
    });
}

// 消除满行
function sweep() {
    let linesCleared = 0;
    
    outer: for (let y = ROWS - 1; y > 0; y--) {
        for (let x = 0; x < COLS; x++) {
            if (board[y][x] === 0) {
                continue outer;
            }
        }
        
        const row = board.splice(y, 1)[0].fill(0);
        board.unshift(row);
        linesCleared++;
        y++; // 重新检查当前行
    }
    
    if (linesCleared > 0) {
        // 更新分数
        score += [40, 100, 300, 1200][linesCleared - 1] * level;
        scoreElement.textContent = score;
        
        // 更新等级
        level = Math.floor(score / 1000) + 1;
        levelElement.textContent = level;
        
        // 加快下落速度
        dropInterval = Math.max(100, 1000 - (level - 1) * 100);
    }
}

// 创建新方块
function createPiece() {
    const type = Math.floor(Math.random() * 7) + 1;
    return {
        matrix: SHAPES[type],
        type: type
    };
}

// 重置当前方块
function resetPiece() {
    piece.matrix = nextPiece.matrix;
    piece.type = nextPiece.type;
    piece.pos.y = 0;
    piece.pos.x = Math.floor(COLS / 2) - Math.floor(piece.matrix[0].length / 2);
    
    nextPiece = createPiece();
    drawNextPiece();
    
    // 检查游戏结束
    if (collide(board, piece)) {
        gameOver = true;
        cancelAnimationFrame(requestId);
        alert(`游戏结束!最终得分: ${score}`);
    }
}

// 方块下落
function drop() {
    piece.pos.y++;
    if (collide(board, piece)) {
        piece.pos.y--;
        merge(board, piece);
        resetPiece();
        sweep();
    }
    dropStart = Date.now();
}

// 游戏主循环
function gameLoop() {
    if (gameOver) return;
    
    const now = Date.now();
    const delta = now - dropStart;
    
    if (delta > dropInterval) {
        drop();
    }
    
    drawBoard();
    requestId = requestAnimationFrame(gameLoop);
}

// 初始化游戏
function init() {
    board = createBoard();
    score = 0;
    level = 1;
    gameOver = false;
    dropInterval = 1000;
    
    scoreElement.textContent = score;
    levelElement.textContent = level;
    
    nextPiece = createPiece();
    resetPiece();
    drawBoard();
    drawNextPiece();
}

// 控制事件监听
document.addEventListener('keydown', event => {
    if (gameOver || !requestId) {  // 添加暂停状态检查
        return;
    }
    
    switch (event.keyCode) {
        case 37: // 左箭头
        case 65: // A键 (新增)
            piece.pos.x--;
            if (collide(board, piece)) piece.pos.x++;
            break;
        case 39: // 右箭头
        case 68: // D键 (新增)
            piece.pos.x++;
            if (collide(board, piece)) piece.pos.x--;
            break;
        case 40: // 下箭头
        case 83: // S键 (新增)
            drop();
            break;
        case 38: // 上箭头 (旋转)
        case 87: // W键 (新增)
            const rotated = rotate(piece.matrix);
            const original = piece.matrix;
            piece.matrix = rotated;
            if (collide(board, piece)) piece.matrix = original;
            break;
        case 32: // 空格键 (硬降落)
            event.preventDefault();  // 阻止空格键触发按钮点击
            while (!collide(board, piece)) {
                piece.pos.y++;
            }
            piece.pos.y--;
            merge(board, piece);
            resetPiece();
            sweep();
            break;
    }
});

// 按钮事件
startBtn.addEventListener('click', () => {
    if (gameOver) init();
    if (requestId) cancelAnimationFrame(requestId);
    gameOver = false;
    gameLoop();
});

pauseBtn.addEventListener('click', () => {
    if (gameOver) return;
    
    if (requestId) {
        cancelAnimationFrame(requestId);
        requestId = null;
        pauseBtn.textContent = '继续';
    } else {
        gameLoop();
        pauseBtn.textContent = '暂停';
    }
});

// 初始化游戏
init();

验证游戏

直接用浏览器打开index.html文件即可开始游戏

其实验证过程中,我发现了一个问题,就是如果单击了“继续”按钮后,再按空格,虽然方块确实会直接落地,但是游戏也暂停了。下面这个视频演示了这个问题

请至钉钉文档查看附件《网页版俄罗斯方块 和另外 12 个页面 - 个人 - Microsoft​ Edge 2025-05-29 14-55-56.mp4》

后来我让trae再调整代码,问题解决了。

请至钉钉文档查看附件《网页版俄罗斯方块 和另外 12 个页面 - 个人 - Microsoft​ Edge 2025-05-29 15-19-41.mp4》

关注微信公众号“AI发烧友”,获取更多IT开发运维实用工具与技巧,还有很多AI技术文档!

梦幻智能logo-01(无水印).png

### 使用 .NET 开发应用程序 #### 选择合适的集成开发环境 (IDE) 虽然可以使用简单的文本编辑器如记事本来编写 ASP.NET 应用程序[^1],但为了提高效率和减少错误,建议采用更专业的 IDE 如 Visual Studio。Visual Studio 提供了许多内置工具和服务来简化项目管理、调试以及部署过程。 #### 安装必要的软件包 要开始使用 .NET 构建 Web 应用程序,需先安装最新版本的 .NET SDK 和 Visual Studio 或其他支持 C# 的代码编辑器(例如 VS Code)。对于 Windows 用户来说,默认情况下可以选择安装 IIS Express 来作为本地服务器运行环境;而对于跨平台开发者,则可以通过 Kestrel 实现相同的功能。 #### 创建新的 ASP.NET Core Web 应用程序 在启动 Visual Studio 后,可以从模板中选取“ASP.NET Web Application (.NET Core)”选项新建一个解决方案文件夹并命名项目名称。这一步骤将自动生成基本结构化的源码目录树形图,并配置好 NuGet 包依赖关系表单以便后续添加额外库资源[^2]。 ```csharp // Program.cs 文件中的默认入口函数 public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); } ``` 此段代码展示了 `Program` 类里定义了一个静态方法 `Main()` ,它是整个应用程序执行流程的第一步。通过调用 `CreateHostBuilder()` 方法设置主机参数后返回给主线程继续处理请求直到结束为止。 #### 配置 Startup 设置 接着,在名为 `Startup.cs` 的类内部实现中间件管道逻辑与路由映射规则等功能模块。这里主要负责初始化服务容器并向 HTTP 请求响应周期注入所需组件实例化对象。 ```csharp public class Startup { // 此处省略构造函数... public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); // 添加 MVC 控制器的支持 } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { // 判断当前是否处于开发模式下 app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); // 强制 HTTPS 访问策略 } app.UseHttpsRedirection(); // 自动重定向至 HTTPS 协议连接 app.UseStaticFiles(); // 处理静态网页资源 app.UseRouting(); // 注册路由解析机制 app.UseAuthorization(); // 授权验证过滤器 app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); // 映射控制器动作到 URL 路径上 } } ``` 上述片段说明了如何利用 `ConfigureServices()` 函数注册各种服务提供者,而 `Configure()` 中则包含了更多关于应用行为的具体细节描述,比如异常页面显示方式的选择或是启用特定的安全特性等操作。 #### 编写业务逻辑代码 最后就是按照实际需求设计数据库模型实体类及其关联接口,再配合 Repository 模式或者 Dapper 微型 ORM 工具完成数据访问层部分的工作。与此同时也要记得遵循 RESTful API 设计原则去规划前后端交互协议标准,确保客户端能够顺利获取预期的数据结果集。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值