Cocos2d-x学习笔记(九)纹理CCTexture2D和精灵CCSprite
来源:互联网 发布:景观设计效果图软件 编辑:程序博客网 时间:2024/04/30 21:05
原创文章,转载请注明出处:http://blog.csdn.net/sfh366958228/article/details/38850499
前言
在Cocos2d-x中对图片得封装是通过CCImage来完成,该类实现了对于不同类型图片得读取、解析、像素信息保存。由于在引擎内部封装,一般情况下不需要修改此类,由于Cocos2d-x使用了Open GL的图形库,因此在图片显示在屏幕的过程中是通过在3D空间的某个平面通过纹理贴图的方式完成的图片显示,在Cocos2d-x中通过CCTexture2D来实现。
在纹理处理中有如下一些常用类:
CCImage // 调用libpng libjpg来读取图片的像素信息
CCTexture2D // 封装纹理对象
CCTextureCache // 一组纹理对象,通过CCDictionary管理,通过字符key获取
CCRenderTexture // 创建动态纹理
CCSprite // 实现纹理显示
CCSpriteFrame // 用来定义动画层的每一帧,定义好厚以CCAction的形式作用到一个CCSprite上来呈现动画效果
CCSpriteBatchNode //
CCSpriteFrameCache // 一组纹理对象,通过CCDictionary管理,通过字符key获取
CCAnimation // 实现一组Sprite播放的Action
根据图片文件创建CCSprite
CCSprite * sprite = CCSprite::create("HelloWorld.png");利用create方法完成了对图片纹理的加载,我们来看看创建过程的源码
CCSprite* CCSprite::create(const char *pszFileName, const CCRect& rect){ CCSprite *pobSprite = new CCSprite(); //创建一个CCSprite对象 if (pobSprite && pobSprite->initWithFile(pszFileName, rect)) // 如果成功创建,且初始化成功 { pobSprite->autorelease(); // 添加到自动释放管理CCPoolManager中 return pobSprite; } CC_SAFE_DELETE(pobSprite); // 创建失败,安全删除 return NULL;}bool CCSprite::initWithFile(const char *pszFilename, const CCRect& rect){ CCAssert(pszFilename != NULL, ""); // 文件名不能为空 CCTexture2D *pTexture = CCTextureCache::sharedTextureCache()->addImage(pszFilename); // 将图片添加至纹理缓存中,并获取对应的CCTexture对象 if (pTexture) // 如果对象不为空,返回initWithTexture { return initWithTexture(pTexture, rect); } return false;}bool CCSpriteFrame::initWithTexture(CCTexture2D* pobTexture, const CCRect& rect){ CCRect rectInPixels = CC_RECT_POINTS_TO_PIXELS(rect); // 点矩形转像素矩形 return initWithTexture(pobTexture, rectInPixels, false, CCPointZero, rectInPixels.size);}bool CCSpriteFrame::initWithTexture(CCTexture2D* pobTexture, const CCRect& rect, bool rotated, const CCPoint& offset, const CCSize& originalSize){ m_pobTexture = pobTexture; if (pobTexture) { pobTexture->retain(); } m_obRectInPixels = rect; m_obRect = CC_RECT_PIXELS_TO_POINTS(rect); m_obOffsetInPixels = offset; m_obOffset = CC_POINT_PIXELS_TO_POINTS( m_obOffsetInPixels ); m_obOriginalSizeInPixels = originalSize; m_obOriginalSize = CC_SIZE_PIXELS_TO_POINTS( m_obOriginalSizeInPixels ); m_bRotated = rotated; return true;}
根据CCTexture2D纹理对象创建CCSprite
CCTexture2D *texture = CCTextureCache()::sharedTextureCache()->addImage("Player.png");CCSprite *sprite = CCSprite::createWithTexture(texture, CCRectMake(0, 0, 85, 121));CCRectMake是指定一个裁剪区域,该方法实现了将纹理对象texture的一部分区域创建一个CCSprite图层。
CCSprite* CCSprite::createWithTexture(CCTexture2D *pTexture, const CCRect& rect){ CCSprite *pobSprite = new CCSprite(); if (pobSprite && pobSprite->initWithTexture(pTexture, rect)) { pobSprite->autorelease(); return pobSprite; } CC_SAFE_DELETE(pobSprite); return NULL;}createWithTexture和create方法几乎类似。
使用CCSpriteFrame创建CCSprite
CCTexture2D *texture = CCTextureCache()::sharedTextureCache()->addImage("Player.png");CCSpriteFrame spriteFrame01 = CCSpriteFrame::createWithTexture(texture, CCRectMake(132 * 0, 132 * 0, 132, 132));CCSprite *sprite = CCSprite::createWithSpriteFrame(spriteFrame01);而CCSpriteFrame的创建除了直接通过CCTexture2D对象之外,还可以通过读取纹理工具(Cocos Studio)导出的plist文件来创建。
CCSpriteFrameCache *cache = CCSpriteFrameCache::sharedSpriteFrameCache();cache->addSpriteFramesWithFile("grossini.plist");CCArray *aniFrames = CCArray::createWithCapacity(14);char str[100] = {0};for (int k = 0; k < 14; ;++){sprintf(str, "grossini_dance_%02d.png", (k+1));CCSpriteFrame *frame = cache->spriteFrameByName(str);animFrames->addObject(frame);}通过grossini.plist将图片剪裁程多帧,在使用的时候通过spriteFrameByName方法从CCSpriteFrameCache获取每一帧,通过工具软件生成plist,通过上述方法解析plist,能大大加快程序开发的效率。
// 序列帧加载方法1 - 逐图加载CCAnimation *animation = CCAnimation::create();char str[100] = {0};for(int i = 1; i <= 14; i++){ sprintf(str, "grossini_dance_%02d.png", i); animation->addSpriteFrameWithFileName(str);}animation->setDelayPerUnit(0.2);animation->setRestoreOriginalFrame(false);sprite->runAction(CCAnimate::create(animate));// 序列帧加载方法2 - 切图法CCArray* animFrames = CCArray::createWithCapacity(14);CCTexture2D * texture = CCTextureCache::sharedTextureCache()->addImage("grossini_dance_atlas_nomipmap.png");for (int i = 0; i < 14; i++) { CCSpriteFrame* spriteFrame = CCSpriteFrame::createWithTexture(texture, CCRectMake(40 * i % 5, 57 * i / 5, 40, 57)); animFrames->addObject(spriteFrame);}CCAnimation *animation = CCAnimation::createWithSpriteFrames(animFrames, 0.2f);sprite->runAction(CCAnimate::create(animation));
用CCSpriteBatchNode进行文理贴图的优化
在场景中随机生成100个相同的精灵,看看使用CCSpriteBatchNode优化前和优化后两种不同的效果。
// 优化前for (int i = 0; i < 100; i++){ CCSprite *sp = CCSprite::create("Icon.png"); int x = arc4random()%480; int y = arc4random()%320; sp->setPosition(CCPointMake(x, y)); this->addChild(sp);}// 优化后CCSpriteBatchNode* batchNode = CCSpriteBatchNode::create("Icon.png", 10);batchNode->setPosition(CCPointZero);this->addChild(batchNode);for (int i=0; i<100; i++){ CCSprite *sp = CCSprite::create("Icon.png"); int x = arc4random()%480; int y = arc4random()%320; sp->setPosition(CCPointMake(x, y)); batchNode->addChild(sp);}
效果(优化前):
效果(优化后):
优化了之后,明显的看的出第一幅图第一个参数是100,也就是说精灵渲染了100次,这是比较消耗资源的。第二幅图,第一个参数只渲染一次。还有就是由于模拟器调用的是PC的内存所以内存比较大,对第三个参数是不会有多大的影响的,但如果是真机调试的话效果会很明显,第一种情况会明显的比较卡。
- Cocos2d-x学习笔记(九)纹理CCTexture2D和精灵CCSprite
- Cocos2d-x学习笔记(九)纹理CCTexture2D和精灵CCSprite
- 纹理CCTexture2D和精灵CCSprite
- 纹理CCTexture2D和精灵CCSprite
- cocos2d-x学习笔记-CCSprite(精灵)
- cocos2d-x学习笔记-CCSprite(精灵)
- cocos2d-x学习笔记-CCSprite(精灵)
- cocos2d-x学习笔记-CCSprite(精灵)
- cocos2d-x学习笔记-CCSprite(精灵)
- Cocos2d-x学习笔记(五)-------->CCSprite精灵
- cocos2d-x 详解之 CCTexture2D(纹理图片)和 CCTextureCache(纹理缓存)
- cocos2d-x 详解之 CCSprite(精灵)- “CCSpriteBatchNode”和“CCSpriteFrameCache”
- cocos2d-X之精灵角色(CCSprite)
- 【Cocos2d-X开发学习笔记】第06期:渲染框架之精灵类(CCSprite)的使用
- 【Cocos2d-X开发学习笔记】第06期:渲染框架之精灵类(CCSprite)的使用
- 我的Cocos2d-x学习笔记(七)纹理缓存、帧缓存、精灵的创建、zOrder
- cocos2d-x学习笔记(4)精灵和菜单
- cocos2d-X学习之主要类介绍:精灵角色(CCSprite)
- DNS服务器和DNS从属关系部署
- 创建型设计模式---构建模式(Builder)
- Javascript中的类实现
- 使用arm-eabi-addr2line, ndk-stack工具跟踪Android调用堆栈
- 字符编码笔记:ASCII,Unicode和UTF-8
- Cocos2d-x学习笔记(九)纹理CCTexture2D和精灵CCSprite
- 软阵列和LVM实现
- oracle 释放无用连接
- 使用FlasCC处理位图数据
- iframe中动态添加html内容
- 程序员生存定律--如何尽快变的稍微专业一点
- .NET程序加壳的基本原理和方式
- PHP分页
- 基于GBT28181:SIP协议组件开发-----------第二篇SIP组件开发原理