提示词:
制作一个网页小游戏,网页标题名为“浪漫烟花”,游戏功能为鼠标点击网页底部区域任意位置,实现在点击位置燃放上升多个烟花,在屏幕上方位置绚丽绽放,网页背景黑色,所有代码保存在一个网页里。设置有1%-5%概率绽放一朵玫瑰花烟花,设置有0.5%概率绽放满屏樱花。不需要显示音乐控制按钮,打开页面就播放背景音乐。
背景音乐,引用下面链接:https://www.aibxm.com/yanhua/bj.ogg
鼠标点击底部区域时烟花发射音效,引用下面链接:https://www.aibxm.com/yanhua/shoot.ogg
烟花在上部区域爆炸时音效,引用下面链接:https://www.aibxm.com/yanhua/explode.ogg
成品地址:
浪漫烟花 (使用智谱清言制作)
浪漫烟花 (使用智谱清言制作,带音乐开关版)
浪漫烟花 (使用通义千问制作)
浪漫烟花 (使用Kimi 智能助手制作)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>浪漫烟花-使用智谱清言制作</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #000;
overflow: hidden;
font-family: Arial, sans-serif;
cursor: crosshair;
}
canvas {
display: block;
width: 100vw;
height: 100vh;
}
.hint {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
color: rgba(255, 255, 255, 0.5);
font-size: 14px;
pointer-events: none;
animation: fadeInOut 3s ease-in-out infinite;
}
@keyframes fadeInOut {
0%, 100% { opacity: 0.3; }
50% { opacity: 0.8; }
}
</style>
</head>
<body>
<canvas id="fireworksCanvas"></canvas>
<div>点击底部区域燃放烟花</div>
<!-- 音频元素 -->
<audio id="bgMusic" loop>
<source src="https://www.aibxm.com/yanhua/bj.ogg" type="audio/ogg">
</audio>
<audio id="shootSound">
<source src="https://www.aibxm.com/yanhua/shoot.ogg" type="audio/ogg">
</audio>
<audio id="explodeSound">
<source src="https://www.aibxm.com/yanhua/explode.ogg" type="audio/ogg">
</audio>
<script>
const canvas = document.getElementById('fireworksCanvas');
const ctx = canvas.getContext('2d');
const bgMusic = document.getElementById('bgMusic');
const shootSound = document.getElementById('shootSound');
const explodeSound = document.getElementById('explodeSound');
// 设置画布大小
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
// 烟花数组
let fireworks = [];
let particles = [];
let sakuraParticles = [];
// 烟花类
class Firework {
constructor(x, y, targetY, color) {
this.x = x;
this.y = y;
this.targetY = targetY;
this.color = color;
this.velocity = -15 - Math.random() * 5;
this.gravity = 0.3;
this.opacity = 1;
this.trail = [];
}
update() {
this.trail.push({ x: this.x, y: this.y, opacity: this.opacity });
if (this.trail.length > 10) {
this.trail.shift();
}
this.velocity += this.gravity;
this.y += this.velocity;
if (this.y <= this.targetY || this.velocity >= 0) {
this.explode();
return false;
}
return true;
}
draw() {
// 绘制轨迹
this.trail.forEach((point, index) => {
ctx.save();
ctx.globalAlpha = point.opacity * (index / this.trail.length);
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(point.x, point.y, 2, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
});
// 绘制烟花本体
ctx.save();
ctx.globalAlpha = this.opacity;
ctx.fillStyle = this.color;
ctx.shadowBlur = 10;
ctx.shadowColor = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, 3, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
}
explode() {
explodeSound.currentTime = 0;
explodeSound.play().catch(e => console.log('音效播放失败'));
const random = Math.random();
if (random < 0.005) {
// 0.5% 概率满屏樱花
this.createSakuraExplosion();
} else if (random < 0.025 + Math.random() * 0.025) {
// 1%-5% 概率玫瑰花
this.createRoseExplosion();
} else {
// 普通烟花
this.createNormalExplosion();
}
}
createNormalExplosion() {
const particleCount = 50 + Math.random() * 50;
for (let i = 0; i < particleCount; i++) {
const angle = (Math.PI * 2 / particleCount) * i + Math.random() * 0.5;
const velocity = 3 + Math.random() * 5;
particles.push(new Particle(
this.x,
this.y,
Math.cos(angle) * velocity,
Math.sin(angle) * velocity,
this.color
));
}
}
createRoseExplosion() {
// 玫瑰花形状
const petalCount = 8;
for (let i = 0; i < petalCount; i++) {
const angle = (Math.PI * 2 / petalCount) * i;
for (let j = 0; j < 20; j++) {
const radius = j * 2;
const x = this.x + Math.cos(angle) * radius;
const y = this.y + Math.sin(angle) * radius;
particles.push(new Particle(
x,
y,
Math.cos(angle) * 2,
Math.sin(angle) * 2,
`hsl(${330 + Math.random() * 30}, 100%, ${50 + Math.random() * 20}%)`
));
}
}
}
createSakuraExplosion() {
// 满屏樱花
for (let i = 0; i < 200; i++) {
sakuraParticles.push(new SakuraParticle(
Math.random() * canvas.width,
-10,
Math.random() * 2 - 1,
1 + Math.random() * 2
));
}
}
}
// 粒子类
class Particle {
constructor(x, y, vx, vy, color) {
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.color = color;
this.gravity = 0.1;
this.opacity = 1;
this.decay = 0.015 + Math.random() * 0.01;
this.size = 2 + Math.random() * 2;
}
update() {
this.vx *= 0.99;
this.vy *= 0.99;
this.vy += this.gravity;
this.x += this.vx;
this.y += this.vy;
this.opacity -= this.decay;
this.size *= 0.98;
return this.opacity > 0;
}
draw() {
ctx.save();
ctx.globalAlpha = this.opacity;
ctx.fillStyle = this.color;
ctx.shadowBlur = 10;
ctx.shadowColor = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
}
}
// 樱花粒子类
class SakuraParticle {
constructor(x, y, vx, vy) {
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.size = 5 + Math.random() * 5;
this.opacity = 1;
this.rotation = Math.random() * Math.PI * 2;
this.rotationSpeed = (Math.random() - 0.5) * 0.1;
this.swayAmplitude = Math.random() * 30 + 10;
this.swaySpeed = Math.random() * 0.02 + 0.01;
this.time = 0;
}
update() {
this.time += this.swaySpeed;
this.x += this.vx + Math.sin(this.time) * this.swayAmplitude * 0.01;
this.y += this.vy;
this.rotation += this.rotationSpeed;
this.opacity -= 0.003;
return this.opacity > 0 && this.y < canvas.height + 10;
}
draw() {
ctx.save();
ctx.globalAlpha = this.opacity;
ctx.translate(this.x, this.y);
ctx.rotate(this.rotation);
// 绘制樱花花瓣
ctx.fillStyle = '#ffb7c5';
ctx.beginPath();
for (let i = 0; i < 5; i++) {
const angle = (Math.PI * 2 / 5) * i;
const x = Math.cos(angle) * this.size;
const y = Math.sin(angle) * this.size;
if (i === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
}
ctx.closePath();
ctx.fill();
ctx.restore();
}
}
// 鼠标点击事件
canvas.addEventListener('click', (e) => {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// 只在底部区域响应点击(下半部分)
if (y > canvas.height / 2) {
shootSound.currentTime = 0;
shootSound.play().catch(e => console.log('音效播放失败'));
// 发射多个烟花
const fireworkCount = 3 + Math.floor(Math.random() * 3);
for (let i = 0; i < fireworkCount; i++) {
setTimeout(() => {
const offsetX = (Math.random() - 0.5) * 100;
const targetY = 100 + Math.random() * 200;
const hue = Math.random() * 360;
const color = `hsl(${hue}, 100%, 50%)`;
fireworks.push(new Firework(
x + offsetX,
y,
targetY,
color
));
}, i * 100);
}
}
});
// 动画循环
function animate() {
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 更新和绘制烟花
fireworks = fireworks.filter(firework => {
firework.draw();
return firework.update();
});
// 更新和绘制粒子
particles = particles.filter(particle => {
particle.draw();
return particle.update();
});
// 更新和绘制樱花
sakuraParticles = sakuraParticles.filter(sakura => {
sakura.draw();
return sakura.update();
});
requestAnimationFrame(animate);
}
// 启动动画
animate();
// 尝试自动播放背景音乐
document.addEventListener('click', () => {
if (bgMusic.paused) {
bgMusic.play().catch(e => console.log('背景音乐播放失败'));
}
}, { once: true });
// 页面加载时尝试播放背景音乐
window.addEventListener('load', () => {
bgMusic.volume = 0.3;
bgMusic.play().catch(e => {
console.log('自动播放被阻止,需要用户交互');
});
});
</script>
</body>
</html>