对象池优化内存

2019-06-19  本文已影响0人  mcgee0731

对象池优化内存

1. 对象池优化是游戏开发中非常重要的优化方式,也是影响游戏性能的重要因素之一
2. 游戏中有许多对象会不停的创建与移除,比如角色攻击子弹,特效的创建与移除,NPC(非玩家角色)的被消灭与刷新等,在创建过程中非常消耗性能,特别是数量多的情况下
3. 对象池技术能很好解决以上问题,在对象移除消失的时候回收到对象池,需要新对象的时候直接从对象池中取出使用
4. 对象池的优点是减少了实例化对象时的开销,且能让对象反复使用,减少了新内存分配与垃圾回收器运行的机会
5. 注意:对象移除时并不是立即从内存中抹去,只有认为内存不足时,才会使用垃圾回收机制清空,清空时很耗内存,很可能就会造成卡顿现象,用了对象池后将减少程序的垃圾对象,有效的提高程序运行速度和稳定性

对象池 Pool

Package laya.utils
public class
Inheritance Pool->ObjectPool 
Pool是对象池类,用于对象的存贮、重复使用。合理使用对象池,可以>有效减少对象创建的开销,避免频繁的垃圾回收,从而优化游戏流畅度。

Laya的API链接地址

其中较常用的是getItemByClass()recover() 方法

Laya.init(1136, 640, Laya.WebGL);//初始化引擎,不支持 WebGL自动切换为Canvas
Laya.Stat.show(0, 0);/**显示性能面板 */
Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;//按照最小比率缩放
Laya.stage.bgColor = "#232628";//背景颜色
Laya.timer.frameLoop(1, this, onFrame);//帧循环,每隔1帧调用一次 onFrame函数
var createTime = 0;
/**帧动画回调 */
function onFrame() {
    //如果创建对象时间为100帧间隔后,即间隔100帧(约1.6秒)生成100个雪花从天而降
    if (createTime >= 100) {
        for (var i = 0; i < 100; i++) {//每100帧间隔创建100个雪花
            /**
             * 不使用对象池写法:var img = new Image();
             */
            //通过对象池创建图片,如对象池中无相应的对象,则根据Image类型执行new Image()创建
            /**
             * getItemByClass(sign: string, cls: any) 根据传入的对象类型标识字符,获取对象池中此类型标识的一个对象实例.
             * 当对象池中无此类型标识的对象时,则根据传入的类型,创建一个新的对象返回.
             * sign 对象类型标识字符.cls 用于创建该类型对象的类.@return 此类型标识的一个对象
             */
            var img = Laya.Pool.getItemByClass("snowflake", Laya.Image);
            img.anchorX = img.anchorY = 0.5;//通过锚点设置轴心点,值为0-1
            img.skin = "res/snow0.png"//设置图片资源(皮肤),图片尺寸 100 * 100
            //在舞台上方随机位置创建
            img.x = Math.random() * Laya.stage.width;
            img.y = Math.random() * -150;
            /**
             * 因为雪花在下落过程中会逐渐减小 scaleX、scaleY,从而让雪花看起来越来越小
             * 当超出边界后会将雪花(图片)对象回收到对象池,所里从对象池中的取出的图片是被缩放了的,这里需重置其缩放属性
             * 同理如果对象中还有其他属性被改变了,下落之前也应该进行重置
             */
            img.scaleX = img.scaleY = 1;
            Laya.stage.addChild(img);//加载到舞台显示
            createTime = 0;//100帧后创建完对象后时间将时间归0
        }
    } else {
        createTime++;//更新创建时间
    }
    animation();
}
/**刷新整个舞台中的所有雪花的位置以及状态信息 */
function animation() {
    /**
     * readonly numChildren: number 子对象数量,这是超类 laya.display.Node 中的属性
     * getChildAt(index: number): Node 根据子节点的索引位置,获取子节点对象。继承自超类 laya.display.Node
     */
    for (var j = 0; j < Laya.stage.numChildren; j++) {
        var img = Laya.stage.getChildAt(j);
        img.y++;//位置更新,垂直降落
        img.scaleX -= 0.001;//对雪花大小进行缩放
        img.scaleY -= 0.001;//对雪花大小进行缩放
        img.rotation++;//对雪花(图片)进行旋转
        //超出边界或缩放小于0时,将对象进行回收并从舞台中清除
        if (img.y > Laya.stage.height || img.scaleX <= 0) {
            /**removeChild(node: Node): Node 删除子节点
             * 从舞台中移除雪花(图片),继承自超类 laya.display.Node */
            Laya.stage.removeChild(img);
            /**recover(sign: string, item: any) 将对象放到对应类型标识的对象池中。
             * sign 对象类型标识字符。item 对象。
             */
            Laya.Pool.recover("snowflake", img);
            // img.destroy(); //不使用对象池的编写方式时,直接用destroy清空             
        }
    }
}
上一篇 下一篇

猜你喜欢

热点阅读