程序员端午摸鱼指南:AI 帮我1分钟开发出一场赛龙舟狂欢

举报
超梦 发表于 2025/05/27 18:56:02 2025/05/27
【摘要】 前言端午节将至,作为一名程序员,我一直想开发一款与端午相关的小游戏来增添节日氛围。然而,独自完成整个游戏开发过程不仅耗时,还可能遇到各种技术难题。但如今有强大的 AI 编程助手,我决定借助它的力量,开启这场赛龙舟游戏的开发之旅。以下是最终呈现效果与实际操作中的开发界面(文末附完整代码):红色是玩家,其它是电脑,看我如何后来居上,哈哈~ 需求提出与初步沟通我首先向 AI 表达了我的需求:“马...

前言

端午节将至,作为一名程序员,我一直想开发一款与端午相关的小游戏来增添节日氛围。然而,独自完成整个游戏开发过程不仅耗时,还可能遇到各种技术难题。但如今有强大的 AI 编程助手,我决定借助它的力量,开启这场赛龙舟游戏的开发之旅。


以下是最终呈现效果与实际操作中的开发界面(文末附完整代码):

红色是玩家,其它是电脑,看我如何后来居上,哈哈~

bandicam 2025-05-27 18-43-47-041 00_00_00-00_00_30.gif

Snipaste_2025-05-27_18-46-01.png


需求提出与初步沟通

我首先向 AI 表达了我的需求:“马上要过端午节了,我想开发一款赛龙舟的竞速游戏,你能帮我吗?”AI 迅速给出了积极回应,并询问我对游戏的具体设想,比如游戏的玩法、界面风格、功能需求等。我详细描述了希望游戏有玩家和 AI 对手,通过空格键控制玩家龙舟加速,有精美的背景和节日装饰,比赛结束后显示排名等功能。

架构设计与规划

在明确需求后,AI 开始引导我进行游戏的架构设计。它提出采用经典的 HTML5 Canvas 技术来实现游戏画面的绘制,因为 Canvas 具有强大的绘图能力和良好的跨平台兼容性。同时,使用 JavaScript 来实现游戏的逻辑控制,包括玩家和 AI 对手的移动、碰撞检测、游戏状态管理等。AI 还为我列出了大致的文件结构,建议创建 index.html 作为游戏的入口页面,style.css 用于样式设计,game.js 实现游戏的核心逻辑。

代码实现与逐步完善

HTML 页面搭建

AI 先帮我生成了 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="game-container">
        <canvas id="gameCanvas" width="800" height="600"></canvas>
    </div>
    <script src="game.js"></script>
</body>
</html>

这段代码创建了一个基本的 HTML 页面,引入了 CSS 样式表和 JavaScript 文件,并在页面中添加了一个 Canvas 元素,用于绘制游戏画面。

CSS 样式设计

接着,AI 为我生成了 style.css 的代码:

body {
    margin: 0;
    padding: 0;
    overflow: hidden; /* 防止页面滚动 */
    background: linear-gradient(135deg, #1e5799 0%,#207cca 51%,#2989d8 100%);
    font-family: 'Arial', sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}

.game-container {
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
    border-radius: 5px;
    overflow: hidden;
}

canvas {
    display: block;
}

这段代码设置了页面的背景、布局和样式,使游戏容器居中显示,并为其添加了阴影和圆角效果。

JavaScript 核心逻辑实现

game.js 中,AI 帮我实现了游戏的核心逻辑。包括游戏状态管理、玩家和 AI 对手的创建与更新、背景和装饰的绘制、事件监听等功能。例如,通过 init 函数初始化游戏,创建玩家和 AI 对手,加载音效,并启动游戏循环:

function init() {
    // 创建玩家龙舟
    game.players.push({
        x: 100,
        y: game.height / 2,
        width: 80,
        height: 30,
        speed: 0,
        color: '#FF5252'
    });

    // 创建AI对手
    for (let i = 0; i < 3; i++) {
        game.players.push({
            x: 100,
            y: game.height / 2 + (i + 1) * 100,
            width: 80,
            height: 30,
            speed: 0,
            color: ['#4CAF50', '#2196F3', '#FFC107'][i],
            isAI: true
        });
    }

    // 设置背景
    game.background = {
        waterLevel: game.height * 0.7,
        waveOffset: 0
    };

    // 加载音效
    loadSounds();

    // 开始游戏循环
    game.lastTime = performance.now();
    requestAnimationFrame(gameLoop);
}

update 函数中,更新玩家和 AI 对手的位置和速度,并检查比赛是否结束:

function update(deltaTime) {
    if (game.state !== 'playing') return;

    // 更新玩家龙舟 (速度降低)
    game.players[0].speed = Math.min(game.players[0].speed + deltaTime * 15, 180);
    game.players[0].x += game.players[0].speed * deltaTime;

    // 更新AI对手 (速度大幅提高)
    for (let i = 1; i < game.players.length; i++) {
        const ai = game.players[i];
        
        // 更激进的AI速度控制
        const baseAcceleration = 45; // 基础加速度大幅提高
        const randomBoost = Math.random() * 30; // 随机加速范围扩大
        const catchUpFactor = (game.players[0].x - ai.x) * 0.12; // 追赶系数增强
        
        ai.speed = Math.min(ai.speed + deltaTime * (baseAcceleration + randomBoost + catchUpFactor), 250); // 最大速度提高
        ai.x += ai.speed * deltaTime;
        
        // AI轻微上下浮动
        ai.y += Math.sin(Date.now() * 0.002 + i) * 0.5;
        
        // 自然速度衰减
        ai.speed *= 0.995;
    }

    // 检查比赛结束
    if (game.players.some(boat => boat.x > game.width - 50)) {
        game.state = 'finished';
        showResult();
    }
}

render 函数中,绘制游戏画面,包括背景、装饰、玩家和 AI 对手:

function render() {
    // 清空画布
    ctx.clearRect(0, 0, game.width, game.height);

    // 绘制背景
    drawBackground();

    // 绘制节日装饰
    drawDecorations();

    // 绘制玩家和AI
    game.players.forEach(player => {
        drawBoat(player);
    });

    // 显示游戏状态
    if (game.state === 'ready') {
        ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
        ctx.fillRect(game.width/2 - 150, game.height/2 - 50, 300, 100);
        
        ctx.fillStyle = '#FFFFFF';
        ctx.font = '30px Arial';
        ctx.textAlign = 'center';
        ctx.fillText('赛龙舟竞速', game.width/2, game.height/2 - 10);
        
        ctx.font = '20px Arial';
        ctx.fillText('按空格键开始', game.width/2, game.height/2 + 30);
    } else if (game.state === 'playing') {
        // 显示当前速度
        ctx.fillStyle = '#FFFFFF';
        ctx.font = '18px Arial';
        ctx.textAlign = 'left';
        ctx.fillText(`速度: ${Math.round(game.players[0].speed)}`, 20, 30);
    }
}

个人见解与总结

在开发过程中,我对 HTML5 Canvas 和 JavaScript 的游戏开发有了更深入的理解。例如,如何使用 Canvas 绘制复杂的图形和动画,如何通过 JavaScript 实现游戏的逻辑控制和状态管理。同时,我也意识到,虽然 AI 可以提供很多帮助,但程序员仍然需要具备扎实的基础知识和独立思考的能力,才能更好地理解和运用 AI 生成的代码,解决开发过程中遇到的问题。

希望这篇技术分享能对其他开发者有所启发,也希望大家在端午节期间能体验到这款充满节日氛围的赛龙舟游戏!

附:

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="game-container">
        <canvas id="gameCanvas" width="800" height="600"></canvas>
    </div>
    <script src="game.js"></script>
</body>
</html>

style.css

body {
    margin: 0;
    padding: 0;
    overflow: hidden; /* 防止页面滚动 */
    background: linear-gradient(135deg, #1e5799 0%,#207cca 51%,#2989d8 100%);
    font-family: 'Arial', sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}

.game-container {
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
    border-radius: 5px;
    overflow: hidden;
}

canvas {
    display: block;
}

game.js

// 游戏主入口
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

// 游戏状态
const game = {
    width: canvas.width,
    height: canvas.height,
    state: 'ready', // ready, playing, finished
    players: [],
    obstacles: [],
    background: null,
    lastTime: 0,
    score: 0,
    sounds: {
        paddle: null,
        cheer: null,
        start: null
    }
};

// 加载音效
function loadSounds() {
    game.sounds.paddle = new Audio('assets/sounds/paddle.wav');
    game.sounds.cheer = new Audio('assets/sounds/cheer.wav');
    game.sounds.start = new Audio('assets/sounds/start.wav');
}

// 初始化游戏
function init() {
    // 创建玩家龙舟
    game.players.push({
        x: 100,
        y: game.height / 2,
        width: 80,
        height: 30,
        speed: 0,
        color: '#FF5252'
    });

    // 创建AI对手
    for (let i = 0; i < 3; i++) {
        game.players.push({
            x: 100,
            y: game.height / 2 + (i + 1) * 100,
            width: 80,
            height: 30,
            speed: 0,
            color: ['#4CAF50', '#2196F3', '#FFC107'][i],
            isAI: true
        });
    }

    // 设置背景
    game.background = {
        waterLevel: game.height * 0.7,
        waveOffset: 0
    };

    // 加载音效
    loadSounds();

    // 开始游戏循环
    game.lastTime = performance.now();
    requestAnimationFrame(gameLoop);
}

// 游戏主循环
function gameLoop(currentTime) {
    const deltaTime = (currentTime - game.lastTime) / 1000;
    game.lastTime = currentTime;

    update(deltaTime);
    render();

    requestAnimationFrame(gameLoop);
}

// 更新游戏状态
function update(deltaTime) {
    if (game.state !== 'playing') return;

    // 更新玩家龙舟 (速度降低)
    game.players[0].speed = Math.min(game.players[0].speed + deltaTime * 15, 180);
    game.players[0].x += game.players[0].speed * deltaTime;

    // 更新AI对手 (速度大幅提高)
    for (let i = 1; i < game.players.length; i++) {
        const ai = game.players[i];
        
        // 更激进的AI速度控制
        const baseAcceleration = 45; // 基础加速度大幅提高
        const randomBoost = Math.random() * 30; // 随机加速范围扩大
        const catchUpFactor = (game.players[0].x - ai.x) * 0.12; // 追赶系数增强
        
        ai.speed = Math.min(ai.speed + deltaTime * (baseAcceleration + randomBoost + catchUpFactor), 250); // 最大速度提高
        ai.x += ai.speed * deltaTime;
        
        // AI轻微上下浮动
        ai.y += Math.sin(Date.now() * 0.002 + i) * 0.5;
        
        // 自然速度衰减
        ai.speed *= 0.995;
    }

    // 检查比赛结束
    if (game.players.some(boat => boat.x > game.width - 50)) {
        game.state = 'finished';
        showResult();
    }
}

// 渲染游戏画面
function render() {
    // 清空画布
    ctx.clearRect(0, 0, game.width, game.height);

    // 绘制背景
    drawBackground();

    // 绘制节日装饰
    drawDecorations();

    // 绘制玩家和AI
    game.players.forEach(player => {
        drawBoat(player);
    });

    // 显示游戏状态
    if (game.state === 'ready') {
        ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
        ctx.fillRect(game.width/2 - 150, game.height/2 - 50, 300, 100);
        
        ctx.fillStyle = '#FFFFFF';
        ctx.font = '30px Arial';
        ctx.textAlign = 'center';
        ctx.fillText('赛龙舟竞速', game.width/2, game.height/2 - 10);
        
        ctx.font = '20px Arial';
        ctx.fillText('按空格键开始', game.width/2, game.height/2 + 30);
    } else if (game.state === 'playing') {
        // 显示当前速度
        ctx.fillStyle = '#FFFFFF';
        ctx.font = '18px Arial';
        ctx.textAlign = 'left';
        ctx.fillText(`速度: ${Math.round(game.players[0].speed)}`, 20, 30);
    }
}

// 绘制背景
function drawBackground() {
    // 天空
    ctx.fillStyle = '#87CEEB';
    ctx.fillRect(0, 0, game.width, game.background.waterLevel);

    // 水面
    ctx.fillStyle = '#1E88E5';
    ctx.beginPath();
    ctx.moveTo(0, game.background.waterLevel);

    // 绘制波浪
    for (let x = 0; x <= game.width; x += 20) {
        const y = game.background.waterLevel + Math.sin(x * 0.02 + game.background.waveOffset) * 10;
        ctx.lineTo(x, y);
    }

    ctx.lineTo(game.width, game.height);
    ctx.lineTo(0, game.height);
    ctx.closePath();
    ctx.fill();

    // 更新波浪偏移
    game.background.waveOffset += 0.05;
}

// 绘制龙舟
function drawBoat(boat) {
    // 船身
    ctx.fillStyle = boat.color;
    ctx.beginPath();
    ctx.moveTo(boat.x, boat.y);
    ctx.lineTo(boat.x + boat.width, boat.y - boat.height / 2);
    ctx.lineTo(boat.x + boat.width, boat.y + boat.height / 2);
    ctx.closePath();
    ctx.fill();

    // 船头装饰
    ctx.fillStyle = '#FFD700';
    ctx.beginPath();
    ctx.arc(boat.x + boat.width, boat.y, boat.height/2, -Math.PI/2, Math.PI/2);
    ctx.fill();

    // 绘制船桨
    ctx.fillStyle = '#795548';
    for (let i = 0; i < 3; i++) {
        const paddleX = boat.x + 20 + i * 20;
        const angle = Math.sin(Date.now() * 0.01 + i) * 0.3;
        
        ctx.save();
        ctx.translate(paddleX, boat.y);
        ctx.rotate(angle);
        ctx.fillRect(0, -15, 5, 30);
        ctx.restore();
    }

    // 绘制水花
    if (boat.speed > 50 && game.state === 'playing') {
        ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
        for (let i = 0; i < 3; i++) {
            const offsetX = Math.random() * 10 - 5;
            const offsetY = Math.random() * 10 - 5;
            const size = Math.random() * 5 + 3;
            ctx.beginPath();
            ctx.arc(boat.x + offsetX, boat.y + boat.height/2 + offsetY, size, 0, Math.PI * 2);
            ctx.fill();
        }
    }
}

// 绘制节日装饰
function drawDecorations() {
    // 绘制旗帜
    ctx.fillStyle = '#FF5252';
    for (let x = 50; x < game.width; x += 150) {
        ctx.beginPath();
        ctx.moveTo(x, 30);
        ctx.lineTo(x + 40, 50);
        ctx.lineTo(x, 70);
        ctx.closePath();
        ctx.fill();
    }

    // 绘制灯笼
    ctx.fillStyle = '#FF9800';
    for (let x = 100; x < game.width; x += 200) {
        ctx.beginPath();
        ctx.arc(x, 100, 20, 0, Math.PI * 2);
        ctx.fill();
        ctx.fillRect(x - 2, 100, 4, 30);
    }
}

// 启动游戏
init();

// 事件监听
document.addEventListener('keydown', (e) => {
    if (game.state === 'ready' && e.code === 'Space') {
        game.state = 'playing';
        if (game.sounds.start) {
            game.sounds.start.play();
        }
    }
    
    // 划桨加速
    if (game.state === 'playing' && e.code === 'Space') {
        game.players[0].speed += 30;
        if (game.sounds.paddle) {
            game.sounds.paddle.currentTime = 0;
            game.sounds.paddle.play();
        }
    }
});

// 显示游戏结果
function showResult() {
    const player = game.players[0];
    const ranking = game.players
        .sort((a, b) => b.x - a.x)
        .findIndex(boat => boat === player) + 1;
    
    ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
    ctx.fillRect(game.width/2 - 150, game.height/2 - 100, 300, 200);
    
    ctx.fillStyle = '#FFFFFF';
    ctx.font = '30px Arial';
    ctx.textAlign = 'center';
    ctx.fillText('比赛结束!', game.width/2, game.height/2 - 50);
    
    ctx.font = '24px Arial';
    ctx.fillText(`你的名次: 第${ranking}`, game.width/2, game.height/2);
    
    ctx.font = '20px Arial';
    ctx.fillText('按R键重新开始', game.width/2, game.height/2 + 50);
}

// 重新开始游戏
document.addEventListener('keydown', (e) => {
    if (e.code === 'KeyR' && game.state === 'finished') {
        game.players.forEach(boat => {
            boat.x = 100;
            boat.speed = 0;
        });
        game.state = 'ready';
    }
});



🌟 让技术经验流动起来

▌▍▎▏ 你的每个互动都在为技术社区蓄能 ▏▎▍▌
点赞 → 让优质经验被更多人看见
📥 收藏 → 构建你的专属知识库
🔄 转发 → 与技术伙伴共享避坑指南

点赞 ➕ 收藏 ➕ 转发,助力更多小伙伴一起成长!💪

💌 深度连接
点击 「头像」→「+关注」
每周解锁:
🔥 一线架构实录 | 💡 故障排查手册 | 🚀 效能提升秘籍

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。