zoukankan      html  css  js  c++  java
  • 用事件队列来处理pixi中的场景元素入场

    在pixi中,添加一个精灵元素,你可能需要,先将贴图load进来,然后才能添加到场景中去,所以一般会这么操作

                       Loader.add("tree","static/images/tree.png").load(function(){
                            for (var i = 0; i < 6; i++) {
                                let sprite = new PIXI.Sprite(
                                    Resources.tree.texture
                                );
                                sprite.x = (i%8)*128;
                                sprite.y = ~~(i/8 + 2)*64;
                                sprite.type = 'tree';
                                sprite.scale.x = 0.1;
                                sprite.scale.y = 0.1;
                                sprite._zIndex = -1;
                                sprite.buttonMode = true;
                                sprite.interactive = true;
                                sprite.on('pointerdown', function(){
                                    console.log(this)
                                });
                                app.stage.addChild(sprite);
                            }
                        });

    不难看出,上述代码,往场景中加了6棵树。

    当要添加很多不同元素的时候,需要的贴图可能会很多,而且load贴图是不能同时load两张以上的贴图,会报如下错误

    所以,雪碧图就产生了,将多张资源贴图整合在一起,生成一张图(用texturepacker工具可以附带生成一个json,不用手动计算每一帧所需的图片在雪碧图中的位置,很方便)

    但是,我觉得这样的话,所有的元素都会由于雪碧图的原因,不得不将不同元素的业务逻辑集中写在同一个雪碧图load后的回调里面,个人感觉很鸡肋,耦合度过高!

    于是,我想到了用事件队列。

    一、用事件队列管理不同元素的业务逻辑

    具体代码,长这样:

    效果是这样的:

    人物由上下左右键控制运动;

    松鼠自由运动,每3秒随机换个方向;

    寸草不生的土地由136个精灵拼接而成;

    一片水和6棵树。

    二、代码解析

    //任务队列对象
    var tasklist = {
                task:[],
                run:function(){
                    var task = this.task.shift();
                    if(task){
                        task();
                    }
                },
                push:function(task){
                    this.task.push(task)
                }
    };
    
    //单个任务
    function tasktree(){
          Loader.add("tree","static/images/tree.png").load(function(){
                tasklist.run();
                for (var i = 0; i < 6; i++) {
                     let sprite = new PIXI.Sprite(
                         Resources.tree.texture
                     );
                     sprite.x = (i%8)*128;
                     sprite.y = ~~(i/8 + 2)*64;
                     sprite.type = 'tree';
                     sprite.scale.x = 0.1;
                     sprite.scale.y = 0.1;
                     sprite.buttonMode = true;
                     sprite.interactive = true;
                     sprite.on('pointerdown', function(){
                          console.log(this)
                     });
                     app.stage.addChild(sprite);
                }
           });
    }
    
    //任务队列初始化和开始运行
    tasklist.task=[taskground,taskwater,taskperson,tasktree,taskanimal];
    tasklist.run();

    该事件队列机制的核心就在于利用数组的shift()方法模拟了队列的FIFO规则,并且规避了不能同时load两个以上贴图的问题。

    因为上述红色粗体字可以看出,上一个任务的贴图load结束之后,立马load下一个任务的贴图,并且此时同步执行上个任务的逻辑部分,如此循环直到任务队列里面的任务全部清空。

    有了这个事件队列机制,大大地降低了各个场景元素之间的雪碧图加载的带来的这种高耦合度问题。并且场景元素的加载与拆卸也会变得很便捷,只要不把这个任务放到事件队列里面那么他就不会被被执行,并且不会影响其他代码块的执行。

    是不是很方便呢?如果你有更好的方法,不妨在下方评论

  • 相关阅读:
    mktemp -t -d用法
    使用getopts处理输入参数
    linux中$1的意思
    linux中的set -e 与set -o pipefail
    在windows 7 和linux上安装xlwt和xlrd
    nginx map使用方法
    Linux crontab下关于使用date命令和sudo命令的坑
    东哥讲义
    ldapsearch使用
    date 命令之日期和秒数转换
  • 原文地址:https://www.cnblogs.com/eco-just/p/11437760.html
Copyright © 2011-2022 走看看