程序员端午摸鱼指南:AI 帮我1分钟开发出一场赛龙舟狂欢
前言
端午节将至,作为一名程序员,我一直想开发一款与端午相关的小游戏来增添节日氛围。然而,独自完成整个游戏开发过程不仅耗时,还可能遇到各种技术难题。但如今有强大的 AI 编程助手,我决定借助它的力量,开启这场赛龙舟游戏的开发之旅。
以下是最终呈现效果与实际操作中的开发界面(文末附完整代码):
红色是玩家,其它是电脑,看我如何后来居上,哈哈~
需求提出与初步沟通
我首先向 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';
}
});
🌟 让技术经验流动起来
▌▍▎▏ 你的每个互动都在为技术社区蓄能 ▏▎▍▌
✅ 点赞 → 让优质经验被更多人看见
📥 收藏 → 构建你的专属知识库
🔄 转发 → 与技术伙伴共享避坑指南
点赞 ➕ 收藏 ➕ 转发,助力更多小伙伴一起成长!💪
💌 深度连接:
点击 「头像」→「+关注」
每周解锁:
🔥 一线架构实录 | 💡 故障排查手册 | 🚀 效能提升秘籍
- 点赞
- 收藏
- 关注作者
评论(0)