关于SpriteSheet。in Box2D

当一张图片被加载到内存后,它是以纹理的形式存在的,纹理是什么,纹理就是一块内存,这块内存中存在的是按照指定的像素格式填充的图片像素信息,它被最终被作为三角面著色所依据的数据源。

CCTexture2D:纹理,即图片加载入内存后供CPU和GPU操作的贴图对象。

CCTexturePVR:处理PVR文件生成纹理的类。

CCTextureCache:纹理管理器,负责加载图片并对生产的纹理进行管理,通过“字典”来进行快速查询。

CCTextureAtlas:纹理块管理器,如果图片是由多个小图块构成,则纹理块管理器用来存储这些小图块的相关信息,以方便绘制相应图块。


cocos2d和像素格式

  在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"];

寻找目录下同名的 图片加入到texturecache中去 . ;解析plist文件追踪 每个文件的位置。

2、创建一个精灵批处理结点

        CCSpriteBatchNode * spriteNode = [CCSpriteBatchNode batchNodeWithFile:@"pvr_texture.pvr.ccz"];
        [self addChild:spriteNode];

创建一个节点  获得所有图片,   batch 会智能遍历它的孩子节点,并通过一次OpenGl es call 进行渲染

3、收集帧的列表

        NSMutableArray * frames = [NSMutableArray array];
       [ frames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache]spriteFrameByName:@"CloseNormal.png"]] ;
        [ frames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache]spriteFrameByName:@"CloseSelected.png"]] ;

这里因为我就测试两幅 所以我没用命名  来进行for循环    注意 frames 里存的是一帧一帧  ,也就是SpriteFrame

4、创建一个 Animation

		CCAnimation *animation = [CCAnimation animationWithSpriteFrames:frames delay:0.2     ];

               注意是 Animation  不是Animate  Action 执行的 是Animate

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]]];

这样就可以看到精灵 并且有动画 .(我没加所谓的[CCTexture2D PVRImageHavePremultipliedAlpha:YES]  好像是这么写的  )反正 这个2.0的版本是不用加的 

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);

我们还需要再update里面更新   精灵的位置   

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()) ];
        }    
    }


这样就实现了在box2D里使用动画。







前面的那些很大一段的话

引用自:http://blog.csdn.net/honghaier/article/details/8068895

引用自:http://www.cnblogs.com/andyque/articles/1988097.html


你可能感兴趣的:(关于SpriteSheet。in Box2D)