烟花模拟器:满屏流光炸开,过年气氛一秒拉满

举报
deli007 发表于 2026/09/23 11:10:52 2026/09/23
【摘要】 烟花模拟器:满屏流光炸开,过年气氛一秒拉满

烟花最好看的是炸开的那一瞬间,但平时很难随手放一场。这个烟花模拟器把夜空、星点和爆炸拖尾都搬进浏览器:点哪里哪里就炸,也会在夜空自动随机绽放;一次能连发 6 发,8 套配色一键切换,爆炸形态分成散花、圆环、柳树三种。先看成品,再讲这个单文件应用是怎么用一段需求让码道 WebUI 生成并部署出来的。

烟花模拟器运行效果

为什么值得看

烟花的本质是一套粒子系统:一颗火箭升到目标点后炸散成几十个带速度的粒子,重力把它们往下拉,流光拖尾靠半透明残影一层层叠出来。把爆炸形态、配色、连发都做成可调项之后,粒子系统的「出生—更新—消亡」这条主线比看教程直观得多。这个工具适合想理解 Canvas 动画又不想先啃一整套引擎的人。

任务描述

在码道 WebUI 输入框粘贴以下需求,回车发送:

开发一个烟花秀模拟器网页应用:深色夜空背景,烟花可以在夜空随机自动绽放,也支持点击画面手动放烟花;烟花要有彩色粒子、流光拖尾、重力下落和轻微闪烁,支持切换配色并一键连发多个烟花;界面简洁美观,单个 index.html 即跑即玩。完成后自动部署成可访问的网页应用,并把访问地址写出来。

码道实际做了什么

我没有让它手写每一步,只说清楚最终效果。它这轮的动作是:

  • 在工作目录下新建项目目录,写入单文件 index.html,随后又做了几次增删改,把爆炸形态、配色和连发逻辑补齐。
  • 从页面里提取内嵌 JavaScript,用 node --check 做语法检查,确认没有语法错误。
  • 探测空闲端口(这轮是 3000),用 python3 -m http.server 启动静态服务,curl 自检 HTTP 200 后给出内部预览地址。
  • 最后把功能清单、文件位置和访问地址一起写回对话,预览地址就在对话末尾。

代码亮点

1. 随机工具:所有随机范围都走同一行

爆炸点、星点大小、闪烁相位都复用这两个函数,避免到处写 Math.random()

const rand = (a, b) => a + Math.random() * (b - a);
const pick = arr => arr[(Math.random() * arr.length) | 0];

2. 三种爆炸形态靠随机阈值分流

同一发火箭升到目标点,按随机值切成散花、圆环、柳树三种形态:

function launch(targetX, targetY) {
  const palette = PALETTES[paletteIdx].colors;
  const type = Math.random();
  const opts = {
    x: targetX == null ? rand(W * 0.12, W * 0.88) : targetX,
    y: H + rand(0, 40),
    tx: targetY == null ? rand(H * 0.12, H * 0.5) : targetY,
    colors: palette,
    kind: type < 0.55 ? 'burst' : type < 0.82 ? 'ring' : 'willow',
  };
  rockets.push(new Rocket(opts));
}

3. 拖尾用半透明覆盖代替 clearRect

每一帧不把画布彻底擦干净,而是铺一层几乎透明的深色,上一帧的粒子就自然留下残影;粒子数组从后往前遍历,删除时可以安全 splice

function frame(now) {
  const t = now * 0.001;

  ctx.fillStyle = 'rgba(5,6,15,0.28)';
  ctx.fillRect(0, 0, W, H);

  drawStars(t);

  for (let i = rockets.length - 1; i >= 0; i--) {
    if (!rockets[i].update()) rockets.splice(i, 1);
  }
  for (let i = particles.length - 1; i >= 0; i--) {
    if (!particles[i].update()) particles.splice(i, 1);
  }

自动放烟花也不是 setInterval 写死,而是每次随机 0.9–2.2 秒再排下一次:

function scheduleAuto() {
  clearTimeout(autoTimer);
  if (!autoEnabled) return;
  autoTimer = setTimeout(() => {
    launch();
    scheduleAuto();
  }, rand(900, 2200));
}

验证与踩坑

  • 生成结束后打开对话里的内部预览地址,页面标题是「烟花模拟器」,烟花确实会自动炸开。
  • 隔几秒连截两张运行画面,两个文件内容不重复:自动烟花的时间间隔是随机数,画面本来就一直在变。
  • 踩坑:内部预览链接偶发跳到开发者空间登录跳转页,重新打开一次才稳定进入应用。截图前先确认页面标题或 Canvas 已经出现,避免截到空白页。
  • 从代码看,拖尾浓淡由 rgba(5,6,15,0.28) 的 alpha 决定;这个值越低屏幕越难清干净,越高拖尾越短。这是最容易调出「炸完就糊成一团」的地方。

本地复现

项目是单文件 index.html,没有第三方依赖。把文件保存到本地后直接用浏览器打开就能玩;如果想通过本地 HTTP 服务访问:

cd codearts-fireworks-sky
python3 -m http.server 8080
# 然后打开 http://127.0.0.1:8080

直接下载试玩

源码同步到公开 Demo Park 仓库:

准备环境:进入 AI 开发者空间

本文用码道 WebUI 版演示。先进入 AI 开发者空间并选择体验版,不需要本地安装:

  1. 浏览器打开 https://devstation.developer.huaweicloud.com/aidevspace?utm_source=opcsfsq&utm_medium=wbwz
  2. 弹窗「请选择要进入的版本」→ 点击 体验版
  3. 首次使用跳到华为云登录页,登录一次后浏览器会话可复用
  4. 弹窗「临时凭据自动配置」→ 点击 同意,沙箱自动创建

进入主界面后,等左侧菜单加载出来,找到 CodeArts,点它右侧的浏览器图标,就打开了码道 WebUI 对话窗口。

AI 开发者空间主界面

开通后有三种使用方式:WebUI(浏览器对话)、TUI(终端命令行)和桌面 IDE(IDE 插件)。本文用 WebUI 版演示。

进入 CodeArts:https://developer.huaweicloud.com/codeartsco.html?source=dmzntgwsf&sourcead=dmzntgwwbwz

码道 WebUI 生成完成

使用码道体会

最省事的是「部署」这步:以前写单文件小工具,写完还要自己开本地服务、找端口;这次让它在需求里顺带把服务起好,拿到 URL 就能在浏览器里看。生成过程中它还会自己跑一遍 JS 语法检查,出错先修再往下走,比直接扔给我一坨代码再让我 debug 舒服。不足是内部预览链接有偶发跳转,需要重开一次;体验版环境 3 小时会释放,所以要记得立刻保存 index.html 和截图。

总结

烟花模拟器把粒子系统的核心链路浓缩成一个单文件:随机工具负责所有不确定性,launch() 负责火箭与爆炸形态,frame() 用半透明覆盖制造流光拖尾。8 套配色和连发按钮让「放烟花」这件小事变得有按钮可按。后续可以加音效、慢动作回放,或者把爆炸形态做成可勾选项,让一场烟花能按自己的顺序来。

烟花模拟器运行效果对照

连续截取的两个运行画面,左边是自动烟花炸开瞬间,右边是数秒后的另一帧:

烟花模拟器运行对比

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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