文心快码 Coding 智能体 Zulu 正式发布!欢迎各位小伙伴们抢先体验!使用 Comate Zulu,用对话就能写代码,更加智能、简单、直观, 并且提供从代码生成到业务理解的完整智能服务——0开发经验也能做软件、做网站、做游戏,让编程技术门槛更低,让开发者自由挥洒创意!
Comate Zulu发布了新一期打卡任务。只要在4月25日至5月7日活动时间有效使用 Comate Zulu,即可参加小度智能屏X7、智能音箱、按摩仪等超多好礼的抽奖!有兴趣的小伙伴可以点击我的邀请链接参与哟!
https://comate.baidu.com/?inviteCode=6h2mrwpb
有效使用要同时满足以下三个条件:
- 在插件上登陆,并切换到zulu模式提问
- 提问内容需明确涉及代码开发场景,包括但不限于:
代码生成(例:“帮我写一个俄罗斯方块小游戏”)
项目分析(例:“解释当前SpringBoot项目的分层架构”) - Zulu系统返回完整回答
一、第1轮对话
我们第一次使用Comate Zulu时给了一个“命题作文”,详见《第一次使用Comate Zulu生成贪食蛇游戏的学思笔记》。这里我们来一个开放式作文。
我:请你为我生成一个类似但不是贪食蛇的小游戏。
zulu:我将为您创建一个"躲避陨石"的小游戏,玩家控制飞船躲避下落的陨石。
一分钟后,它为我开发了一个"躲避陨石"的小游戏,具有以下特点:
- 使用方向键控制飞船左右移动
- 随着分数增加,陨石下落速度会逐渐加快
- 游戏结束后按R键可以重新开始
- 自适应窗口大小调整
双击start meteor-dodge.html文件运行,哎呦,还不错!能玩!但是有点简单!
二、第2轮对话
我:游戏有点简单,请你增加一些难度
zulu:我将为游戏添加不同类型的陨石,使游戏更有挑战性:
- 4种陨石类型:普通(蓝色)、快速(红色菱形)、分裂(绿色)和追踪(黄色)
- 难度会随分数自动提升,特殊陨石出现概率增加
- 游戏界面显示操作说明和当前难度
- 按R键可随时重新开始
这里花了很多时间解决bug:
1、画面只有飞船(三角形),不能移动,且没有陨石出现
2、游戏难度增加过快,不利于新手玩家
3、分裂陨石不分裂
三、第3轮对话
我:请你进一步丰富游戏内容
zulu:我将增加一种名为护盾的游戏道具,通过收集"shield"类型的道具获得护盾,道具随机从上方掉落,颜色为青色(#00ffff)。同时增加添加"时间减缓"和"清屏炸弹"两种新道具。增加背景星空动画。
这一步对游戏进行了以下优化:
1、由于颜色难以记忆,所有陨石的外观统一为圆形
2、给道具加上了中文标识,外观调整为圆形以外的形状。
附上可玩的html代码
新建一个txt文件,复制粘贴进去,修改后缀名为html即可双击运行。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Meteor Dodge Game</title>
<style>
body {
margin: 0;
overflow: hidden;
background-color: #000;
}
canvas {
display: block;
}
</style>
</head>
<body>
<canvas id="gameCanvas"></canvas>
<script>
// 游戏核心逻辑将在这里实现
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// 初始化画布尺寸
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// 游戏状态
let score = 0;
let gameOver = false;
let stars = [];
// 初始化星空背景
function initStars() {
stars = [];
for (let i = 0; i < 200; i++) {
stars.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
size: Math.random() * 1.5 + 0.5,
speed: Math.random() * 2 + 1
});
}
}
// 玩家飞船
const player = {
x: canvas.width / 2,
y: canvas.height - 50,
width: 30,
height: 30,
speed: 8,
color: '#3498db',
shield: 0, // 护盾值(0-100)
hasShield: false // 是否有护盾
};
// 游戏对象数组
let meteors = [];
let powerups = []; // 道具数组
// 控制状态
const keys = {
ArrowLeft: false,
ArrowRight: false
};
// 游戏主循环(添加性能保护)
let lastTime = performance.now();
const maxFrameTime = 1000/30; // 限制最低30fps
function gameLoop() {
const now = performance.now();
const delta = now - lastTime;
if (gameOver) return;
if (delta > maxFrameTime * 3) {
console.warn('帧率过低,跳过渲染');
lastTime = now - maxFrameTime;
return requestAnimationFrame(gameLoop);
}
lastTime = now;
// 清空画布
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制星空背景
ctx.fillStyle = 'white';
stars.forEach(star => {
ctx.beginPath();
ctx.arc(star.x, star.y, star.size, 0, Math.PI * 2);
ctx.fill();
// 星星下落
star.y += star.speed;
if (star.y > canvas.height) {
star.y = 0;
star.x = Math.random() * canvas.width;
}
});
// 更新游戏对象
updatePlayer();
updateMeteors();
updatePowerups();
// 绘制游戏对象
drawPlayer();
drawMeteors();
drawPowerups();
// 显示分数
drawScore();
// 随机生成新陨石 - 提高生成频率
if (Math.random() < 0.05 * getDifficultyMultiplier()) {
createMeteor();
}
// 随机生成道具(概率较低)
if (Math.random() < 0.01 * getDifficultyMultiplier()) {
createPowerup();
}
requestAnimationFrame(gameLoop);
}
// 初始化游戏 - 确保正确初始化
function init() {
// 清除现有陨石和道具
meteors = [];
powerups = [];
score = 0;
gameOver = false;
// 重置玩家状态
player.x = canvas.width / 2;
player.hasShield = false;
player.shield = 0;
// 添加事件监听
window.addEventListener('keydown', handleKeyDown);
window.addEventListener('keyup', handleKeyUp);
// 启动游戏循环
requestAnimationFrame(gameLoop);
}
// 游戏功能函数
function updatePlayer() {
if (keys.ArrowLeft && player.x > 0) {
player.x -= player.speed;
}
if (keys.ArrowRight && player.x < canvas.width - player.width) {
player.x += player.speed;
}
// 护盾随时间衰减
if (player.hasShield && player.shield > 0) {
player.shield -= 0.5;
if (player.shield <= 0) {
player.hasShield = false;
player.shield = 0;
}
}
}
function drawPlayer() {
// 绘制护盾(如果有)
if (player.hasShield && player.shield > 0) {
ctx.strokeStyle = '#00ffff';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(
player.x + player.width/2,
player.y + player.height/2,
player.width + 5,
0, Math.PI*2
);
ctx.stroke();
}
// 绘制三角形飞船
ctx.fillStyle = player.color;
ctx.beginPath();
ctx.moveTo(player.x + player.width/2, player.y);
ctx.lineTo(player.x, player.y + player.height);
ctx.lineTo(player.x + player.width, player.y + player.height);
ctx.closePath();
ctx.fill();
}
function createMeteor() {
const size = Math.random() * 30 + 10;
meteors.push({
x: Math.random() * (canvas.width - size),
y: -size,
width: size,
height: size,
speed: Math.random() * 3 + 2,
color: `hsl(${Math.random() * 360}, 70%, 50%)`
});
}
function updateMeteors() {
for (let i = meteors.length - 1; i >= 0; i--) {
const meteor = meteors[i];
// 不同类型陨石的不同行为
if (meteor.type === 'homing') {
// 追踪陨石会追踪玩家
meteor.dx = (player.x - meteor.x) * 0.01;
meteor.x += meteor.dx;
}
meteor.y += meteor.speedY || meteor.speed;
if (meteor.speedX) {
meteor.x += meteor.speedX;
}
// 碰撞检测
if (
player.x < meteors[i].x + meteors[i].width &&
player.x + player.width > meteors[i].x &&
player.y < meteors[i].y + meteors[i].height &&
player.y + player.height > meteors[i].y
) {
if (player.hasShield && player.shield > 0) {
// 护盾吸收伤害
player.shield -= 30;
if (player.shield <= 0) {
player.hasShield = false;
player.shield = 0;
}
// 移除陨石
meteors.splice(i, 1);
} else {
// 没有护盾,游戏结束
gameOver = true;
ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#fff';
ctx.font = '40px Arial';
ctx.textAlign = 'center';
ctx.fillText(`Game Over! Score: ${score}`, canvas.width/2, canvas.height/2);
ctx.font = '20px Arial';
ctx.fillText('Press R to restart', canvas.width/2, canvas.height/2 + 50);
return;
}
}
// 分裂陨石被击中时分裂
// 分裂陨石逻辑(添加调试保护)
if (meteor.type === 'split' &&
meteor.y + meteor.height > canvas.height / 3 &&
Math.random() < 0.9 * getDifficultyMultiplier()) {
// 限制最大陨石数量防止卡死
if(meteors.length < 100) {
for (let j = 0; j < 2; j++) {
const angle = (j === 0 ? -0.5 : 0.5) * Math.PI/4; // 左右各22.5度
meteors.push({
x: meteor.x + (j * meteor.width/2),
y: meteor.y,
width: Math.max(20, meteor.width * 0.6), // 最小20像素
height: Math.max(20, meteor.height * 0.6),
speedX: Math.sin(angle) * meteor.speed * 0.5, // 水平速度分量
speedY: meteor.speed * 1.1, // 垂直速度稍快
color: meteor.color,
type: 'normal'
});
}
console.log('陨石分裂成功,当前总数:', meteors.length);
} else {
console.warn('达到最大陨石数量限制');
}
meteor.type = 'normal'; // 分裂后变为普通陨石,防止二次分裂
}
// 移除超出屏幕的陨石
if (meteor.y > canvas.height) {
meteors.splice(i, 1);
score += meteor.type === 'fast' ? 2 : 1;
}
}
}
function drawMeteors() {
meteors.forEach(meteor => {
ctx.fillStyle = meteor.color;
ctx.beginPath();
ctx.arc(
meteor.x + meteor.width/2,
meteor.y + meteor.height/2,
meteor.width/2,
0, Math.PI * 2
);
ctx.fill();
});
}
function drawScore() {
ctx.fillStyle = '#fff';
ctx.font = '20px Arial';
ctx.fillText(`Score: ${score}`, 20, 30);
// 添加游戏说明
ctx.font = '16px Arial';
ctx.fillText('← → 移动飞船 | R 重新开始', 20, 60);
// 显示当前难度
const difficulty = Math.floor(getDifficultyMultiplier() * 100);
ctx.fillText(`难度: ${difficulty}%`, 20, 90);
// 显示护盾状态
if (player.hasShield && player.shield > 0) {
ctx.fillText(`护盾: ${Math.floor(player.shield)}%`, 20, 120);
}
}
function handleKeyDown(e) {
if (e.key === 'ArrowLeft') {
keys.ArrowLeft = true;
} else if (e.key === 'ArrowRight') {
keys.ArrowRight = true;
}
}
function handleKeyUp(e) {
if (e.key in keys) {
keys[e.key] = false;
}
// 重新开始游戏
if (gameOver && e.key.toLowerCase() === 'r') {
score = 0;
gameOver = false;
meteors = [];
player.x = canvas.width / 2;
gameLoop();
}
}
// 窗口大小调整处理
window.addEventListener('resize', () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
player.x = canvas.width / 2;
});
// 调整游戏难度 - 更平缓的难度曲线
function getDifficultyMultiplier() {
// 线性增长到100分达到1.5倍速,之后缓慢增长最高2倍速
if (score < 100) {
return 1 + (score / 200); // 0-100分: 1x-1.5x
} else {
return 1.5 + (Math.min(score, 300) - 100) / 400; // 100-300分: 1.5x-2x
}
}
// 随机生成新陨石
function createMeteor() {
const size = Math.random() * 30 + 10;
const type = Math.random();
let meteor;
// 随着分数增加,生成特殊陨石的概率提高
const specialChance = Math.min(0.4, score / 500);
// 普通陨石(60%-specialChance)
if (type < 0.6 - specialChance) {
meteor = {
x: Math.random() * (canvas.width - size),
y: -size,
width: size,
height: size,
speed: (Math.random() * 3 + 2) * getDifficultyMultiplier(),
color: `hsl(${Math.random() * 360}, 70%, 50%)`,
type: 'normal'
};
}
// 快速陨石(25%+specialChance/2)
else if (type < 0.85 + specialChance/2) {
meteor = {
x: Math.random() * (canvas.width - size),
y: -size,
width: size * 0.7,
height: size * 0.7,
speed: (Math.random() * 5 + 4) * getDifficultyMultiplier(),
color: '#ff0000',
type: 'fast'
};
}
// 分裂陨石(25%+specialChance) - 显著提高基础概率
else if (type < 0.85 + specialChance) {
meteor = {
x: Math.random() * (canvas.width - size),
y: -size,
width: size,
height: size,
speed: (Math.random() * 2 + 1) * getDifficultyMultiplier(),
color: '#00ff00',
type: 'split',
health: 2
};
}
// 追踪陨石(5%+specialChance)
else {
meteor = {
x: Math.random() * (canvas.width - size),
y: -size,
width: size * 0.8,
height: size * 0.8,
speed: (Math.random() * 2 + 1) * getDifficultyMultiplier(),
color: '#ffff00',
type: 'homing',
dx: 0
};
}
meteors.push(meteor);
}
// 生成道具
function createPowerup() {
const rand = Math.random();
let type;
// 调整道具生成概率
if (rand < 0.2) { // 40%概率生成护盾
type = 'shield';
} else if (rand < 0.9) { // 40%概率生成分数
type = 'score';
} else if (rand < 0.95) { // 10%概率生成减速
type = 'slow';
} else { // 10%概率生成炸弹
type = 'bomb';
}
let color;
switch(type) {
case 'shield': color = '#00ffff'; break;
case 'score': color = '#ff00ff'; break;
case 'slow': color = '#ffff00'; break;
case 'bomb': color = '#ff0000'; break;
}
powerups.push({
x: Math.random() * (canvas.width - player.width),
y: -player.height,
width: player.width,
height: player.height,
speed: 2,
type: type,
color: color
});
}
// 游戏状态
let isSlowed = false;
let slowEndTime = 0;
// 更新道具
function updatePowerups() {
for (let i = powerups.length - 1; i >= 0; i--) {
const powerup = powerups[i];
powerup.y += powerup.speed;
// 碰撞检测
if (
player.x < powerup.x + powerup.width &&
player.x + player.width > powerup.x &&
player.y < powerup.y + powerup.height &&
player.y + player.height > powerup.y
) {
if (powerup.type === 'shield') {
player.hasShield = true;
player.shield = 100;
} else if (powerup.type === 'score') {
score += 50;
} else if (powerup.type === 'slow') {
isSlowed = true;
slowEndTime = Date.now() + 5000; // 5秒减速效果
} else if (powerup.type === 'bomb') {
// 清除所有陨石并加分
meteors.forEach(meteor => {
score += meteor.type === 'fast' ? 2 : 1;
});
meteors = [];
}
powerups.splice(i, 1);
}
// 移除超出屏幕的道具
if (powerup.y > canvas.height) {
powerups.splice(i, 1);
}
}
// 检查减速状态
if (isSlowed && Date.now() > slowEndTime) {
isSlowed = false;
}
}
// 绘制道具
function drawPowerups() {
powerups.forEach(powerup => {
if (powerup.type === 'shield') {
// 护盾道具绘制正方形
ctx.fillStyle = powerup.color;
const centerX = powerup.x + powerup.width/2;
const centerY = powerup.y + powerup.height/2;
function drawStar(ctx, cx, cy, spikes, outerRadius, innerRadius) {
let rot = Math.PI/2;
let x = cx;
let y = cy;
let step = Math.PI/spikes;
ctx.beginPath();
ctx.moveTo(cx, cy - outerRadius);
for(let i = 0; i < spikes; i++) {
x = cx + Math.cos(rot) * outerRadius;
y = cy + Math.sin(rot) * outerRadius;
ctx.lineTo(x, y);
rot += step;
x = cx + Math.cos(rot) * innerRadius;
y = cy + Math.sin(rot) * innerRadius;
ctx.lineTo(x, y);
rot += step;
}
ctx.closePath();
}
// 绘制正方形护盾道具
ctx.fillStyle = powerup.color;
ctx.fillRect(
powerup.x,
powerup.y,
powerup.width,
powerup.height
);
// 保留护盾文字
ctx.fillStyle = '#000';
ctx.font = '13px Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('盾',
powerup.x + powerup.width/2,
powerup.y + powerup.height/2
);
} else if (powerup.type === 'slow') {
// 减速道具绘制正方形
ctx.fillStyle = powerup.color;
ctx.fillRect(
powerup.x,
powerup.y,
powerup.width,
powerup.height
);
// 添加文字
ctx.fillStyle = '#000';
ctx.font = '13px Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('减',
powerup.x + powerup.width/2,
powerup.y + powerup.height/2
);
ctx.fillStyle = '#000';
ctx.font = '13px Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('减',
powerup.x + powerup.width/2,
powerup.y + powerup.height/2
);
} else if (powerup.type === 'bomb') {
// 炸弹道具绘制正方形
ctx.fillStyle = powerup.color;
ctx.fillRect(
powerup.x,
powerup.y,
powerup.width,
powerup.height
);
// 添加文字
ctx.fillStyle = '#000';
ctx.font = '13px Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('炸',
powerup.x + powerup.width/2,
powerup.y + powerup.height/2
);
} else {
// 其他道具保持圆形
ctx.fillStyle = powerup.color;
ctx.beginPath();
ctx.arc(
powerup.x + powerup.width/2,
powerup.y + powerup.height/2,
powerup.width/2, 0, Math.PI*2
);
ctx.fill();
}
});
}
// 开始游戏
init();
initStars();
</script>
</body>
</html>