본문 바로가기
Cocos2D-x

CCSpriteBatchNode

by CodeDiver 2014. 8. 14.

CCSpriteBatchNode

출처: http://digitanomad.blogspot.kr/2012/12/ccspritebatchnode.html

게임을 개발하다 보면, 이미지 처리에 있어 성능 상의 문제에 직면하게 됩니다.
예를 들면, 슈팅 게임을 개발할 때 탄막을 표현한다고 합시다. 일반적으로 총알을 화면에 표시하려면 
CCSprite 객체를 사용합니다. 이 때 총알 하나하나를 모두 화면에 표시하려고
하면 엄청난 갯수의 CCSprite 객체를 생성해야 되는데, 분명히 기기 성능에 문제가 발생할
 것입니다. 이러한 그리기 성능의 문제를 해결하기 위해 CCSpriteBatchNode를 사용해야 
합니다. 


1. CCSpriteBatchNode


(1) 설명
1) Cocos2d 0.9x 버전 이하에 있던 CCSpriteSheet라는 클래스가 CCSpriteBatchNode로 변경
    되었습니다. 개념은 이전과 같습니다.

2) CCSpriteBatchNode는 오직 하나의 이미지 또는 텍스쳐만을 참조할 수 있습니다. 
     그래서 TexturePacker나 Zwoptex와 같은 프로그램을 이용해서 이미지들을 하나로 묶어줍니
     다. 그리고 텍스쳐를 갖고 있는 CCSprite 객체만이CCSpriteBatchNode에 추가될 수 있습니다.

3) CCSpriteBatchNode에 추가된 모든 CCSprite 객체들은 한번의 OpenGL ES draw 호출에 그려집니다. 
    이것을 Batch Draw라고 합니다. 반면에, CCSpriteBatchNode에 추가되어 지지 않은 CCSprite 
    객체들은 각자 OpenGL ES draw 호출을 수행하여 화면에 그려집니다. 
    이 방법은 비효율적이라고 할 수 있습니다.

(2) 제한사항
1) CCSpriteBatchNode의 자식 노드로는 CCSprite 또는 CCSprite의 서브클래스 만이 허용됩니다. 
     Paticles, Labels, Layer는 CCSpriteBatchNode의 자식 노드로 추가할 수 없습니다.
2) CCSpriteBatchNode의 자식들은 모두 Aliased 또는 Antialiased 속성을 가져야 합니다.  
      Alias는 텍스쳐의 속성인데, 모든 Sprite들은 같은 텍스쳐를 공유하기 때문에 서로 다른 속성을 가진 
     노드들이 섞여있어서는 안됩니다.



2. 실습하기

(1) 코딩하기
TexturePacker를 사용하면 파일명.plist와 파일명.png를 생성하실 수 있습니다. 이 때 저장위치는 프로젝트의

_batchNode=CCSpriteBatchNode::create("Sprites.png");
this->addChild(_batchNode);
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("Sprites.plist");

_ship=CCSprite::createWithSpriteFrameName("SpaceFlier_sm_1.png");
CCSize winSize=CCDirector::sharedDirector()->getWinSize();
_ship->setPosition(ccp(winSize.width * 0.1, winSize.height * 0.5));
_batchNode->addChild(_ship, 1); 

 이처럼, CCSpriteBatchNode 클래스의 create 함수를 이용해 Sprites.png 그림 파일로 객체를 생성합니다. 그리고 Sprites.plist 파일을 읽기 위해 CCSpriteFrameCache 클래스를 사용합니다. CCSpriteFrameCache는 Singleton으로 구현되어 있어서 sharedSpriteFrameCache() 함수로 인스턴스를 얻어와서 addSpriteFramesWithFile 함수로 plist 파일을 지정해줍니다.
 다음으로, 집어넣고자 하는 Sprite를 얻어오기 위해, 아까 TexturePacker에서 집어넣었던 Sprite의 이름을 createWithSpriteFrameName 함수의 인자로 집어넣어주면 됩니다. Sprite의 위치를 정해주고 batchNode에다 자식노드로 집어넣어야 합니다.
 컴파일 후 실행시켜보면 이처럼 깔끔하게 들어갔습니다.