• 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();
  • 相关阅读:
    字符数组初始化
    makefile学习笔记
    convert between char* and std::string
    mysql 学习笔记(二)
    面试中的Singleton (转)
    由谈退格键的实现来学习字符编码
    mysql 学习笔记(一)
    Eclipse插件的安装方法
    Http状态码
    net use命令
  • 原文地址:https://www.cnblogs.com/sevenyuan/p/3179370.html
Copyright © 2020-2023  润新知