最近搜索

第9讲 对象池概念 创建子弹,对象池 一直维护这么多子弹,有利于性能。

浏览:466
管理员 2021-08-20 03:10

https://docs.cocos.com/creator/manual/zh/scripting/pooling.html?h=%E5%AF%B9%E8%B1%A1%E6%B1%A0




对象池 一直维护这么多子弹,有利于性能。



初始化对象池

在场景加载的初始化脚本中,我们可以将需要数量的节点创建出来,并放进对象池

//...properties: {
    enemyPrefab: cc.Prefab
},
onLoad: function () {    this.enemyPool = new cc.NodePool();    let initCount = 5;    for (let i = 0; i < initCount; ++i) {        let enemy = cc.instantiate(this.enemyPrefab); // 创建节点
        this.enemyPool.put(enemy); // 通过 put 接口放入对象池
    }
}

对象池里需要的初始节点数量可以根据游戏的需要来控制,即使我们对初始节点数量的预估不准确也不要紧,后面我们会进行处理。

对象池请求对象

接下来在我们的运行时代码中就可以用下面的方式来获得对象池中储存的对象了:

// ...createEnemy: function (parentNode) {    let enemy = null;    if (this.enemyPool.size() > 0) { // 通过 size 接口判断对象池中是否有空闲的对象
        enemy = this.enemyPool.get();
    } else { // 如果没有空闲对象,也就是对象池中备用对象不够时,我们就用 cc.instantiate 重新创建
        enemy = cc.instantiate(this.enemyPrefab);
    }
    enemy.parent = parentNode; // 将生成的敌人加入节点树
    enemy.getComponent('Enemy').init(); //接下来就可以调用 enemy 身上的脚本进行初始化}


初始化对象池

  onLoad() {
        cc.log("wx:xiaomao0055");
        cc.log("qq:14496453");
        this.bg1.y = 0;
        this.bg2.y = this.bg1.y + this.bg1.height;
        this.isBgMove = false;
        this.bg_speed = 5;
        this.set_touch();
        this.play_node.active = true;
        this.btn_pause_node.active = false;
        this.pause_jiemian_node.active = false;

        //初始化飞机位置
        this.hero.x = 0;
        this.hero.y = -500;

        //创建对象池
        this.bullet_time = 0;//子弹产生的累加器 ,时间 
        this.bullet_pool = new cc.NodePool();
       

    },


添加创建子弹的方法

    create_bullet() {
        let bullet = null;
        if (this.bullet_pool.size()> 0) { 
            // 通过 size 接口判断对象池中是否有空闲的对象
            bullet = this.bullet_pool.get();
        } else { 
            // 如果没有空闲对象,也就是对象池中备用对象不够时,我们就用 cc.instantiate 重新创建
            bullet = cc.instantiate(this.pre_bullet);
        }
        bullet.parent = this.node;
        var pos = this.hero.getPosition();
        bullet.setPosition(cc.v2(pos.x, pos.y + this.hero.height / 2));
    },


修改update方法  让子弹一直产生

    update(dt) {
        if (this.isBgMove) {
            this.setBG();
        } else {
        }
        
        this.bullet_time++;
        if(this.bullet_time==5){
            this.create_bullet();
            this.bullet_time=0;
        }
    },


image.png



cc.Class({
    extends: cc.Component,

    properties: {
        bg1: cc.Node,
        bg2: cc.Node,
        play_node: cc.Node,
        btn_pause_node: cc.Node,
        pause_jiemian_node: cc.Node,
        hero: cc.Node,
        pre_bullet: cc.Prefab
    },
    onLoad() {
        cc.log("wx:xiaomao0055");
        cc.log("qq:14496453");
        this.bg1.y = 0;
        this.bg2.y = this.bg1.y + this.bg1.height;
        this.isBgMove = false;
        this.bg_speed = 5;
        this.set_touch();
        this.play_node.active = true;
        this.btn_pause_node.active = false;
        this.pause_jiemian_node.active = false;

        //初始化飞机位置
        this.hero.x = 0;
        this.hero.y = -500;

        //创建对象池
        this.bullet_time = 0;//子弹产生的累加器 ,时间 
        this.bullet_pool = new cc.NodePool();
       

    },
    set_touch() {
        this.node.on('touchstart', function (event) {
            cc.log("touchstart");
            this.isBgMove = true;
            this.play_node.active = false;
            this.btn_pause_node.active = true;
        }, this);

        this.node.on('touchmove', function (event) {
            if (this.isBgMove)
                var pos_hero = this.hero.getPosition();
            var pos_move = event.getDelta();
            this.hero.setPosition(cc.v2(pos_hero.x + pos_move.x, pos_hero.y + pos_move.y));
        }, this);

        this.node.on('touchend', function (event) {
        }, this);
    },
    setBG() {
        this.bg1.y = this.bg1.y - this.bg_speed;
        this.bg2.y = this.bg2.y - this.bg_speed;

        if (this.bg1.y <= -this.bg1.height) {
            this.bg1.y = this.bg2.y + this.bg1.height;
        }
        if (this.bg2.y <= -this.bg1.height) {
            this.bg2.y = this.bg1.y + this.bg1.height;
        }
    },
    create_bullet() {
        let bullet = null;
        if (this.bullet_pool.size()> 0) { 
            // 通过 size 接口判断对象池中是否有空闲的对象
            bullet = this.bullet_pool.get();
        } else { 
            // 如果没有空闲对象,也就是对象池中备用对象不够时,我们就用 cc.instantiate 重新创建
            bullet = cc.instantiate(this.pre_bullet);
        }
        bullet.parent = this.node;
        var pos = this.hero.getPosition();
        bullet.setPosition(cc.v2(pos.x, pos.y + this.hero.height / 2));
    },
    onBulletKilled: function (bullet) {
        // 子弹  销毁的时候  回收到 对象池里面
        this.bullet_pool.put(bullet); 
        // 和初始化时的方法一样,将节点放进对象池,这个方法会同时调用节点的 removeFromParent
    },
    btn_click(sender, str) {

        if (str == 'pause') {
            this.isBgMove = false;
            this.pause_jiemian_node.active = true;
            this.btn_pause_node.active = false;
        } else if (str == 'continue') {
            this.isBgMove = true;
            this.btn_pause_node.active = true;
            this.pause_jiemian_node.active = false;
        } else if (str == 'back') {

        } else if (str == 'restart') {
            this.hero.x = 0;
            this.hero.y = -500;

            this.play_node.active = true;
            this.btn_pause_node.active = false;
            this.pause_jiemian_node.active = false;
        }

    },
    start() {
    },
    update(dt) {
        if (this.isBgMove) {
            this.setBG();
        } else {
        }
        
        this.bullet_time++;
        if(this.bullet_time==5){
            this.create_bullet();
            this.bullet_time=0;
        }
    },
});


联系站长

站长微信:xiaomao0055

站长QQ:14496453