• 【h5-egret】深入浅出对象池


    最近看到对象池这一块的东西,是频繁创建删除类型游戏优化性能的一个解决方案。

    简单来讲对象池就是个数组,把不用的对象放进去,因为数组还保存了对象的引用,所以对象不会被回收,等需要用的时候再从数组中取出来。

    这类的游戏大概是打飞机这一类的游戏,频繁创建子弹,和删除子弹,敌机等。

    参考资料,传送门:http://bbs.egret.com/thread-1017-1-1.html;http://bbs.egret.com/thread-256-1-1.html。

    1.一个简单的对象池

    好,让我们先对对象池来一个简单的理解。

    // 回收不用的对象
    public recycleObject(noUse:any):void  
    {  
        this._pool.push(noUse);  
    } 
    // 需要用这个对象的时候,先检索对象池有没有缓存对象,有的话取出来以后初始化属性,对象池是空的话再创建新对象
    
    public getObject():any
    {
        if(this._pool.length)
            return this._pool.shift();
        else
            return new egret.Bitmap(); //用bitmap作示例
    }

    需要创建对象的时候,调用getObject方法,不需要的对象实例通过recycleObject方法回收。

    这就是一个简单的对象池。

    2.来来来,看一段干货

     
    我打算用注释来搞定一段非常优秀的干货:
     
     
    // 声明一个存放对象池数组 的数组
    private static cacheDict:Object = {};
    
    // 创建对象,对象池有就拿出来初始化,没有就创建一个对象。(冒号后面是返回值,返回值的类型就是我们的缓存对象。)
    public static produce(textureName:string):fighter.Airplane
    {
    
      // textureName 是缓存对象的标识,这样的写法的好处是可以缓存多种不同的对象,比如飞机有两种,“p1”,“p2”。
      // 如果textureName对应的对象池为空的话,初始化一个对象池。
      if(fighter.Airplane.cacheDict[textureName]==null){
        fighter.Airplane.cacheDict[textureName] = [];
      }
    
      //根据对象的标示textureName找到对象缓存池数组
      var dict:fighter.Airplane[] = fighter.Airplane.cacheDict[textureName];
    
      // 声明一个对象来接收需要返回出去的对象
      var theFighter:fighter.Airplane;
    
      // 如果对象池有对象就把对象拿出来用,否则创建一个对象
      if(dict.length>0) {
        theFighter = dict.pop();
      } else {
        theFighter = new fighter.Airplane(RES.getRes(textureName));
      }
      // 返回对象
      return theFighter;
    }
    
    // 回收对象
    public static reclaim(theFighter:fighter.Airplane,textureName:string):void
    {
    
      // 如果textureName对应的对象池为空的话,初始化一个对象池。
      if(fighter.Airplane.cacheDict[textureName]==null){
        fighter.Airplane.cacheDict[textureName] = [];
      }
    
      // 根据对象的标示textureName找到对象缓存池数组
      var dict:fighter.Airplane[] = fighter.Airplane.cacheDict[textureName];
    
      // 如果对象池里面没有这个对象,那么缓存进对象池
      if(dict.indexOf(theFighter)==-1){
        dict.push(theFighter);
      }
    }

    流程解析(比如打飞机的子弹):

    1.创建:定时器创建子弹,创建1个,produce一次,创建第二个,继续produce一次,创建多少,produce多少次。因为还没有回收的对象,所以调用的都是theFighter = new fighter.Airplane(RES.getRes(textureName))这句,来新建对象;

    2:回收:等到子弹碰到敌机或者飞出界面的时候,就可以reclaim了,回收对象,此刻对象池就有回收的对象了。一个,两个,回收多少,对象池就多少对象,回收的对象,都是一种对象。

    3:回收之后创建:当定时器再创建子弹的时候,就直接去取对象池的对象,因为回收了对象,而且所有的对象都是一种,就直接pop或者shift推出来,然后对象池删除推出来使用的对象。

    对象池就这么简单的搞定了。

    MT.Team

     
  • 相关阅读:
    mhWaveEdit 1.4.8
    FFmpeg — 屏幕录制器材
    GNOME 主题: Troll
    cGmail — 主动反省邮件
    最小化布置 Ubuntu
    GNOME Do — 疾速翻开法式和文件
    PyTone 一个控制台音乐播放器
    高恪守编辑器 VIM-把持篇(2)
    Cankiri:玲珑实用的屏幕录像机
    LiVES 0.9.6pre4
  • 原文地址:https://www.cnblogs.com/mtTeam/p/4881544.html
Copyright © 2020-2023  润新知