CocosCreator 객체 풀 사용 방법

4520 단어 Cocos개체 풀성능

선언:


실행할 때 노드의 생성(cc.instantiate)과 삭제(node.destroy) 작업을 하는 것은 성능이 매우 소모되기 때문에 우리는 비교적 복잡한 장면에서 장면 초기화 논리(onLoad)에서만 노드의 생성을 하고 장면을 전환할 때 노드의 삭제를 한다.만약 대량의 적이나 총알이 반복적으로 생성되고 소멸되어야 하는 동작류 게임을 제작한다면 우리는 어떻게 게임이 진행되는 과정에서 수시로 노드를 창설하고 소각해야 합니까?이곳은 대상 탱크의 도움이 필요하다.
대상 탱크는 회수 가능한 노드 대상입니다. cc를 만듭니다.NodePool의 인스턴스로 노드의 객체 풀을 초기화합니다.일반적으로 우리가prefab를 여러 개 실례화해야 할 때, 각각prefab에 cc를 만들어야 한다.NodePool 인스턴스입니다.
우리가 노드를 만들어야 할 때, 대상 탱크에 노드를 신청하고, 대상 탱크에 사용할 수 있는 노드가 있으면, 노드를 사용자에게 되돌려주고, 사용자는node를 통해.add Child는 이 새 노드를 장면 노드 트리에 추가합니다.
우리가 노드를 삭제해야 할 때, 대상 탱크 실례의put(node) 방법을 호출하여 삭제해야 할 노드 실례를 전송하면 대상 탱크는 노드를 장면 노드 트리에서 제거하는 작업을 자동으로 완성하고 대상 탱크로 되돌아옵니다.
이렇게 하면 소수의 노드의 순환 이용을 실현할 수 있다.

구체적인 조작


1단계: Prefab 준비


당신이 만들고 싶은 노드를 미리 설정하고 Prefab 자원을 만들면 어떤 친구들은 프리젠테이션을 만들지 못할까?
(자원 관리자의 자원을 등급 관리자로 끌어다 놓고 노드를 자원 관리자로 끌어당기기만 하면 된다)
이렇게 하면 사전 제작체의 생성이 완성됩니다!

2단계: 개체 풀 초기화


장면에 불러오는 초기화 스크립트에서 우리는 수량이 필요한 노드를 만들어서 대상 탱크에 넣을 수 있다.

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  
    }
}
대상 탱크에 필요한 초기 노드 수량은 게임의 수요에 따라 제어할 수 있다. 설령 우리가 초기 노드 수량에 대한 예측이 정확하지 않더라도 괜찮다. 다음에 우리는 처리할 것이다.

3단계: 개체 풀에서 개체 요청


다음은 우리가 실행할 때 코드에서 다음 방식으로 대상 탱크에 저장된 대상을 얻을 수 있습니다.

createEnemy: function (parentNode) {
    let enemy = null;
    if (this.enemyPool.size() > 0) { //   size  
        // get() 
        enemy = this.enemyPool.get();
        
    } else { //  , ,  cc.instantiate  
        enemy = cc.instantiate(this.enemyPrefab);
    }
    enemy.parent = parentNode; //  
    enemy.getComponent('Enemy').init(); //  enemy  
}
안전한 사용 대상 탱크의 요점은 get이 대상을 얻기 전에 영원히 size로 사용 가능한 대상이 있는지 판단하는 것입니다. 없으면 정상적으로 노드를 만드는 방법을 사용합니다. 실행 시 성능을 소모하지만 게임 붕괴보다 좋습니다!또 다른 선택은 get을 직접 호출하는 것입니다. 대상 탱크에 사용할 수 있는 노드가 없으면null로 되돌아옵니다. 이 단계에서 판단하셔도 됩니다.

4단계: 객체를 객체 풀로 돌아가기


우리가 적을 죽일 때, 적의 노드를 대상 탱크에 반환하여 이후에 계속 순환하여 이용할 수 있도록 해야 한다. 우리는 이런 방법을 사용한다.

onEnemyKilled: function (enemy) {
    // enemy   cc.Node
    this.enemyPool.put(enemy); //  , ,  removeFromParent
}
이렇게 하면 우리는 완전한 순환을 완성할 수 있다. 주인공이 얼마나 많은 몬스터를 처치해야 하는지는 문제가 되지 않는다.노드를 대상 탱크에서 꺼내는 작업은 추가 메모리 관리 비용을 가져오지 않기 때문에 가능하다면 최대한 이용해야 한다.

단계 5: 구성 요소를 사용하여 회수 및 재사용 이벤트 처리


구조 함수를 사용하여 대상 풀을 만들 때 노드에 마운트되어 노드 회수 및 재사용 이벤트를 처리하는 구성 요소로 사용할 구성 요소 유형이나 이름을 지정할 수 있습니다.
객체 풀을 만들 때 다음을 사용할 수 있습니다.

 let menuItemPool = new cc.NodePool('MenuItem');  //  
이렇게 하면 menuItemPool을 사용할 수 있습니다.get () 노드를 가져오면 Menu Item의 Reuse 방법을 호출하여 이벤트 등록을 완료합니다.
menuItemPool을 사용하는 경우put(menu Item Node) 노드를 회수하면 Menu Item의 unuse 방법을 호출하여 클릭 이벤트의 반등록을 완료합니다.

cc.Class({
    extends: cc.Component,
    onLoad: function () {
        this.node.selected = false;
        this.node.on(cc.Node.EventType.TOUCH_END, this.onSelect, this.node);
    },
    // put()  
    unuse: function () {
        this.node.off(cc.Node.EventType.TOUCH_END, this.onSelect, this.node);
    },
    // get() 
    reuse: function () {
        this.node.on(cc.Node.EventType.TOUCH_END, this.onSelect, this.node);
    }
});
따로NodePool.get () 은 reuse 메서드에 그대로 전달되는 수량 유형의 매개 변수를 전달할 수 있습니다.

// BulletManager.js
let myBulletPool = new cc.NodePool('Bullet'); // 
let newBullet = myBulletPool.get(this); //   manager  , 

// Bullet.js
reuse (bulletManager) {
    this.bulletManager = bulletManager; // get  
}
hit () {
    this.bulletManager.put(this.node); //  
}

6단계: 객체 풀 지우기


개체 풀의 노드가 더 이상 필요하지 않으면 수동으로 개체 풀을 비우고 캐시된 모든 노드를 제거할 수 있습니다.

myPool.clear(); //  
대상 탱크의 실례가 더 이상 어디에서도 인용되지 않을 때, 엔진의 쓰레기 회수 시스템은 자동으로 대상 탱크의 노드를 제거하고 회수한다.그러나 이 과정의 시간은 제어할 수 없다. 또한 그 중의 노드가 다른 곳에 인용되면 메모리 유출을 초래할 수 있기 때문에 장면을 전환하거나 다른 대상 탱크가 필요하지 않을 때 수동으로clear 방법을 호출하여 캐시 노드를 비우는 것이 가장 좋다.
다음은 CocosCreator 대상 풀을 어떻게 사용하는지에 대한 상세한 내용입니다. 더 많은 CocosCreator 대상 풀에 대한 자료는 저희 기타 관련 글을 참고하세요!

좋은 웹페이지 즐겨찾기