当一张图片被加载到内存后,它是以纹理的形式存在的,纹理是什么,纹理就是一块内存,这块内存中存在的是按照指定的像素格式填充的图片像素信息,它被最终被作为三角面著色所依据的数据源。
CCTexture2D:纹理,即图片加载入内存后供CPU和GPU操作的贴图对象。
CCTexturePVR:处理PVR文件生成纹理的类。
CCTextureCache:纹理管理器,负责加载图片并对生产的纹理进行管理,通过“字典”来进行快速查询。
CCTextureAtlas:纹理块管理器,如果图片是由多个小图块构成,则纹理块管理器用来存储这些小图块的相关信息,以方便绘制相应图块。
在cocos2d里面,理解像素格式非常重要。因为,像素格式会影响在你的游戏中加载一张图片到底需要多少内存。因为游戏通常要加载大量的图片资源,所以你要尽可能充分利用移动设备上面非常少的可用物理内存。
默认情况下面,当你在cocos2d里面加载一张图片的时候,对于每一个像素点使用4个byte来表示--1个byte(8位)代表red,另外3个byte分别代表green、blue和alpha透明通道。这个就简称RGBA8888。
因此,如果你使用默认的像素格式来加载图片的话,你可以通过下面的公式来计算出将要消耗多少内存来加载:
图像宽度(width)×图像高度(height)×每一个像素的位数(bytes per pixel) = 内存大小
此时,如果你有一张512×512的图片,那么当你使用默认的像素格式去加载它的话,那么将耗费
512×512×4=1MB(好多啊!)
这里,我们以Iphone3G为例。它总共只有128兆内存,但是系统就要占掉一大半,还有其它一些程序也要使用一些内存,实际可用的内存更少。对于单独一张spritesheet来说那确实足够了。可是想像一下你有许许多多的spritesheet,而且游戏里面经常需要大量的spritesheet!
这里就需要让像素格式来帮忙了。你可以为图片的每个像素点指定更小的字节来保存图片。(比如每个像素点2个字节,即每个像素点16位),这种方式就能够在图片质量和内存消耗之间取得一个很好的平衡点。
通常,你是在你的游戏看起来还ok的提前下,尽可能少地使用内存。背景图片就非常适用用8位或者16位来存储,而精灵则一般要用16位或者32位。对于更多可选的像素格式和适用的场合,你可以参考Riq(cocos2d的作者)的一篇文章: understanding pixel format guide.(理解像素格式向导)
OK 到此位置 ,本来想 看一些 转过来一些, 发现一点条例没有 .所以 停止,上面的这些算是帮助理解纹理,这个东西。
下边 总结一下,spritesheet,存在的目的是为了减少系统对于图像的渲染次数,bacthNode会遍历孩子节点,调用OpenGL es call 来渲染。
那么,如何定义 spriteSheet 我翻了好多资料 ,印象中记得叫纹理图册 , 但是没找到 .感觉纹理图册 挺适合的 .包括png 或pvr.ccz 和 plist 文件(内部包含 一些图片和图片再整张图片里的坐标)
如何制作spriteSheet 有两个工具, zwoptex 和 texture packer 很不幸 都是花钱的 .但两者都有一个限免的时间,好像是 一个星期吧。
后者还会提供一个免版的 , ,,但是 会给你弄成红色 , 个人感觉拿来练手无影响。Texture Packer 似乎包含了 Zwoptex 90%的功能,但是 tp 有三个功能 zwoptex 没有:
1.抖动, 像素低,但是 还是让相片看的笔记清楚,尽管质量很低
2.pvr.ccz 使程序更快,更小。加载更快。
3. 命令行工具支持,可以把这个工具集成到Xcode中去, 虽然我不会用 . 但是Mark下
接下来就是如何用了 .
首先 咱们制作一个(参考http://www.cnblogs.com/andyque/articles/1988097.html)
制作完成之后得到 一个pvr.ccz 和 一个plist 两个文件;
拖到工程里 .
1、缓冲sprite帧和纹理
[[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:@"pvr_texture.plist"];
2、创建一个精灵批处理结点
CCSpriteBatchNode * spriteNode = [CCSpriteBatchNode batchNodeWithFile:@"pvr_texture.pvr.ccz"]; [self addChild:spriteNode];
3、收集帧的列表
NSMutableArray * frames = [NSMutableArray array]; [ frames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache]spriteFrameByName:@"CloseNormal.png"]] ; [ frames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache]spriteFrameByName:@"CloseSelected.png"]] ;
4、创建一个 Animation
CCAnimation *animation = [CCAnimation animationWithSpriteFrames:frames delay:0.2 ];
5、创建一个精灵并且 run Action
CCSprite * sprite = [CCSprite spriteWithSpriteFrameName:@"CloseNormal.png"]; [sprite setPosition:CGPointMake(s.width/2, s.height/2)]; [spriteNode addChild:sprite]; [sprite runAction:[CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:animation]]];
6、创建一个刚体并且绑定
b2BodyDef spBodyDef; spBodyDef.position =b2Vec2::b2Vec2(((float)sprite.position.x)/PTM_RATIO,((float)sprite.position.y)/PTM_RATIO); spBodyDef.type = b2_dynamicBody; b2Body*spBody = world->CreateBody(&spBodyDef); b2FixtureDef spFixtureDef; b2PolygonShape spBox; spBox.SetAsBox((float)sprite.textureRect.size.width/2/PTM_RATIO, (float)sprite.textureRect.size.width/2/PTM_RATIO); spFixtureDef.shape = &spBox; spFixtureDef.density = 0.5; spFixtureDef.friction = 0.5; spFixtureDef.restitution = 0.5; spBody ->CreateFixture(&spFixtureDef); spBody->SetUserData(sprite);
7、更新精灵的位置:
for (b2Body* b = world->GetBodyList(); b; b = b->GetNext()) { if (b->GetUserData() != NULL) { //Synchronize the AtlasSprites position and rotation with the corresponding body CCSprite* myActor = (CCSprite*)b->GetUserData(); [myActor setPosition: CGPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO)]; [myActor setRotation: -1 * CC_RADIANS_TO_DEGREES(b->GetAngle()) ]; } }
前面的那些很大一段的话
引用自:http://blog.csdn.net/honghaier/article/details/8068895
引用自:http://www.cnblogs.com/andyque/articles/1988097.html