各位道友久候!上集我们炼就了《灵蛇奇谭》的元神,今日将开启Canvas修仙路上最绚丽的篇章——掌控微观粒子的创世之力!(ノ≧∀≦)ノ
章前黑话词典
🔍 量子境术语表:
- 对象池(Object Pool):粒子轮回转生的往生池
- 贝塞尔曲线(Bézier):绘制流体轨迹的时空扭曲术
- 四叉树(Quadtree):快速检索的空间切割大阵
- 离屏渲染(Offscreen):提前绘制的时空镜像术
- 卷积滤镜(Convolution):改变物质形态的造化炉
第三转:量子烟花·混沌初开
完整粒子系统架构
javascript">class QuantumFirework {constructor(x, y) {this.particles = []// 能量核心爆炸this.explode(x, y) }explode(x, y) {const hue = Math.random() * 360// 生成量子纠缠粒子群for(let i=0; i<360; i+=6) {const radian = i * Math.PI / 180// 量子态随机参数const config = {x, y,vx: Math.cos(radian) * (3 + Math.random()*5),vy: Math.sin(radian) * (3 + Math.random()*5),life: 1, // 生命周期decay: 0.015 + Math.random()*0.02, // 衰变速度size: 2 + Math.random()*4,hue: hue + Math.random()*30 -15 // 色相波动}this.particles.push(config)}}update() {this.particles.forEach(p => {// 经典力学模拟p.vy += 0.1 // 重力p.vx *= 0.98 // 空气阻力p.vy *= 0.98p.x += p.vxp.y += p.vyp.life -= p.decay // 寿命衰减})// 清除死亡粒子this.particles = this.particles.filter(p => p.life > 0)}draw() {this.particles.forEach(p => {ctx.beginPath()// 生命末期缩小const size = p.size * p.life ctx.arc(p.x, p.y, size, 0, Math.PI*2)// 颜色生命周期渐变ctx.fillStyle = `hsla(${p.hue}, 70%, 50%, ${p.life*0.7})`ctx.fill()// 添加光晕ctx.shadowColor = `hsl(${p.hue}, 100%, 50%)`ctx.shadowBlur = 20 * p.lifectx.fill()})}
}
第四转:物理宇宙·因果律引擎
自主研制的2D物理规则
javascript">class PhysicsEngine {constructor() {this.objects = [] // 注册的物理实体this.gravity = 0.5 // 重力加速度this.airResistance = 0.99 // 空气阻力}add(obj) {obj.vx = obj.vx || 0obj.vy = obj.vy || 0this.objects.push(obj)}update() {this.objects.forEach(obj => {// 牛顿第一定律obj.vy += this.gravityobj.vx *= this.airResistanceobj.vy *= this.airResistance// 更新坐标obj.x += obj.vxobj.y += obj.vy// 边界反弹(非弹性碰撞)if(obj.x <0 || obj.x > canvas.width) {obj.vx *= -0.8obj.x = Math.max(0, Math.min(obj.x, canvas.width))}if(obj.y > canvas.height) {obj.vy *= -0.7obj.y = canvas.heightobj.vx *= 0.9 // 摩擦力}})// 双循环检测碰撞(实际项目应使用四叉树优化)for(let i=0; i<this.objects.length; i++) {for(let j=i+1; j<this.objects.length; j++) {const a = this.objects[i]const b = this.objects[j]if(this.checkCollision(a, b)) {this.resolveCollision(a, b)}}}}checkCollision(a, b) {// 圆形碰撞检测const dx = a.x - b.xconst dy = a.y - b.yconst distance = Math.sqrt(dx*dx + dy*dy)return distance < a.radius + b.radius}resolveCollision(a, b) {// 动量守恒计算const nx = (b.x - a.x) / distanceconst ny = (b.y - a.y) / distanceconst p = 2 * (a.vx * nx + a.vy * ny - b.vx * nx - b.vy * ny) / (a.mass + b.mass)a.vx = a.vx - p * a.mass * nxa.vy = a.vy - p * a.mass * nyb.vx = b.vx + p * b.mass * nxb.vy = b.vy + p * b.mass * ny}
}
第五转:性能渡劫·时空法则
三大优化禁术
🪄 禁术一:对象池复活术
javascript">class ParticlePool {constructor(maxSize) {this.pool = Array(maxSize).fill().map(() => ({active: false,x:0, y:0, vx:0, vy:0, life:1}))}get() {// 寻找可复活对象const obj = this.pool.find(p => !p.active)if(obj) {obj.active = truereturn obj}return null // 池已耗尽}recycle(obj) {obj.active = false}
}// 使用示例
const pool = new ParticlePool(1000)function createParticle(x,y) {const p = pool.get() || { active: true } // 降级方案Object.assign(p, {x,y,vx:0,vy:0,life:1})return p
}
🔮 禁术二:脏矩形净衣诀
javascript">let dirtyRects = []// 记录变化区域
function addDirtyRect(x, y, w, h) {dirtyRects.push({x,y,w,h})
}// 增量渲染
function smartRender() {// 清空脏区域dirtyRects.forEach(rect => {ctx.clearRect(rect.x-5, rect.y-5, rect.w+10, rect.h+10)})// 仅重绘受影响元素objects.forEach(obj => {if(isInDirtyArea(obj)) {obj.draw()}})dirtyRects = [] // 重置记录
}
🌌 禁术三:离屏镜像术
javascript">// 创建离屏画布
const bufferCanvas = document.createElement('canvas')
bufferCanvas.width = 800
bufferCanvas.height = 600
const bufferCtx = bufferCanvas.getContext('2d')// 预渲染静态背景
function renderBackground() {bufferCtx.fillStyle = '#000'bufferCtx.fillRect(0,0,800,600)// 绘制星空for(let i=0; i<200; i++){bufferCtx.beginPath()bufferCtx.arc(Math.random()*800,Math.random()*600,Math.random()*2,0, Math.PI*2)bufferCtx.fillStyle = '#fff'bufferCtx.fill()}
}// 主渲染循环
function render() {// 直接拷贝静态背景ctx.drawImage(bufferCanvas, 0, 0)// 叠加动态元素dynamicObjects.forEach(obj => obj.draw())
}
第六转:音律大道·元神共鸣
游戏音效融合术
javascript">class AudioManager {constructor() {this.sounds = {explode: this.loadSound('explode.mp3'),bounce: this.loadSound('bounce.wav'),collect: this.loadSound('collect.ogg')}this.music = new Audio('bgm.mp3')this.music.loop = true}loadSound(url) {const audio = new Audio(url)audio.load()return {play: () => audio.cloneNode(true).play(), // 允许同时播放多个stop: () => audio.pause()}}playExplode() {this.sounds.explode.play()}startBGM() {this.music.currentTime = 0this.music.volume = 0.3this.music.play()}
}// 在碰撞发生时触发
function handleCollision() {audioManager.playExplode()
}
渡劫答案揭晓(金丹九问)
- 残影特效:不清空画布+叠加半透明背景
- Math.cos作用:计算粒子运动X分量
- nextDirection:防止同一帧内连续转向
- 粒子优化:对象池+限制数量+简化绘制
- 瓦片地图:用二维数组存储地形索引
金丹境毕业标准:
✅ 能实现复杂粒子特效
✅ 掌握基础物理模拟
✅ 熟练运用性能优化
✅ 整合多媒体交互
(道友们请结合上下集代码炼制《量子贪吃蛇》小游戏)
👉 下期预告:《第四重天·元婴境——WebGL与Three.js破碎虚空》,将传授:
- 三维空间造物法则
- GLSL着色器编写
- 模型加载与骨骼动画
- 真实光影渲染
道阻且长,行则将至,我们元婴境再见!🚀