当前位置: 首页 > 科技观察

【腾讯Bugly干货】Canvas粒子引擎实战教学,教你了不起的领导和用户

时间:2023-03-11 23:19:53 科技观察

前言嗯,是“粒子引擎”还是头条,离真正的粒子引擎还是有点距离。废话少说,先看【demo】,扫描后点击屏幕有惊喜……本文将教你制作一个简单的画布粒子制作器(以下简称引擎)。世界观这个简单的引擎需要三个元素:World、Launcher和Grain。总的来说:发射器存在于世界中,发射器创建粒子,世界和发射器会影响粒子的状态,每个粒子在受到世界和发??射器影响后计算下一时刻的位置,并把自己画出来。世界(World)所谓“世界”,就是全局影响存在于这个“世界”中的粒子的环境。如果一个粒子选择存在于这个“世界”中,那么这个粒子就会受到这个“世界”的影响。Launcher用来发射粒子的单位。它们可以控制粒子生成的粒子的各种属性。发射器作为粒子的父母,可以控制粒子的出生属性:出生位置、出生大小、寿命、是否受“World”影响、是否受“Launcher”自身影响等……在此外,发射器本身也需要清理自身产生的死颗粒。粒子(Grain)的最小基本单位是每一个粒子。每个个体都有自己的位置、大小、寿命,以及是否受同名影响,以便时刻准确地描绘在画布上。粒子绘制的主要逻辑以上就是粒子绘制的主要逻辑。让我们先看看世界需要什么。创造一个世界我不知道为什么我理所当然地认为世界应该有重力加速度。但是单靠重力加速度并不能显出多少花样,所以这里我又给他加上了另外两个影响因素:热和风。重力加速度和热力加速度的方向是垂直的,风影响的方向是水平的。有了这三样东西,我们就可以让粒子动起来很骚了。有些状态的维持(比如粒子的生死)需要时间标记,所以我们给世界加上时间,方便后期做时间暂停和逆流效果。define(function(require,exports,module){varUtil=require('./Util');varLauncher=require('./Launcher');/***worldconstructor*@paramconfig*backgroundImage*canvascanvasreference*contextofcontextcanvas**time世界时间**gravity重力加速度**heat*heatEnable热开关*minHeat随机最小热*maxHeat随机最大热**windwind*windEnable风开关*minWind随机最小风*maxWind随机最大风**timeProgress时间进度单位,用于控制时间速度*launchers属于这个世界的launcher队列*@constructor*/functionWorld(config){//太长,省略细节}World.prototype.updateStatus=function(){};World.prototype.timeTick=function(){};World.prototype.createLauncher=function(config){};World.prototype.drawBackground=function(){};module.exports=World;});Everyone我们都知道绘制动画是不断重绘的,所以我们需要对外暴露一个循环调用的方法:/***循环触发函数*满足条件时触发*如RequestAnimationFrame回调,或者setTimeout回调后循环触发*用于维持World的生命*/World.prototype.timeTick=function(){//更新世界的各种状态this.updateStatus();this.context.clearRect(0,0,this.canvas.width,this.canvas.height);this.drawBackground();//触发所有launcher的循环调用函数for(vari=0;i=this.maxAliveCount&&count+this.grainList.length>this.maxAliveCount){//旧粒子数尚未达到最大限制//计数新加老的超过最大限制count=this.maxAliveCount-this.grainList.length;}else{count=0;}for(vari=0;ithis.life;};粒子应该如何显示自己?Grain.prototype.paint=function(){if(this.isDead()){this.launcher.swipeDeadGrain(this.id);}else{this.calculate();this.world.context.save();this.world.context.globalCompositeOperation='打火机';thisthis.world.context.globalAlpha=this.alpha;this.world.context.drawImage(this.launcher.grainImage,this.x-(this.sizeX)/2,this.y-(this.sizeY)/2,this.sizeX,this.sizeY);this.world.context.restore();}};希望后续可以利用这个原型进行扩展,打造一个可视化的编辑器设备供大家使用。对了,代码在这里:https://github.com/jation/CanvasGrain