各位道友久候!上集我們煉就了《靈蛇奇譚》的元神,今日將開啟Canvas修仙路上最絢麗的篇章——掌控微觀粒子的創世之力!(ノ≧?≦)ノ
章前黑話詞典
🔍 量子境術語表:
- 對象池(Object Pool):粒子輪回轉生的往生池
- 貝塞爾曲線(Bézier):繪制流體軌跡的時空扭曲術
- 四叉樹(Quadtree):快速檢索的空間切割大陣
- 離屏渲染(Offscreen):提前繪制的時空鏡像術
- 卷積濾鏡(Convolution):改變物質形態的造化爐
第三轉:量子煙花·混沌初開
完整粒子系統架構
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物理規則
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}
}
第五轉:性能渡劫·時空法則
三大優化禁術
🪄 禁術一:對象池復活術
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
}
🔮 禁術二:臟矩形凈衣訣
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 = [] // 重置記錄
}
🌌 禁術三:離屏鏡像術
// 創建離屏畫布
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())
}
第六轉:音律大道·元神共鳴
游戲音效融合術
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著色器編寫
- 模型加載與骨骼動畫
- 真實光影渲染
道阻且長,行則將至,我們元嬰境再見!🚀