1、第一次使用Comate Zulu生成贪食蛇游戏的学思笔记.jpg
还记得我们上次的《第一次使用Trae AI生成贪食蛇游戏的学思笔记》吗?

我们反反复复对话了几次才搞定贪食蛇小游戏。

这次我们试试百度家的文心快码Baidu Comate。它家最新上线了Zulu模式。

什么是Comate Zulu

和我之前介绍的Cursor、Trae一样,Zulu 是文心快码(Baidu Comate)全新推出的自动编程智能体,用户通过全自然语言实现编程。

Zulu 现已开启公测,所有用户均可使用,免费用户可有限次体验。经测试,免费体验50次!

怎么安装Comate Zulu

请直接访问官网https://comate.baidu.com/zh/download

使用Comate Zulu生成贪食蛇游戏

为了和Tare对比,这次我们还是让Comate Zulu使用web技术栈生成一个贪食蛇游戏。

以下是我稍作整理的Comate Zulu的回答:

第1步、了解一下当前的项目结构

分析comate-zulu-demo文件夹。由于这个文件夹里没有任何文件,所以Comate Zulu认定这是一个新项目。

接着它按照Web应用开发流程来规划这个贪食蛇游戏项目。

第2步、需求分析与功能规划

核心玩法:经典贪食蛇游戏

  • 蛇可以通过键盘方向键控制移动方向
  • 随机生成食物,蛇吃到食物后长度增加
  • 撞到墙壁或自身则游戏结束

游戏特性:

  • 计分系统:记录当前分数
  • 游戏状态:开始、暂停、结束
  • 响应式设计:适配不同屏幕尺寸

技术选型:

  • 纯原生Web技术,不依赖任何框架
  • HTML5 Canvas:绘制游戏画面
  • JavaScript:游戏逻辑
  • CSS:页面布局和样式

项目结构规划:

├── index.html # 游戏主页面
├── css/style.css # 样式文件
└── js/game.js # 游戏逻辑

第3步、创建文件

  • 创建HTML主页面
  • 创建CSS文件夹和样式文件
  • 创建JavaScript游戏逻辑文件

第4步、验证文件结构是否正确

它又对comate-zulu-demo文件夹进行了分析。已经确认成功创建了所有必要的文件

第5步、总结项目

项目结构:

  • index.html:主页面
  • css/style.css:样式文件
  • js/game.js:游戏逻辑

技术栈:

  • HTML5:用于构建页面结构
  • CSS3:用于样式和布局
  • JavaScript:用于游戏逻辑和交互
  • HTML5 Canvas:用于绘制游戏画面

游戏功能:

  • 经典贪食蛇游戏玩法
  • 使用键盘方向键控制蛇的移动
  • 随机生成食物
  • 计分系统
  • 开始、暂停和重新开始功能
  • 游戏结束检测(撞墙或自身)

响应式设计:

  • 使用CSS媒体查询适配不同屏幕尺寸
  • 可以在浏览器中打开 index.html 文件来玩这个贪食蛇游戏。

以下是游戏的基本操作:

  • 点击"Start Game"按钮开始游戏
  • 使用键盘方向键(上、下、左、右)控制蛇的移动
  • 引导蛇吃到红色的食物来增加分数和长度
  • 避免撞到墙壁或蛇自身
  • 使用"Pause"按钮暂停游戏,再次点击继续
  • 游戏结束后,可以点击"Restart"按钮重新开始

可以通过以下命令在浏览器中打开游戏:

执行终端命令start index.html

游戏特点:

  • 使用HTML5 Canvas绘制游戏画面
  • 键盘方向键控制蛇的移动
  • 随机生成食物
  • 计分系统
  • 游戏状态管理(开始、暂停、重新开始)
  • 碰撞检测(墙壁和自身)
  • 响应式设计,适配不同屏幕尺寸

使用感受

很好很强大!编程执行很快!而且一轮对话就成功了!

我想成功的关键在于它会在结束前对项目进行检查。

2、第一次使用Comate Zulu生成贪食蛇游戏的学思笔记.jpg

附代码文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Snake Game</title>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <div class="game-container">
        <div class="game-header">
            <h1>Snake Game</h1>
            <div class="score">Score: <span id="score">0</span></div>
        </div>
        <canvas id="gameCanvas" width="400" height="400"></canvas>
        <div class="game-controls">
            <button id="startBtn">Start Game</button>
            <button id="pauseBtn">Pause</button>
        </div>
        <div class="game-instructions">
            <p>Use arrow keys to control the snake</p>
            <p>Eat food to grow and earn points</p>
            <p>Don't hit the walls or yourself!</p>
        </div>
    </div>
    <script src="js/game.js"></script>
</body>
</html>
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Arial', sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background-color: #f0f0f0;
}

.game-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    background-color: white;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
    max-width: 500px;
    width: 100%;
}

.game-header {
    width: 100%;
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 15px;
}

.game-header h1 {
    font-size: 24px;
    color: #333;
}

.score {
    font-size: 18px;
    font-weight: bold;
    color: #4CAF50;
}

#gameCanvas {
    border: 2px solid #333;
    background-color: #e8f5e9;
    margin: 10px 0;
}

.game-controls {
    display: flex;
    gap: 10px;
    margin: 15px 0;
}

button {
    padding: 8px 16px;
    font-size: 16px;
    cursor: pointer;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 4px;
    transition: background-color 0.3s;
}

button:hover {
    background-color: #388E3C;
}

button:disabled {
    background-color: #9E9E9E;
    cursor: not-allowed;
}

.game-instructions {
    margin-top: 15px;
    text-align: center;
    color: #666;
}

.game-instructions p {
    margin: 5px 0;
}

@media (max-width: 500px) {
    .game-container {
        padding: 10px;
    }
    
    .game-header h1 {
        font-size: 20px;
    }
    
    #gameCanvas {
        width: 300px;
        height: 300px;
    }
    
    button {
        padding: 6px 12px;
        font-size: 14px;
    }
}
class SnakeGame {
    constructor() {
        this.canvas = document.getElementById('gameCanvas');
        this.ctx = this.canvas.getContext('2d');
        this.gridSize = 20;
        this.snake = [{x: 5, y: 5}];
        this.direction = 'right';
        this.food = this.generateFood();
        this.score = 0;
        this.gameLoop = null;
        this.isPaused = false;
        
        // Game speed (lower = faster)
        this.gameSpeed = 150;
        
        // Bind controls
        this.startBtn = document.getElementById('startBtn');
        this.pauseBtn = document.getElementById('pauseBtn');
        this.scoreElement = document.getElementById('score');
        
        this.setupEventListeners();
    }

    setupEventListeners() {
        // Keyboard controls
        document.addEventListener('keydown', (e) => {
            const key = e.key;
            const directions = {
                'ArrowUp': 'up',
                'ArrowDown': 'down',
                'ArrowLeft': 'left',
                'ArrowRight': 'right'
            };

            if (directions[key]) {
                e.preventDefault();
                const newDirection = directions[key];
                const opposites = {
                    'up': 'down',
                    'down': 'up',
                    'left': 'right',
                    'right': 'left'
                };
                
                // Prevent 180-degree turns
                if (this.snake.length === 1 || opposites[this.direction] !== newDirection) {
                    this.direction = newDirection;
                }
            }
        });

        // Button controls
        this.startBtn.addEventListener('click', () => this.startGame());
        this.pauseBtn.addEventListener('click', () => this.togglePause());
    }

    startGame() {
        if (this.gameLoop) {
            // Reset game if already running
            clearInterval(this.gameLoop);
            this.reset();
        }
        
        this.gameLoop = setInterval(() => this.update(), this.gameSpeed);
        this.startBtn.textContent = 'Restart';
        this.pauseBtn.disabled = false;
    }

    togglePause() {
        if (this.isPaused) {
            this.gameLoop = setInterval(() => this.update(), this.gameSpeed);
            this.pauseBtn.textContent = 'Pause';
        } else {
            clearInterval(this.gameLoop);
            this.pauseBtn.textContent = 'Resume';
        }
        this.isPaused = !this.isPaused;
    }

    reset() {
        this.snake = [{x: 5, y: 5}];
        this.direction = 'right';
        this.score = 0;
        this.scoreElement.textContent = '0';
        this.food = this.generateFood();
        this.isPaused = false;
        this.pauseBtn.textContent = 'Pause';
    }

    generateFood() {
        const maxX = this.canvas.width / this.gridSize - 1;
        const maxY = this.canvas.height / this.gridSize - 1;
        
        while (true) {
            const food = {
                x: Math.floor(Math.random() * maxX),
                y: Math.floor(Math.random() * maxY)
            };
            
            // Check if food spawns on snake
            if (!this.snake.some(segment => segment.x === food.x && segment.y === food.y)) {
                return food;
            }
        }
    }

    update() {
        const head = {...this.snake[0]};
        
        // Update snake head position
        switch (this.direction) {
            case 'up': head.y--; break;
            case 'down': head.y++; break;
            case 'left': head.x--; break;
            case 'right': head.x++; break;
        }
        
        // Check collision with walls
        if (head.x < 0 || head.x >= this.canvas.width / this.gridSize ||
            head.y < 0 || head.y >= this.canvas.height / this.gridSize) {
            this.gameOver();
            return;
        }
        
        // Check collision with self
        if (this.snake.some(segment => segment.x === head.x && segment.y === head.y)) {
            this.gameOver();
            return;
        }
        
        // Add new head
        this.snake.unshift(head);
        
        // Check if food is eaten
        if (head.x === this.food.x && head.y === this.food.y) {
            this.score += 10;
            this.scoreElement.textContent = this.score;
            this.food = this.generateFood();
        } else {
            // Remove tail if no food eaten
            this.snake.pop();
        }
        
        this.draw();
    }

    draw() {
        // Clear canvas
        this.ctx.fillStyle = '#e8f5e9';
        this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
        
        // Draw snake
        this.snake.forEach((segment, index) => {
            this.ctx.fillStyle = index === 0 ? '#388E3C' : '#4CAF50';
            this.ctx.fillRect(
                segment.x * this.gridSize,
                segment.y * this.gridSize,
                this.gridSize - 1,
                this.gridSize - 1
            );
        });
        
        // Draw food
        this.ctx.fillStyle = '#F44336';
        this.ctx.fillRect(
            this.food.x * this.gridSize,
            this.food.y * this.gridSize,
            this.gridSize - 1,
            this.gridSize - 1
        );
    }

    gameOver() {
        clearInterval(this.gameLoop);
        this.gameLoop = null;
        this.pauseBtn.disabled = true;
        alert(`Game Over! Your score: ${this.score}`);
    }
}

// Initialize game when page loads
window.onload = () => {
    new SnakeGame();
};