Trae初体验

240 阅读2分钟

我正在参加 Trae AI 编码从入门到实践线上共学第一期,Trae 免费下载链接: www.trae.ai

#Trae 从入门到实践

Trae界面

官网下载Trae Windows版,界面和VScode差不多,可以直接导入VScode的配置与插件。 image.png

右侧是AI聊天框和Builder,目前支持的大模型有GPT-4o和Claude-3.5-Sonnet。 image.png

Trae构建程序

我们先让Builder写一个贪吃蛇小游戏:

image.png

Trae创建了两个文件,index.htmlgame.js,用浏览器打开index.html就可以直接玩贪吃蛇了。但是界面不太喜欢,让Trae再优化一下:

image.png

再次打开index.html,页面相比第一版优化了背景,游戏边框变成圆角。

image.png

贪吃蛇的运动速度有点快,希望再慢一点。

image.png

代码:

<!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>
        @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;700&display=swap');
        body {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100vh;
            margin: 0;
            background: linear-gradient(135deg, #ffd6e7, #c1efff);
            background-size: cover;
            font-family: 'Noto Sans SC', sans-serif;
        }
        #game-container {
            position: relative;
        }
        #gameCanvas {
            border: 3px solid #ff69b4;
            background-color: rgba(255, 255, 255, 0.9);
            border-radius: 10px;
            box-shadow: 0 0 15px rgba(255, 105, 180, 0.3);
        }
        #score {
            font-size: 28px;
            margin-bottom: 20px;
            color: #ff69b4;
            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
            font-weight: bold;
        }
        #controls {
            margin-top: 20px;
            text-align: center;
        }
        button {
            padding: 12px 25px;
            font-size: 18px;
            margin: 0 10px;
            cursor: pointer;
            background-color: #ff69b4;
            color: white;
            border: none;
            border-radius: 25px;
            transition: all 0.3s ease;
            box-shadow: 0 4px 15px rgba(255, 105, 180, 0.3);
        }
        button:hover {
            background-color: #ff1493;
            transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(255, 105, 180, 0.4);
        }
    </style>
</head>
<body>
    <div id="score">分数: <span id="scoreValue">0</span></div>
    <div id="game-container">
        <canvas id="gameCanvas" width="400" height="400"></canvas>
    </div>
    <div id="controls">
        <button id="startBtn">开始游戏</button>
        <button id="restartBtn">重新开始</button>
    </div>
    <script src="game.js"></script>
</body>
</html>
class Snake {
    constructor() {
        this.reset();
    }

    reset() {
        this.body = [
            { x: 10, y: 10 },
            { x: 9, y: 10 },
            { x: 8, y: 10 }
        ];
        this.direction = 'right';
        this.nextDirection = 'right';
    }

    move(food) {
        const head = { ...this.body[0] };

        switch (this.direction) {
            case 'up': head.y--; break;
            case 'down': head.y++; break;
            case 'left': head.x--; break;
            case 'right': head.x++; break;
        }

        this.body.unshift(head);

        if (head.x === food.x && head.y === food.y) {
            return true;
        }

        this.body.pop();
        return false;
    }

    changeDirection(newDirection) {
        const opposites = {
            'up': 'down',
            'down': 'up',
            'left': 'right',
            'right': 'left'
        };

        if (newDirection !== opposites[this.direction]) {
            this.nextDirection = newDirection;
        }
    }

    update() {
        this.direction = this.nextDirection;
    }

    checkCollision(gridSize) {
        const head = this.body[0];
        
        if (head.x < 0 || head.x >= gridSize || 
            head.y < 0 || head.y >= gridSize) {
            return true;
        }

        for (let i = 1; i < this.body.length; i++) {
            if (head.x === this.body[i].x && head.y === this.body[i].y) {
                return true;
            }
        }

        return false;
    }
}

class Game {
    constructor() {
        this.canvas = document.getElementById('gameCanvas');
        this.ctx = this.canvas.getContext('2d');
        this.gridSize = 20;
        this.tileSize = this.canvas.width / this.gridSize;
        this.snake = new Snake();
        this.food = this.generateFood();
        this.score = 0;
        this.isRunning = false;
        this.gameLoop = null;

        this.bindEvents();
    }

    bindEvents() {
        document.addEventListener('keydown', (e) => {
            const keyDirections = {
                'ArrowUp': 'up',
                'ArrowDown': 'down',
                'ArrowLeft': 'left',
                'ArrowRight': 'right'
            };

            const newDirection = keyDirections[e.key];
            if (newDirection) {
                this.snake.changeDirection(newDirection);
            }
        });

        document.getElementById('startBtn').addEventListener('click', () => {
            if (!this.isRunning) {
                this.start();
            }
        });

        document.getElementById('restartBtn').addEventListener('click', () => {
            this.restart();
        });
    }

    generateFood() {
        const food = {
            x: Math.floor(Math.random() * this.gridSize),
            y: Math.floor(Math.random() * this.gridSize)
        };

        // 确保食物不会生成在蛇身上
        for (const segment of this.snake.body) {
            if (food.x === segment.x && food.y === segment.y) {
                return this.generateFood();
            }
        }

        return food;
    }

    update() {
        this.snake.update();
        
        if (this.snake.move(this.food)) {
            this.score += 10;
            document.getElementById('scoreValue').textContent = this.score;
            this.food = this.generateFood();
        }

        if (this.snake.checkCollision(this.gridSize)) {
            this.stop();
            alert('游戏结束!得分:' + this.score);
        }
    }

    draw() {
        // 清空画布
        this.ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
        this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);

        // 绘制蛇
        for (let i = 0; i < this.snake.body.length; i++) {
            const segment = this.snake.body[i];
            const gradient = this.ctx.createRadialGradient(
                (segment.x + 0.5) * this.tileSize,
                (segment.y + 0.5) * this.tileSize,
                0,
                (segment.x + 0.5) * this.tileSize,
                (segment.y + 0.5) * this.tileSize,
                this.tileSize / 2
            );
            gradient.addColorStop(0, '#ff9ecd');
            gradient.addColorStop(1, '#ff69b4');
            
            this.ctx.beginPath();
            this.ctx.fillStyle = gradient;
            this.ctx.arc(
                (segment.x + 0.5) * this.tileSize,
                (segment.y + 0.5) * this.tileSize,
                (this.tileSize - 2) / 2,
                0,
                Math.PI * 2
            );
            this.ctx.fill();
        }

        // 绘制食物
        const foodGradient = this.ctx.createRadialGradient(
            (this.food.x + 0.5) * this.tileSize,
            (this.food.y + 0.5) * this.tileSize,
            0,
            (this.food.x + 0.5) * this.tileSize,
            (this.food.y + 0.5) * this.tileSize,
            this.tileSize / 2
        );
        foodGradient.addColorStop(0, '#ffeb3b');
        foodGradient.addColorStop(1, '#ffc107');

        this.ctx.beginPath();
        this.ctx.fillStyle = foodGradient;
        this.ctx.arc(
            (this.food.x + 0.5) * this.tileSize,
            (this.food.y + 0.5) * this.tileSize,
            (this.tileSize - 2) / 2,
            0,
            Math.PI * 2
        );
        this.ctx.fill();
    }

    start() {
        if (!this.isRunning) {
            this.isRunning = true;
            this.gameLoop = setInterval(() => {
                this.update();
                this.draw();
            }, 200);
        }
    }

    stop() {
        this.isRunning = false;
        clearInterval(this.gameLoop);
    }

    restart() {
        this.stop();
        this.snake.reset();
        this.food = this.generateFood();
        this.score = 0;
        document.getElementById('scoreValue').textContent = this.score;
        this.start();
    }
}

// 初始化游戏
const game = new Game();