各位道友久候!上集我们炼就了《灵蛇奇谭》的元神,今日将开启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.98
p.x += p.vx
p.y += p.vy
p.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.life
ctx.fill()
})
}
}
第四转:物理宇宙·因果律引擎
自主研制的2D物理规则
class PhysicsEngine {
constructor() {
this.objects = [] // 注册的物理实体
this.gravity = 0.5 // 重力加速度
this.airResistance = 0.99 // 空气阻力
}
add(obj) {
obj.vx = obj.vx || 0
obj.vy = obj.vy || 0
this.objects.push(obj)
}
update() {
this.objects.forEach(obj => {
// 牛顿第一定律
obj.vy += this.gravity
obj.vx *= this.airResistance
obj.vy *= this.airResistance
// 更新坐标
obj.x += obj.vx
obj.y += obj.vy
// 边界反弹(非弹性碰撞)
if(obj.x <0 || obj.x > canvas.width) {
obj.vx *= -0.8
obj.x = Math.max(0, Math.min(obj.x, canvas.width))
}
if(obj.y > canvas.height) {
obj.vy *= -0.7
obj.y = canvas.height
obj.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.x
const dy = a.y - b.y
const distance = Math.sqrt(dx*dx + dy*dy)
return distance < a.radius + b.radius
}
resolveCollision(a, b) {
// 动量守恒计算
const nx = (b.x - a.x) / distance
const ny = (b.y - a.y) / distance
const 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 * nx
a.vy = a.vy - p * a.mass * ny
b.vx = b.vx + p * b.mass * nx
b.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 = true
return 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 = 0
this.music.volume = 0.3
this.music.play()
}
}
// 在碰撞发生时触发
function handleCollision() {
audioManager.playExplode()
}
渡劫答案揭晓(金丹九问)
- 残影特效:不清空画布+叠加半透明背景
- Math.cos作用:计算粒子运动X分量
- nextDirection:防止同一帧内连续转向
- 粒子优化:对象池+限制数量+简化绘制
- 瓦片地图:用二维数组存储地形索引
金丹境毕业标准:
✅ 能实现复杂粒子特效
✅ 掌握基础物理模拟
✅ 熟练运用性能优化
✅ 整合多媒体交互
(道友们请结合上下集代码炼制《量子贪吃蛇》小游戏)
👉 下期预告:《第四重天·元婴境——WebGL与Three.js破碎虚空》,将传授:
- 三维空间造物法则
- GLSL着色器编写
- 模型加载与骨骼动画
- 真实光影渲染
道阻且长,行则将至,我们元婴境再见!🚀