《Canvas修仙传·第三重天金丹境(下集)》 ——量子烟花与物理宇宙的混沌法则

各位道友久候!上集我们炼就了《灵蛇奇谭》的元神,今日将开启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()
}

渡劫答案揭晓(金丹九问)

  1. 残影特效:不清空画布+叠加半透明背景
  2. Math.cos作用:计算粒子运动X分量
  3. nextDirection:防止同一帧内连续转向
  4. 粒子优化:对象池+限制数量+简化绘制
  5. 瓦片地图:用二维数组存储地形索引

金丹境毕业标准
✅ 能实现复杂粒子特效
✅ 掌握基础物理模拟
✅ 熟练运用性能优化
✅ 整合多媒体交互

(道友们请结合上下集代码炼制《量子贪吃蛇》小游戏)

👉 下期预告:《第四重天·元婴境——WebGL与Three.js破碎虚空》,将传授:

  • 三维空间造物法则
  • GLSL着色器编写
  • 模型加载与骨骼动画
  • 真实光影渲染

道阻且长,行则将至,我们元婴境再见!🚀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值