所有分类
  • 所有分类
  • 后端开发
Canvas量子机关:小家伙们的狂欢之旅

Canvas量子机关:小家伙们的狂欢之旅

这个简单的引擎里需要有三种元素:世界(World)、发射器(Launcher)、粒子(Grain)。粒子绘制主逻辑上面就是粒子绘制的主要逻辑。轮询全世界所有发射器,并更新它们的状态,创建新的粒子,绘制粒子

世界、发射器和粒子

我们在Canvas量子机关中,关键要把握好三个环节:“世界”、“投放器”还有“粒子”。世就是小颗粒们聚集的家园,投放器负责调整它们的特性,而粒子本身就是游戏中的各种东西,嬉戏玩耍于世界中。只要将三者完美配合,机关就能欢快地运转了。

你看,这个世界就像是一台巨大无比的发动机,里面全都是粒子在飞舞。只要这些小家伙待在这儿,他们就能被世界改变,感觉好好玩!想把粒子弄成什么形状?那就要看我们的发射器了。它决定粒子从哪个地方窜出来,长得多大,寿命多长之类的事情。另外,发射器还要处理那些挂掉的粒子,让整个机器运行得更顺溜。

Canvas量子机关:小家伙们的狂欢之旅

重力、热气和风

咱们在游戏里加了个新功能,就是给那些小粒子装上了三个小伙伴儿:重力、热力和风力。这样一来,原本静静呆着的它们就开始跳舞!你看,由于重力让它们向上走,热力又喜欢高点儿的地方,风还能横着飞,这么多因素一加持,小粒子们就能走出各种各样的路线,真是有趣极了!

时间标志和全局更新

define(function(require, exports, module) {
    var Util = require('./Util');
    var Launcher = require('./Launcher');
    /**
     * 世界构造函数
     * @param config
     *          backgroundImage     背景图片
     *          canvas              canvas引用
     *          context             canvas的context
     *
     *          time                世界时间
     *
     *          gravity             重力加速度
     *
     *          heat                热力
     *          heatEnable          热力开关
     *          minHeat             随机最小热力
     *          maxHeat             随机最大热力
     *
     *          wind                风力
     *          windEnable          风力开关
     *          minWind             随机最小风力
     *          maxWind             随机最大风力
     *
     *          timeProgress        时间进步单位,用于控制时间速度
     *          launchers           属于这个世界的发射器队列
     * @constructor
     */
    function World(config){
        //太长了,略去细节
    }
    World.prototype.updateStatus = function(){};
    World.prototype.timeTick = function(){};
    World.prototype.createLauncher = function(config){};
    World.prototype.drawBackground = function(){};
    module.exports = World;
});

我们在引擎里加个计时器标记,就是为了保证状态变化比如粒子的生生死死和时间效果的流利。这样以后制作瞬移或者回溯之类的功能就能简单点。当然,也别忘了外面还有个程序,留着放映游戏整体情况的口子:时不时去看看发射器需不需要update;弄点新粒子出来,把所有的都画上。

/**
 * 循环触发函数
 * 在满足条件的时候触发
 * 比如RequestAnimationFrame回调,或者setTimeout回调之后循环触发的
 * 用于维持World的生命
 */
 
World.prototype.timeTick = function(){
    //更新世界各种状态
    this.updateStatus();
    this.context.clearRect(0,0,this.canvas.width,this.canvas.height);
    this.drawBackground();
    //触发所有发射器的循环调用函数
    for(var i = 0;i<this.launchers.length;i++){
        this.launchers[i].updateLauncherStatus();
        this.launchers[i].createGrain(1);
        this.launchers[i].paintGrain();
    }
};

世界状态更新和发射器生成

为了把事情处理好,得在线搞点新粒子呀。这么一来,后面的事就顺利多了。

World.prototype.updateStatus = function(){
    this.time+=this.timeProgress;
    this.wind = Util.randomFloat(this.minWind,this.maxWind);
    this.heat = Util.randomFloat(this.minHeat,this.maxHeat);
};

发射器属性和基因

World.prototype.createLauncher = function(config){
    var _launcher = new Launcher(config);
    this.launchers.push(_launcher);
};

每根小发器都是独一无二的,位置、风速和温度各不相同。还有个秘密告诉你,每个小发器其实都有自己的「基因」,作用就在于他们是怎样变身为小粒的。不过你可能想不到,给这些小发器加入更多的基因的话,出生后的宝宝就会不像原来那么陌生~

粒子状态与绘制

每颗小颗粒就像发动机里的螺钉,有自己的特点–如位子、速度、大小,甚至是寿命!下面要做的就是算出这些颗粒下一步怎么炸开宇宙,再把它们留在墙上形成酷炫的效果。整件事关键就在于不停更新每个颗粒的现状,这样整个画面才能行云流水般顺畅

define(function (require, exports, module) {
    var Util = require('./Util');
    var Grain = require('./Grain');
    /**
     * 发射器构造函数
     * @param config
     *          id              身份标识用于后续可视化编辑器的维护
     *          world           这个launcher的宿主
     *
     *          grainImage      粒子图片
     *          grainList       粒子队列
     *          grainLife       产生的粒子的生命
     *          grainLifeRange  粒子生命波动范围
     *          maxAliveCount   最大存活粒子数量
     *
     *          x               发射器位置x
     *          y               发射器位置y
     *          rangeX          发射器位置x波动范围
     *          rangeY          发射器位置y波动范围
     *
     *          sizeX           粒子横向大小
     *          sizeY           粒子纵向大小
     *          sizeRange       粒子大小波动范围
     *
     *          mass            粒子质量(暂时没什么用)
     *          massRange       粒子质量波动范围
     *
     *          heat            发射器自身体系的热气
     *          heatEnable      发射器自身体系的热气生效开关
     *          minHeat         随机热气最小值
     *          maxHeat         随机热气最小值
     *
     *          wind            发射器自身体系的风力
     *          windEnable      发射器自身体系的风力生效开关
     *          minWind         随机风力最小值
     *          maxWind         随机风力最小值
     *
     *          grainInfluencedByWorldWind      粒子受到世界风力影响开关
     *          grainInfluencedByWorldHeat      粒子受到世界热气影响开关
     *          grainInfluencedByWorldGravity   粒子受到世界重力影响开关
     *
     *          grainInfluencedByLauncherWind   粒子受到发射器风力影响开关
     *          grainInfluencedByLauncherHeat   粒子受到发射器热气影响开关
     *
     * @constructor
     */
    function Launcher(config) {
        //太长了,略去细节
    }
    Launcher.prototype.updateLauncherStatus = function () {};
    Launcher.prototype.swipeDeadGrain = function (grain_id) {};
    Launcher.prototype.createGrain = function (count) {};
    Launcher.prototype.paintGrain = function () {};
    module.exports = Launcher;
});

试了好多回,最后终于找到了一款功能强大的Canvas粒子引擎,只需三步就可以搞定啦——创建一个世界、放上发射器以及无数可爱的小颗粒。有了这些元素,你将会看到各种炫酷的运动轨迹和逼真的动态效果,真是太棒了!而且,各个部分搭配得天衣无缝,构造成的就是一个既精致又酷炫的微观世界。

 Launcher.prototype.createGrain = function (count) {
        if (count + this.grainList.length = this.maxAliveCount &&
            count + this.grainList.length > this.maxAliveCount) {
            //光是旧的粒子数量还没能达到最大限制
            //新建了count个加上旧的超过了最大数额限制
            count = this.maxAliveCount - this.grainList.length;
        } else {
            count = 0;
        }
        for (var i = 0; i < count; i++) {
            var _rd = Util.randomFloat(0, Math.PI * 2);
            var _grain = new Grain({/*粒子配置*/});
            this.grainList.push(_grain);
        }
    };

原文链接:https://www.icz.com/technicalinformation/web/javascript/2024/04/12576.html,转载请注明出处~~~
0

评论0

请先
注意:请收藏好网址www.icz.com,防止失联!站内免费资源持续上传中…!赞助我们
显示验证码
没有账号?注册  忘记密码?