cocos2d-x Sprite


轉自:http://codingnow.cn/cocos2d-x/795.html

精靈是游戲中十分重要的組成部分,隨處可見,如:游戲背景、NPC、人物、道具等。在cocos2d-x引擎中,只要是用圖片展示的,基本上需要使用精靈類。

1. 首先來了解一下跟精靈相關的幾個類:
(1) CCTexture2D
可以把它看成一個紋理,它是cocos2d-x渲染圖形的重要參數,用來貼圖,因為cocos2d-x使用opengl es繪制2d圖形的,它的尺寸是2的n次方。一般通過以下方式獲得:

CCTexture2D* cache = CCTextureCache::sharedTextureCache()->addImage("hero.png");

(2) CCSprite
這個就是精靈類,是CCNode的子類,它的內部封裝了CCTexture2D(紋理),可以通過下面幾種方式初始化精靈對象。

//CCTexture2D表示精靈包含的圖片,范圍是整張圖片
static CCSprite* spriteWithTexture(CCTexture2D *pTexture);
//CCRect表示圖片的指定范圍,即從圖片的指定矩形區域裁剪
static CCSprite* spriteWithTexture(CCTexture2D *pTexture, const CCRect& rect);
//CCSpriteFrame表示精靈的某一幀,大多數情況下精靈本身的圖片有多幀。它內部封裝了CCTexture2D和CCRect,可以從一個大圖片取出一部分作為一幀。
static CCSprite* spriteWithSpriteFrame(CCSpriteFrame *pSpriteFrame);
//pszSpriteFrameName表示幀的名字,根據幀名從內存中取出CCSpriteFrame
static CCSprite* spriteWithSpriteFrameName(const char *pszSpriteFrameName);
//pszFileName表示本地圖片文件名
static CCSprite* spriteWithFile(const char *pszFileName);
static CCSprite* spriteWithFile(const char *pszFileName, const CCRect& rect);
static CCSprite* spriteWithBatchNode(CCSpriteBatchNode *batchNode, const CCRect& rect);

下面是兩種比較常用的初始化精靈的方式:

CCSprite* sprite = CCSprite::spriteWithFile("hero.png");
/** 或者 **/
CCTexture2D* cache = CCTextureCache::sharedTextureCache()->addImage("hero.png");
CCSprite* sprite = CCSprite::spriteWithTexture(cache);

(3) CCTextureCache
它相當於CCTexture2D的容器,是內存池,用來緩存CCTexture2D對象的,它內部有一個字典CCMutableDictionary m_pTextures,key為圖片的名稱,值是CCTexture2D。當調用它的addImage函數添加圖片時,會先根據圖片名稱去內存中查找是否已存在,是則直接取出返回。下面是addImage部分源碼:

CCTexture2D * CCTextureCache::addImage(const char * path)
{
    CCTexture2D * texture = NULL;
    std::string pathKey = path;
    CCFileUtils::ccRemoveHDSuffixFromFile(pathKey);
 
    pathKey = CCFileUtils::fullPathFromRelativePath(pathKey.c_str());
    texture = m_pTextures->objectForKey(pathKey);
 
    std::string fullpath = pathKey; // (CCFileUtils::fullPathFromRelativePath(path));
    if( ! texture ) 
    {
        /** .... */
    }
 
    return texture;
}

如果需要一次加載多張圖片的時候,可以先把圖片加載到CCTextureCache中,這樣使用圖片的時候速度就會很快了。
(4) CCSpriteBatchNode
它是批處理繪制精靈,主要是用來提高精靈的繪制效率的,需要繪制的精靈數量越多,效果越明顯。因為cocos2d-x采用opengl es繪制圖片的,opengl es繪制每個精靈都會執行:open-draw-close流程。而CCSpriteBatchNode是把多個精靈放到一個紋理上,繪制的時候直接統一繪制該texture,不需要單獨繪制子節點,這樣opengl es繪制的時候變成了:open-draw()-draw()…-draw()-close(),節省了多次open-close的時間。CCSpriteBatchNode內部封裝了一個CCTextureAtlas(紋理圖集,它內部封裝了一個CCTexture2D)和一個CCArray(用來存儲CCSpriteBatchNode的子節點:單個精靈)。注意:因為繪制的時候只open-close一次,所以CCSpriteBatchNode對象的所有子節點都必須和它是用同一個texture(同一張圖片),類似下面這樣的圖片,4個貝殼都在同一紋理上:

 

在addChild的時候會檢查子節點紋理的名稱跟CCSpriteBatchNode的是不是一樣,如果不一樣就會出錯,源碼:

void CCSpriteBatchNode::addChild(CCNode *child, int zOrder, int tag)
{
    /** ... */
    // check CCSprite is using the same texture id
    CCAssert(pSprite->getTexture()->getName() == m_pobTextureAtlas->getTexture()->getName(), "");
 
    /** ... */
}

下面是使用CCSpriteBatchNode的使用代碼示例:

CCSpriteBatchNode* BatchNode1 = CCSpriteBatchNode::batchNodeWithFile("Images/grossini_dance_atlas.png", 50);
addChild(BatchNode1, 0, kTagSpriteBatchNode);
 
CCSpriteBatchNode* BatchNode = (CCSpriteBatchNode*) getChildByTag( kTagSpriteBatchNode );
int idx = CCRANDOM_0_1() * 1400 / 100;
int x = (idx%5) * 85;
int y = (idx/5) * 121;
 
CCSprite* sprite = CCSprite::spriteWithTexture(BatchNode->getTexture(), CCRectMake(x,y,85,121));
BatchNode->addChild(sprite);
 
sprite->setPosition( ccp( p.x, p.y) );

(5) CCSpriteFrameCache
它是管理CCSpriteFrame的內存池,跟CCTextureCache功能一樣,不過跟CCTextureCache不同的是,如果內存池中不存在要查找的幀,它會提示找不到,而不會去本地加載圖片。它的內部封裝了一個字典:CCDictionary *m_pSpriteFrames,key為幀的名稱。CCSpriteFrameCache一般用來處理plist文件(這個文件指定了每個獨立的精靈在這張“大圖”里面的位置和大小),該文件對應一張包含多個精靈的大圖,plist文件可以使用TexturePacker制作。如下圖所示:

 

下面是使用CCSpriteFrameCache的使用代碼示例:

CCSpriteFrameCache* cache = CCSpriteFrameCache::sharedSpriteFrameCache();
cache->addSpriteFramesWithFile("animations/grossini.plist", "animations/grossini.png");
m_pSprite1 = CCSprite::spriteWithSpriteFrameName("grossini_dance_01.png");
m_pSprite1->setPosition( ccp( s.width/2-80, s.height/2) );

只要plist文件跟對應的png圖片在同一目錄下,且名字相同,則

  addSpriteFramesWithFile(“animations/grossini.plist”, “animations/grossini.png”)可以改成

  addSpriteFramesWithFile(“animations/grossini.plist”);

2. CCSpriteBatchNode和CCSpriteFrameCache結合使用
必須保證CCSpriteFrameCache和CCSpriteBatchNode加載的是同一紋理貼圖。

CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("animations/ghosts.plist", "animations/ghosts.png");
 
CCSpriteBatchNode *aParent = CCSpriteBatchNode::batchNodeWithFile("animations/ghosts.png");
addChild(aParent, 0, kTagSprite1);
 
CCSprite *pFather = CCSprite::spriteWithSpriteFrameName("father.gif");
pFather->setPosition(ccp( s.width/2, s.height/2));
aParent->addChild(pFather, 0, kTagSprite2);

 

CCSprite API

CCSprite*spret=CCSprite::spriteWithFile("Icon.png");

spret->setPosition( ccp(size.width/2, size.height/2) );
this->addChild(spret);
CCSprite*spret=CCSprite::spriteWithFile("Icon.png",CCRectMake(0, 0, 20 ,10 ));//加載圖片的一個區域
spret->setScale(3);//設置CCSprite的縮放比例
spret->setScaleX(1);//以x,y軸縮放
spret->setScaleY(1);
spret->setRotation(90);//旋轉angle) 其中angle為角度不是弧度。正數為順時針旋轉,負數為逆時針旋轉。
spret->setSkewX(30);
spret->setSkewY(30);//原圖片坐標XY軸傾斜 (圖片會拉扯)
spret->setOpacity(20);//范圍0-255,0完全透明,255完全不透明。
spret->setIsVisible(false);//true代表可見false代表不可見
spret->setFlipX(true);//翻轉
spret->autorelease();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM